예제 #1
0
 /// <summary>
 /// Get an unsigned integer (any size from 1 to 8 bytes) from EBML Element's data section.
 /// </summary>
 /// <returns>a ulong containing the parsed value.</returns>
 public ulong GetULong()
 {
     if (Data == null)
     {
         return(0);
     }
     return(Data.ToULong());
 }
예제 #2
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;
        }
예제 #3
0
        /// <summary>
        /// Read EBML header and data-size if it is an abstract one.
        /// It then becomes a non abstract EBML.
        /// </summary>
        /// <param name="throwException">Throw exception on invalid EBML read if true (Default: false).</param>
        /// <returns>True if successful.</returns>
        public bool Read(bool throwException = false)
        {
            if (!Abstract)
            {
                return(true);
            }

            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            try
            {
                var ex = new InvalidOperationException("Invalid EBML format Read");

                if (offset >= (ulong)(file.Length) - 1)
                {
                    throw ex;
                }

                // Prepare for Consitency check
                uint  ebml_id_check   = ebml_id;
                ulong ebml_size_check = Size;


                file.Seek((long)offset);

                // 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 ex;
                }

                // 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)
                {
                    size_length = 1;                     // Special: Empty element (all zero state)
                }
                else
                {
                    vector[0] &= (Byte)(mask - 1);                      // Clear the marker bit
                }
                // Now read the rest of the EBML element size
                if (size_length > 1)
                {
                    vector.Add(file.ReadBlock(size_length - 1));
                }

                ebml_size = vector.ToULong();

                // Special: Auto-size (0xFF byte)
                if (size_length == 1 && ebml_size == 0x7F)
                {
                    // Resolve auto-size to fill in to its containing element
                    ulong bound = parent == null ? (ulong)file.Length : parent.Offset + parent.Size;
                    ebml_size = bound - offset - (ulong)(id_length + size_length);
                }

                data_offset = offset + id_length + size_length;

                // Consistency check: Detect descrepencies between read data and abstract data
                if (ebml_id_check != 0 && ebml_id_check != ebml_id)
                {
                    throw ex;
                }
                if (ebml_size_check != 0 && ebml_size_check != Size)
                {
                    throw ex;
                }

                return(true);
            }
            catch (Exception ex)
            {
                if (throwException)
                {
                    throw ex;
                }
                return(false);
            }
        }
예제 #4
0
 /// <summary>
 ///    Populates the values in the current instance by parsing
 ///    its field data in a specified version.
 /// </summary>
 /// <param name="data">
 ///    A <see cref="ByteVector" /> object containing the
 ///    extracted field data.
 /// </param>
 /// <param name="version">
 ///    A <see cref="byte" /> indicating the ID3v2 version the
 ///    field data is encoded in.
 /// </param>
 protected override void ParseFields(ByteVector data, byte version)
 {
     play_count = data.ToULong();
 }
예제 #5
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;
        }
 protected override void ParseFields(ByteVector data, byte version)
 {
     this.play_count = data.ToULong();
 }