コード例 #1
0
        public EBMLElement(Matroska.File _file, ulong position)
        {
            if (_file == null)
            {
                throw new ArgumentNullException("file");
            }
            if (position > (ulong)(_file.Length - 4))
            {
                throw new ArgumentOutOfRangeException("position");
            }
            file = _file;
            file.Seek((long)position);
            ByteVector vector = file.ReadBlock(1);
            Byte       header_byte = vector[0];
            Byte       mask = 0x80, id_length = 1;

            while (id_length <= 4 && (header_byte & mask) == 0)
            {
                id_length++;
                mask >>= 1;
            }
            if (id_length > 4)
            {
                throw new CorruptFileException("invalid EBML id size");
            }
            if (id_length > 1)
            {
                vector.Add(file.ReadBlock(id_length - 1));
            }
            ebml_id = vector.ToUInt();
            vector.Clear();
            vector      = file.ReadBlock(1);
            header_byte = vector[0];
            mask        = 0x80;
            Byte size_length = 1;

            while (size_length <= 8 && (header_byte & mask) == 0)
            {
                size_length++;
                mask >>= 1;
            }
            if (size_length > 8)
            {
                throw new CorruptFileException("invalid EBML element size");
            }
            vector[0] &= (Byte)(mask - 1);
            if (size_length > 1)
            {
                vector.Add(file.ReadBlock(size_length - 1));
            }
            ebml_size   = vector.ToULong();
            offset      = position;
            data_offset = offset + id_length + size_length;
        }
コード例 #2
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(Matroska.File file, long position, long reserved = 0)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            if (position > file.Length || position < 0)
            {
                throw new ArgumentOutOfRangeException("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;
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Remove the EBML element from the file
        /// </summary>
        /// <returns>Size difference compare to previous EBML size</returns>
        public long Remove()
        {
            long ret = -(long)Size;

            file.RemoveBlock((long)Offset, (long)Size);

            // Invalidate this object
            ebml_id     = 0;
            data_offset = offset;
            ebml_size   = 0;
            file        = null;

            return(ret);
        }
コード例 #4
0
        /// <summary>
        /// Constructs a root <see cref="EBMLreader" /> instance, by reading from
        /// the provided file position.
        /// </summary>
        /// <param name="_file"><see cref="File" /> File instance to read from.</param>
        /// <param name="position">Position in the file to start reading from.</param>
        public EBMLreader(Matroska.File _file, ulong position)
        {
            // Keep a reference to the file
            file   = _file;
            parent = null;

            // Initialize attributes
            offset      = position;
            data_offset = position;
            ebml_id     = 0;
            ebml_size   = 0;

            // Actually read the EBML on the file
            Read(true);
        }
コード例 #5
0
        /// <summary>
        /// Create a new abstract <see cref="EBMLreader" /> with arbitrary attributes,
        /// without reading its information on the file.
        /// </summary>
        /// <param name="parent">The <see cref="EBMLreader" /> that contains the instance to be described.</param>
        /// <param name="position">Position in the file.</param>
        /// <param name="ebmlid">EBML ID of the element</param>
        /// <param name="size">Total size of the EBML, in bytes</param>
        public EBMLreader(EBMLreader parent, ulong position, MatroskaID ebmlid, ulong size = 0)
        {
            // Keep a reference to the file
            if (parent != null)
            {
                file = parent.file;
            }
            this.parent = parent;

            // Initialize attributes
            offset      = position;
            data_offset = offset;
            ebml_id     = (uint)ebmlid;
            ebml_size   = size;
        }
コード例 #6
0
        /// <summary>
        /// Constructs a child <see cref="EBMLreader" /> reading the data from the
        /// EBML parent at the provided file position.
        /// </summary>
        /// <param name="parent">The <see cref="EBMLreader" /> that contains the instance to be created.</param>
        /// <param name="position">Position in the file to start reading from.</param>
        public EBMLreader(EBMLreader parent, ulong position)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("file");
            }

            // Keep a reference to the file
            file        = parent.file;
            this.parent = parent;

            // Initialize attributes
            offset      = position;
            data_offset = position;
            ebml_id     = 0;
            ebml_size   = 0;


            // Actually read the EBML on the file
            Read(true);
        }
