Ejemplo n.º 1
0
        /// <summary>
        /// Write the EMBL (and all its data/content) to a file.
        /// </summary>
        /// <param name="file">A <see cref="File"/> representing the file to write to.</param>
        /// <param name="position">The byte-position in the file to write the EBML to.</param>
        /// <param name="reserved">The reserved size in bytes that the EBML may overwrite from the given position. (Default: 0, insert)</param>
        public void Write(File file, long position, long reserved = 0)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (position > file.Length || position < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            if (Data != null && Children != null)
            {
                throw new UnsupportedFormatException("EBML element cannot contain both Data and Children");
            }


            // Reserve required size upfront to speed up writing
            var size = Size;

            if (size > reserved)
            {
                // Extend reserved size
                file.Insert(size - reserved, position + reserved);
                reserved = size;
            }

            // Write the Header
            var header = Header;

            file.Insert(header, position, header.Count);
            position += header.Count;
            reserved -= header.Count;

            // Write the data/content
            if (Data != null)
            {
                file.Insert(Data, position, Data.Count);
            }
            else if (Children != null)
            {
                foreach (var child in Children)
                {
                    child.Write(file, position, reserved);
                    var csize = child.Size;
                    position += csize;
                    reserved -= csize;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Write the <see cref="DataSize"/> to the EBML file.
        /// Resize the data-size length to 8 bytes.
        /// This will *not* insert extra bytes, but overwrite next contiguous bytes.
        /// It will claim the size added on the value of the data-size.
        /// </summary>
        /// <returns>Offset created in Writing the new data-size</returns>
        public long WriteDataSize()
        {
            ulong       value          = DataSize;
            const ulong newsize_length = 8;

            // Figure out the ID size in bytes
            ulong mask = 0xFF000000, id_length = 4;

            while (id_length > 0 && (ebml_id & mask) == 0)
            {
                id_length--;
                mask >>= 8;
            }
            if (id_length == 0)
            {
                throw new CorruptFileException("invalid EBML ID (zero)");
            }

            // Figure out the Data size length in bytes
            ulong size_length = DataOffset - offset - id_length;

            if (size_length > 8)
            {
                throw new CorruptFileException("invalid EBML element size");
            }

            // Construct the data-size field
            ByteVector vector = new ByteVector((int)newsize_length);

            mask = value;
            for (int i = (int)newsize_length - 1; i >= 0; i--)
            {
                vector[i] = (byte)(mask & 0xFF);
                mask    >>= 8;
            }
            // Set the marker bit
            vector[0] |= 0x100 >> (int)newsize_length;

            // Write data-size field to file
            file.Insert(vector, (long)(offset + id_length), (long)newsize_length);

            // Update fields
            ulong woffset = newsize_length - size_length;

            DataOffset += woffset;
            DataSize    = value - woffset;

            return((long)woffset);
        }