コード例 #7
0
        /// <summary>
        /// Constructs a <see cref="EBMLElement" /> parsing from provided
        /// file data.
        /// </summary>
        /// <param name="_file"><see cref="File" /> instance to read from.</param>
        /// <param name="position">Position to start reading from.</param>
        public EBMLElement(Matroska.File _file, ulong position)
        {
            if (_file == null)
            {
                throw new ArgumentNullException("file");
            }

            if (position > (ulong)(_file.Length - 4))
            {
                throw new ArgumentOutOfRangeException("position");
            }

            // Keep a reference to the file
            file = _file;

            file.Seek((long)position);

            // Get the header byte
            ByteVector vector      = file.ReadBlock(1);
            Byte       header_byte = vector [0];
            // Define a mask
            Byte mask = 0x80, id_length = 1;

            // Figure out the size in bytes
            while (id_length <= 4 && (header_byte & mask) == 0)
            {
                id_length++;
                mask >>= 1;
            }

            if (id_length > 4)
            {
                throw new CorruptFileException("invalid EBML id size");
            }

            // Now read the rest of the EBML ID
            if (id_length > 1)
            {
                vector.Add(file.ReadBlock(id_length - 1));
            }

            ebml_id = vector.ToUInt();

            vector.Clear();

            // Get the size length
            vector      = file.ReadBlock(1);
            header_byte = vector [0];
            mask        = 0x80;
            Byte size_length = 1;

            // Iterate through various possibilities
            while (size_length <= 8 && (header_byte & mask) == 0)
            {
                size_length++;
                mask >>= 1;
            }

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

            // Clear the marker bit
            vector [0] &= (Byte)(mask - 1);

            // Now read the rest of the EBML element size
            if (size_length > 1)
            {
                vector.Add(file.ReadBlock(size_length - 1));
            }

            ebml_size = vector.ToULong();

            offset      = position;
            data_offset = offset + id_length + size_length;
        }
コード例 #8
0
        /// <summary>
        /// Constructs a <see cref="EBMLElement" /> parsing from provided
        /// file data.
        /// </summary>
        /// <param name="_file"><see cref="File" /> instance to read from.</param>
        /// <param name="position">Position to start reading from.</param>
        public EBMLElement (Matroska.File _file, ulong position)
        {
            if (_file == null)
                throw new ArgumentNullException ("file");

            if (position > (ulong) (_file.Length - 4))
                throw new ArgumentOutOfRangeException ("position");

            // Keep a reference to the file
            file = _file;

            file.Seek ((long) position);

            // Get the header byte
            ByteVector vector = file.ReadBlock (1);
            Byte header_byte = vector [0];
            // Define a mask
            Byte mask = 0x80, id_length = 1;
            // Figure out the size in bytes
            while (id_length <= 4 && (header_byte & mask) == 0) {
                id_length++;
                mask >>= 1;
            }

            if (id_length > 4) {
                throw new CorruptFileException ("invalid EBML id size");
            }

            // Now read the rest of the EBML ID
            if (id_length > 1) {
                vector.Add (file.ReadBlock (id_length -1));
            }

            ebml_id = vector.ToUInt ();

            vector.Clear ();

            // Get the size length
            vector = file.ReadBlock (1);
            header_byte = vector [0];
            mask = 0x80;
            Byte size_length = 1;

            // Iterate through various possibilities
            while (size_length <= 8 && (header_byte & mask) == 0) {
                size_length++;
                mask >>= 1;
            }

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

            // Clear the marker bit
            vector [0] &= (Byte) (mask - 1);

            // Now read the rest of the EBML element size
            if (size_length > 1) {
                vector.Add (file.ReadBlock (size_length - 1));
            }

            ebml_size = vector.ToULong ();

            offset = position;
            data_offset = offset + id_length + size_length;
        }