public Picture(ByteVector data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (data.Count < 0x20)
     {
         throw new CorruptFileException("Data must be at least 32 bytes long");
     }
     int startIndex = 0;
     this.type = (PictureType) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     int count = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.mime_type = data.ToString(StringType.Latin1, startIndex, count);
     startIndex += count;
     int num3 = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.description = data.ToString(StringType.UTF8, startIndex, num3);
     startIndex += num3;
     this.width = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.height = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.color_depth = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.indexed_colors = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     int length = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.picture_data = data.Mid(startIndex, length);
 }
Exemple #2
0
        private static IPicture PictureFromData(ByteVector data)
        {
            if (data.Count < 9)
            {
                return(null);
            }
            int     offset = 0;
            Picture p      = new Picture();

            p.Type  = (PictureType)data[offset];
            offset += 1;
            int size = (int)data.Mid(offset, 4).ToUInt(false);

            offset += 4;
            int found = data.Find(ByteVector.TextDelimiter(StringType.UTF16LE), offset, 2);

            if (found < 0)
            {
                return(null);
            }
            p.MimeType = data.ToString(StringType.UTF16LE, offset, found - offset);
            offset     = found + 2;
            found      = data.Find(ByteVector.TextDelimiter(StringType.UTF16LE), offset, 2);
            if (found < 0)
            {
                return(null);
            }
            p.Description = data.ToString(StringType.UTF16LE, offset, found - offset);
            offset        = found + 2;
            p.Data        = data.Mid(offset, size);
            return(p);
        }
Exemple #3
0
        private void Parse(ByteVector data)
        {
            String currentKey, currentValue;
            int    keyLen, valueLen;

            try
            {
                do
                {
                    keyLen = (int)data.ToUInt(true);
                    data.RemoveRange(0, 4);
                    valueLen = (int)data.ToUInt(true);
                    data.RemoveRange(0, 4);
                    currentKey = data.ToString(TagLib.StringType.UTF8, 0, keyLen);
                    data.RemoveRange(0, keyLen);
                    currentValue = data.ToString(TagLib.StringType.UTF8, 0, valueLen);
                    data.RemoveRange(0, valueLen);
                    tags.Add(new KeyValuePair <string, string>(currentKey, currentValue));
                    if (data.Count != 0)
                    {
                        data.RemoveRange(0, 1);
                    }
                }while(data.Count >= 4);
            }
            catch (Exception)
            {
            }
            if (data.Count != 0)
            {
                throw new CorruptFileException();
            }
        }
 private void Parse(ByteVector data)
 {
     this.title = data.ToString(StringType.Latin1, 0, 0x20).Trim();
     this.artist = data.ToString(StringType.Latin1, 0x20, 0x1c).Trim();
     this.year = data.ToString(StringType.Latin1, 60, 4).Trim();
     this.comment = data.ToString(StringType.Latin1, 0x40, 0x30).Trim();
     this.genre = data.ToString(StringType.Latin1, 0x70, 3).Trim();
     this.extra_data = data.Mid(0x73, 6);
 }
Exemple #5
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)
        {
            if (data.Count < 6)
            {
                throw new CorruptFileException(
                          "Not enough bytes in field.");
            }

            encoding         = (StringType)data [0];
            language         = data.ToString(StringType.Latin1, 1, 3);
            timestamp_format = (TimestampFormat)data [4];
            lyrics_type      = (SynchedTextType)data [5];

            ByteVector delim = ByteVector.TextDelimiter(
                encoding);
            int delim_index = data.Find(delim, 6, delim.Count);

            if (delim_index < 0)
            {
                throw new CorruptFileException(
                          "Text delimiter expected.");
            }

            description = data.ToString(encoding, 6,
                                        delim_index - 6);

            int offset           = delim_index + delim.Count;
            List <SynchedText> l = new List <SynchedText> ();

            while (offset + delim.Count + 4 < data.Count)
            {
                delim_index = data.Find(delim, offset,
                                        delim.Count);

                if (delim_index < offset)
                {
                    throw new CorruptFileException(
                              "Text delimiter expected.");
                }

                string text = data.ToString(encoding, offset,
                                            delim_index - offset);
                offset = delim_index + delim.Count;

                if (offset + 4 > data.Count)
                {
                    break;
                }

                l.Add(new SynchedText(data.Mid(offset, 4)
                                      .ToUInt(), text));
                offset += 4;
            }

            this.text = l.ToArray();
        }
Exemple #6
0
 /// <summary>
 ///    Populates the current instance by parsing the contents of
 ///    a raw DivX tag.
 /// </summary>
 /// <param name="data">
 ///    A <see cref="ByteVector" /> object containing the
 ///    starting with an DivX tag.
 /// </param>
 private void Parse(ByteVector data)
 {
     title      = data.ToString(StringType.Latin1, 0, 32).Trim();
     artist     = data.ToString(StringType.Latin1, 32, 28).Trim();
     year       = data.ToString(StringType.Latin1, 60, 4).Trim();
     comment    = data.ToString(StringType.Latin1, 64, 48).Trim();
     genre      = data.ToString(StringType.Latin1, 112, 3).Trim();
     extra_data = data.Mid(115, 6);
 }
Exemple #7
0
 protected override void ParseFields(ByteVector data, byte version)
 {
     if (data.Count < 4)
     {
         throw new CorruptFileException("Not enough bytes in field.");
     }
     encoding = (StringType)data[0];
     language = data.ToString(StringType.Latin1, 1, 3);
     text     = data.ToString(encoding, 4, data.Count - 4);
 }
        protected override void ParseFields(ByteVector data,
                                            byte version)
        {
            if (data.Count < 4)
            {
                throw new CorruptFileException(
                          "An object frame must contain at least 4 bytes.");
            }

            int start = 0;

            text_encoding = (StringType)data [start++];

            int end = data.Find(
                ByteVector.TextDelimiter(StringType.Latin1),
                start);

            if (end < start)
            {
                return;
            }

            mime_type = data.ToString(StringType.Latin1, start,
                                      end - start);

            ByteVector delim = ByteVector.TextDelimiter(
                text_encoding);

            start = end + 1;
            end   = data.Find(delim, start, delim.Count);

            if (end < start)
            {
                return;
            }

            file_name = data.ToString(text_encoding, start,
                                      end - start);
            start = end + delim.Count;
            end   = data.Find(delim, start, delim.Count);

            if (end < start)
            {
                return;
            }

            description = data.ToString(text_encoding, start,
                                        end - start);
            start = end + delim.Count;

            data.RemoveRange(0, start);
            this.data = data;
        }
Exemple #9
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="Picture" /> by reading the contents of a raw Flac
        ///    image structure.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the raw
        ///    Flac image.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> contains less than 32 bytes.
        /// </exception>
        public Picture(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (data.Count < 32)
            {
                throw new CorruptFileException(
                          "Data must be at least 32 bytes long");
            }

            int pos = 0;

            type = (PictureType)data.Mid(pos, 4).ToUInt();
            pos += 4;

            int mimetype_length = (int)data.Mid(pos, 4).ToUInt();

            pos += 4;

            mime_type = data.ToString(StringType.Latin1, pos,
                                      mimetype_length);
            pos += mimetype_length;

            int description_length = (int)data.Mid(pos, 4)
                                     .ToUInt();

            pos += 4;

            description = data.ToString(StringType.UTF8, pos,
                                        description_length);
            pos += description_length;

            width = (int)data.Mid(pos, 4).ToUInt();
            pos  += 4;

            height = (int)data.Mid(pos, 4).ToUInt();
            pos   += 4;

            color_depth = (int)data.Mid(pos, 4).ToUInt();
            pos        += 4;

            indexed_colors = (int)data.Mid(pos, 4).ToUInt();
            pos           += 4;

            int data_length = (int)data.Mid(pos, 4).ToUInt();

            pos += 4;

            picture_data = data.Mid(pos, data_length);
        }
Exemple #10
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="Picture" /> by reading the contents of a raw Flac
        ///    image structure.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the raw
        ///    Flac image.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> contains less than 32 bytes.
        /// </exception>
        public Picture(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (data.Count < 32)
            {
                throw new CorruptFileException("Data must be at least 32 bytes long");
            }

            int pos = 0;

            Type = (PictureType)data.Mid(pos, 4).ToUInt();
            pos += 4;

            int mimetype_length = (int)data.Mid(pos, 4).ToUInt();

            pos += 4;

            MimeType = data.ToString(StringType.Latin1, pos,
                                     mimetype_length);
            pos += mimetype_length;

            int description_length = (int)data.Mid(pos, 4)
                                     .ToUInt();

            pos += 4;

            Description = data.ToString(StringType.UTF8, pos,
                                        description_length);
            pos += description_length;

            Width = (int)data.Mid(pos, 4).ToUInt();
            pos  += 4;

            Height = (int)data.Mid(pos, 4).ToUInt();
            pos   += 4;

            ColorDepth = (int)data.Mid(pos, 4).ToUInt();
            pos       += 4;

            IndexedColors = (int)data.Mid(pos, 4).ToUInt();
            pos          += 4;

            int data_length = (int)data.Mid(pos, 4).ToUInt();

            pos += 4;

            Data = data.Mid(pos, data_length);
        }
Exemple #11
0
        protected void ParseRawData()
        {
            if (raw_data == null)
            {
                return;
            }
            int pos = 0;
            int offset;

            text_encoding = (StringType)raw_data[pos++];
            if (raw_version > 2)
            {
                offset = raw_data.Find(ByteVector.TextDelimiter(StringType.Latin1), pos);
                if (offset < pos)
                {
                    return;
                }
                mime_type = raw_data.ToString(StringType.Latin1, pos, offset - pos);
                pos       = offset + 1;
            }
            else
            {
                ByteVector ext = raw_data.Mid(pos, 3);
                if (ext == "JPG")
                {
                    mime_type = "image/jpeg";
                }
                else if (ext == "PNG")
                {
                    mime_type = "image/png";
                }
                else
                {
                    mime_type = "image/unknown";
                }
                pos += 3;
            }
            ByteVector delim = ByteVector.TextDelimiter(text_encoding);

            type   = (PictureType)raw_data[pos++];
            offset = raw_data.Find(delim, pos, delim.Count);
            if (offset < pos)
            {
                return;
            }
            description = raw_data.ToString(text_encoding, pos, offset - pos);
            pos         = offset + delim.Count;
            raw_data.RemoveRange(0, pos);
            this.data     = raw_data;
            this.raw_data = null;
        }
Exemple #12
0
        /// <summary>
        /// Get a string from EBML Element's data section (UTF-8).
        /// Handle null-termination.
        /// </summary>
        /// <returns>a string object containing the parsed value.</returns>
        public string GetString()
        {
            if (Data == null)
            {
                return(null);
            }
            var idx = Data.IndexOf(0x00);             // Detected Null termination

            if (idx >= 0)
            {
                return(Data.ToString(StringType.UTF8, 0, idx));
            }
            return(Data.ToString(StringType.UTF8));
        }
        /// <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>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> contains less than 5 bytes.
        /// </exception>
        protected override void ParseFields(ByteVector data, byte version)
        {
            int pos = data.Find(ByteVector.TextDelimiter(StringType.Latin1));

            if (pos < 0)
            {
                return;
            }

            Identification = data.ToString(StringType.Latin1, 0, pos++);

            // Each channel is at least 4 bytes.

            while (pos <= data.Count - 4)
            {
                int type = data[pos++];

                unchecked {
                    channels[type].VolumeAdjustmentIndex = (short)data.Mid(pos, 2).ToUShort();
                }
                pos += 2;

                int bytes = BitsToBytes(data[pos++]);

                if (data.Count < pos + bytes)
                {
                    break;
                }

                channels[type].PeakVolumeIndex = data.Mid(pos, bytes).ToULong();
                pos += bytes;
            }
        }
Exemple #14
0
        /// <summary>
        ///    Reads a COM segment to find the JPEG comment.
        /// </summary>
        /// <param name="length">
        ///    The length of the segment that will be read.
        /// </param>
        private void ReadCOMSegment(int length)
        {
            if ((ImageTag.TagTypes & TagLib.TagTypes.JpegComment) != 0x00)
            {
                return;
            }

            long position = Tell;

            JpegCommentTag com_tag;

            if (length == 0)
            {
                com_tag = new JpegCommentTag();
            }
            else
            {
                ByteVector data = ReadBlock(length);

                int terminator = data.Find("\0", 0);

                if (terminator < 0)
                {
                    com_tag = new JpegCommentTag(data.ToString());
                }
                else
                {
                    com_tag = new JpegCommentTag(data.Mid(0, terminator).ToString());
                }
            }

            ImageTag.AddTag(com_tag);
            AddMetadataBlock(position - 4, length + 4);
        }
Exemple #15
0
        private void ReadzTXtChunk(int data_length)
        {
            long       position = Tell;
            ByteVector data     = ReadChunkData(data_length);

            CheckCRC(zTXt_CHUNK_TYPE, data, ReadCRC());
            int    terminator_index;
            string keyword = ReadKeyword(data, 0, out terminator_index);

            if (terminator_index + 1 >= data_length)
            {
                throw new CorruptFileException("Compression Method byte expected");
            }
            byte       compression_method = data[terminator_index + 1];
            ByteVector plain_data         = Decompress(compression_method, data.Mid(terminator_index + 2));

            if (plain_data == null)
            {
                return;
            }
            string value   = plain_data.ToString();
            PngTag png_tag = GetTag(TagTypes.Png, true)
                             as PngTag;

            if (png_tag.GetKeyword(keyword) == null)
            {
                png_tag.SetKeyword(keyword, value);
            }
            AddMetadataBlock(position - 8, data_length + 8 + 4);
        }
Exemple #16
0
        /// <summary>
        ///    Reads an zTXt Chunk from file. The current position must be set
        ///    to the start of the Chunk Data. Such a Chunk contains compressed
        ///    keywords.
        /// </summary>
        /// <param name="data_length">
        ///    A <see cref="System.Int32"/> with the length of the Chunk Data.
        /// </param>
        /// <remarks>
        ///    The Chunk may also contain compressed Exif data which is written
        ///    by other tools. But, since the PNG specification does not support
        ///    Exif data, we ignore it here.
        /// </remarks>
        private void ReadzTXtChunk(int data_length)
        {
            long position = Tell;

            // zTXt Chunk
            //
            // N Bytes     Keyword
            // 1 Byte      Null Separator
            // 1 Byte      Compression Method
            // N Bytes     Txt
            //
            // Followed by 4 Bytes CRC data

            ByteVector data = ReadChunkData(data_length);

            CheckCRC(zTXt_CHUNK_TYPE, data, ReadCRC());

            int    terminator_index;
            string keyword = ReadKeyword(data, 0, out terminator_index);

            if (terminator_index + 1 >= data_length)
            {
                throw new CorruptFileException("Compression Method byte expected");
            }

            byte compression_method = data [terminator_index + 1];

            ByteVector plain_data = Decompress(compression_method, data.Mid(terminator_index + 2));

            // ignore unknown compression methods
            if (plain_data == null)
            {
                return;
            }

            string     value      = plain_data.ToString();
            RawProfile rawProfile = null;

            if (keyword.StartsWith("Raw profile type"))
            {
                rawProfile = ProcessRawProfile(value);
                value      = rawProfile.ToString();
            }

            // handle XMP, which has a fixed header
            if (keyword == "xmp" || rawProfile != null && string.Compare(rawProfile.Name, "xmp", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                ImageTag.AddTag(new XmpTag(string.Join("", rawProfile.Data.ToArray()), this));
            }
            else
            {
                PngTag png_tag = GetTag(TagTypes.Png, true) as PngTag;

                if (png_tag.GetKeyword(keyword) == null)
                {
                    png_tag.SetKeyword(keyword, value);
                }
            }
            AddMetadataBlock(position - 8, data_length + 8 + 4);
        }
Exemple #17
0
        private void ReadApplicationExtensionBlock()
        {
            long       position = Tell;
            ByteVector data     = ReadBlock(12);

            if (data.Count != 12)
            {
                throw new CorruptFileException("");
            }
            if (data.Mid(1, 8) == XMP_IDENTIFIER && data.Mid(9, 3) == XMP_AUTH_CODE)
            {
                long data_start        = Tell;
                long xmp_trailer_start = Find(new byte[] { 0x00 }, data_start) - XMP_MAGIC_TRAILER.Length + 2;
                Seek(data_start, SeekOrigin.Begin);
                if (xmp_trailer_start <= data_start)
                {
                    throw new CorruptFileException("No End of XMP data found");
                }
                int        data_length = (int)(xmp_trailer_start - data_start);
                ByteVector xmp_data    = ReadBlock(data_length);
                ImageTag.AddTag(new XmpTag(xmp_data.ToString(StringType.UTF8), this));
                AddMetadataBlock(position - 2, 14 + data_length + XMP_MAGIC_TRAILER.Length);
                Seek(xmp_trailer_start + XMP_MAGIC_TRAILER.Length, SeekOrigin.Begin);
            }
            else
            {
                SkipSubBlocks();
            }
        }
Exemple #18
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)
        {
            if (data.Count < 4)
            {
                throw new CorruptFileException(
                          "Not enough bytes in field.");
            }

            encoding = (StringType)data [0];
            language = data.ToString(StringType.Latin1, 1, 3);

            // Instead of splitting into two string, in the format
            // [{desc}\0{value}], try splitting into three strings
            // in case of a misformatted [{desc}\0{value}\0].
            string [] split = data.ToStrings(encoding, 4, 3);

            if (split.Length == 1)
            {
                // Bad comment frame. Assume that it lacks a
                // description.
                description = String.Empty;
                text        = split [0];
            }
            else
            {
                description = split [0];
                text        = split [1];
            }
        }
        /// <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)
        {
            if (data.Count < 4)
            {
                throw new CorruptFileException(
                          "Not enough bytes in field.");
            }

            encoding = (StringType)data [0];
            language = data.ToString(StringType.Latin1, 1, 3);

            string [] split = data.ToStrings(encoding, 4, 2);

            if (split.Length == 1)
            {
                // Bad lyrics frame. Assume that it lacks a
                // description.
                description = String.Empty;
                text        = split [0];
            }
            else
            {
                description = split [0];
                text        = split [1];
            }
        }
Exemple #20
0
        /// <summary>
        ///    Reads a Unicode (UTF-16LE) string of specified length
        ///    from the current instance.
        /// </summary>
        /// <param name="length">
        ///    A <see cref="int" /> value specifying the number of bytes
        ///    to read. This should always be an even number.
        /// </param>
        /// <returns>
        ///    A <see cref="string" /> object containing the Unicode
        ///    string read from the current instance.
        /// </returns>
        public string ReadUnicode(int length)
        {
            ByteVector data   = ReadBlock(length);
            string     output = data.ToString(StringType.UTF16LE);
            int        i      = output.IndexOf('\0');

            return((i >= 0) ? output.Substring(0, i) : output);
        }
Exemple #21
0
        /// <summary>
        ///    Performs the actual parsing of the raw data.
        /// </summary>
        /// <remarks>
        ///    Because of the high parsing cost and relatively low usage
        ///    of the class, <see cref="ParseFields" /> only stores the
        ///    field data so it can be parsed on demand. Whenever a
        ///    property or method is called which requires the data,
        ///    this method is called, and only on the first call does it
        ///    actually parse the data.
        /// </remarks>
        protected void ParseRawData()
        {
            if (raw_data == null)
            {
                return;
            }

            ByteVector data = raw_data;

            raw_data = null;

            // read the string data type (the first byte of the
            // field data)
            encoding = (StringType)data[0];
            List <string> field_list = new List <string>();

            ByteVector delim = ByteVector.TextDelimiter(encoding);

            if (FrameId != FrameType.WXXX)
            {
                field_list.AddRange(data.ToStrings(encoding, 0));
            }
            else if (data.Count > 1 && !data.Mid(0,
                                                 delim.Count).Equals(delim))
            {
                string value = data.ToString(StringType.Latin1, 1,
                                             data.Count - 1);

                // Do a fast removal of end bytes.
                if (value.Length > 1 &&
                    value[value.Length - 1] == 0)
                {
                    for (int i = value.Length - 1; i >= 0; i--)
                    {
                        if (value[i] != 0)
                        {
                            value = value.Substring(0, i + 1);
                            break;
                        }
                    }
                }

                field_list.Add(value);
            }

            // Bad tags may have one or more nul characters at the
            // end of a string, resulting in empty strings at the
            // end of the FieldList. Strip them off.
            while (field_list.Count != 0 &&
                   string.IsNullOrEmpty(field_list[
                                            field_list.Count - 1]))
            {
                field_list.RemoveAt(field_list.Count - 1);
            }

            text_fields = field_list.ToArray();
        }
 //////////////////////////////////////////////////////////////////////////
 // public methods
 //////////////////////////////////////////////////////////////////////////
 public virtual string Parse (ByteVector data)
 {
    if (data == null)
       throw new ArgumentNullException ("data");
    
   string output = data.ToString (StringType.Latin1).Trim ();
   int i = output.IndexOf ('\0');
   return (i >= 0) ? output.Substring (0, i) : output;
 }
 public void CopyResize()
 {
     ByteVector a = new ByteVector(TestVector);
     ByteVector b = ByteVector.FromString("ABCDEFGHIJKL", StringType.UTF8);
     a.Resize(12);
     
     Assert.AreEqual(b, a);
     Assert.AreEqual( b.ToString(), a.ToString());
     Assert.IsFalse(a.Count == TestVector.Count);
 }
 public virtual string Parse(ByteVector data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     string str = data.ToString(StringType.Latin1).Trim();
     int index = str.IndexOf('\0');
     return ((index < 0) ? str : str.Substring(0, index));
 }
		public void CopyResize ()
		{
			var a = new ByteVector (TestVector);
			var b = ByteVector.FromString ("ABCDEFGHIJKL", StringType.UTF8);
			a.Resize (12);

			Assert.AreEqual (b, a);
			Assert.AreEqual (b.ToString (), a.ToString ());
			Assert.IsFalse (a.Count == TestVector.Count);
		}
Exemple #26
0
        /// <summary>
        ///     Populates the current instance by reading in a raw APEv2
        ///     item.
        /// </summary>
        /// <param name="data">
        ///     A <see cref="ByteVector" /> object containing the item to
        ///     read.
        /// </param>
        /// <param name="offset">
        ///     A <see cref="int" /> value specifying the offset in
        ///     <paramref name="data" /> at which the item data begins.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     <paramref name="offset" /> is less than zero.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///     A complete item could not be read.
        /// </exception>
        protected void Parse(ByteVector data, int offset)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            // 11 bytes is the minimum size for an APE item
            if (data.Count < offset + 11)
            {
                throw new CorruptFileException(
                          "Not enough data for APE Item");
            }

            var value_length = data.Mid(offset, 4)
                               .ToUInt(false);

            var flags = data.Mid(offset + 4, 4)
                        .ToUInt(false);

            ReadOnly = (flags & 1) == 1;
            Type     = (ItemType)((flags >> 1) & 3);

            var pos = data.Find(ByteVector.TextDelimiter(
                                    StringType.UTF8), offset + 8);

            Key = data.ToString(StringType.UTF8,
                                offset + 8, pos - offset - 8);

            if (value_length > data.Count - pos - 1)
            {
                throw new CorruptFileException(
                          "Invalid data length.");
            }

            Size = pos + 1 + (int)value_length - offset;

            if (Type == ItemType.Binary)
            {
                this.data = new ReadOnlyByteVector(
                    data.Mid(pos + 1, (int)value_length));
            }
            else
            {
                text = data.Mid(pos + 1,
                                (int)value_length)
                       .ToStrings(
                    StringType.UTF8, 0);
            }
        }
Exemple #27
0
        /// <summary>
        ///    Checks the CRC for a Chunk.
        /// </summary>
        /// <param name="chunk_type">
        ///    A <see cref="ByteVector"/> whith the Chunk type
        /// </param>
        /// <param name="chunk_data">
        ///    A <see cref="ByteVector"/> with the Chunk data.
        /// </param>
        /// <param name="crc_data">
        ///    A <see cref="ByteVector"/> with the read CRC data.
        /// </param>
        private static void CheckCRC(ByteVector chunk_type, ByteVector chunk_data, ByteVector crc_data)
        {
            ByteVector computed_crc = ComputeCRC(chunk_type, chunk_data);

            if (computed_crc != crc_data)
            {
                throw new CorruptFileException(
                          String.Format("CRC check failed for {0} Chunk (expected: 0x{1:X4}, read: 0x{2:X4}",
                                        chunk_type.ToString(), computed_crc.ToUInt(), crc_data.ToUInt()));
            }
        }
Exemple #28
0
        public virtual string Parse(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            string output = data.ToString(StringType.Latin1).Trim();
            int    i      = output.IndexOf('\0');

            return((i >= 0)?output.Substring(0, i):output);
        }
Exemple #29
0
        public string ReadString()
        {
            if (file == null)
            {
                return(null);
            }
            file.Seek((long)data_offset);
            ByteVector vector = file.ReadBlock((int)ebml_size);

            return(vector.ToString());
        }
Exemple #30
0
 public Picture (ByteVector data)
 {
    if (data == null)
       throw new ArgumentNullException ("data");
    
    if (data.Count < 32)
       throw new CorruptFileException ("Data must be at least 32 bytes long");
    
    int pos = 0;
    _type = (PictureType) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    int mimetype_length = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _mimetype = data.ToString (StringType.Latin1, pos, mimetype_length);
    pos += mimetype_length;
    
    int description_length = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _description = data.ToString (StringType.UTF8, pos, description_length);
    pos += description_length;
    
    _width = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _height = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _color_depth = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _indexed_colors = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    int data_length = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _data = data.Mid (pos, data_length);
 }
Exemple #31
0
        protected void Parse(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            int pos           = 0;
            int vendor_length = (int)data.Mid(pos, 4).ToUInt(false);

            pos      += 4;
            vendor_id = data.ToString(StringType.UTF8, pos, vendor_length);
            pos      += vendor_length;
            int comment_fields = (int)data.Mid(pos, 4).ToUInt(false);

            pos += 4;
            for (int i = 0; i < comment_fields; i++)
            {
                int comment_length = (int)data.Mid(pos, 4).ToUInt(false);
                pos += 4;
                string comment = data.ToString(StringType.UTF8, pos, comment_length);
                pos += comment_length;
                int comment_separator_position = comment.IndexOf('=');
                if (comment_separator_position < 0)
                {
                    continue;
                }
                string   key   = comment.Substring(0, comment_separator_position).ToUpper(CultureInfo.InvariantCulture);
                string   value = comment.Substring(comment_separator_position + 1);
                string[] values;
                if (field_list.TryGetValue(key, out values))
                {
                    Array.Resize <string>(ref values, values.Length + 1);
                    values[values.Length - 1] = value;
                    field_list[key]           = values;
                }
                else
                {
                    SetField(key, value);
                }
            }
        }
Exemple #32
0
        public void CommentsFrameError()
        {
            // http://bugzilla.gnome.org/show_bug.cgi?id=582735
            // Comments data found in the wild
            ByteVector vector = new ByteVector (
                1, 255, 254, 73, 0, 68, 0, 51, 0, 71, 0, 58, 0, 32, 0, 50, 0, 55, 0, 0, 0);

            var encoding = (StringType) vector [0];
            var language = vector.ToString (StringType.Latin1, 1, 3);
            var split = vector.ToStrings (encoding, 4, 3);
            Assert.AreEqual (2, split.Length);
        }
Exemple #33
0
 public override string ToString()
 {
     if (type == DataType.Unicode)
     {
         return(strValue);
     }
     if (type == DataType.Bytes)
     {
         return(byteValue.ToString(StringType.UTF16LE));
     }
     return(longValue.ToString());
 }
 protected override void ParseFields(ByteVector data, byte version)
 {
     ByteVector pattern = ByteVector.TextDelimiter(StringType.Latin1);
     int count = data.Find(pattern);
     if (count < 0)
     {
         throw new CorruptFileException("Popularimeter frame does not contain a text delimiter");
     }
     this.user = data.ToString(StringType.Latin1, 0, count);
     this.rating = data[count + 1];
     this.play_count = data.Mid(count + 2).ToULong();
 }
Exemple #35
0
        /// <summary>
        ///    Populates the current instance by parsing the contents of
        ///    a raw AudibleMetadata tag.
        /// </summary>
        /// <param name="data">
        ///     A <see cref="ByteVector" /> object containing the whole tag
        ///     object
        /// </param>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> is less than 128 bytes or does
        ///    not start with <see cref="FileIdentifier" />.
        /// </exception>
        private void Parse(ByteVector data)
        {
            String currentKey, currentValue;
            int    keyLen, valueLen;

            try
            {
                do
                {
                    keyLen = (int)data.ToUInt(true);
                    data.RemoveRange(0, 4);
                    valueLen = (int)data.ToUInt(true);
                    data.RemoveRange(0, 4);
                    currentKey = data.ToString(TagLib.StringType.UTF8, 0, keyLen);
                    data.RemoveRange(0, keyLen);
                    currentValue = data.ToString(TagLib.StringType.UTF8, 0, valueLen);
                    data.RemoveRange(0, valueLen);

                    tags.Add(new KeyValuePair <string, string>(currentKey, currentValue));

                    //StringHandle (currentKey, currentValue);

                    // if it is not the last item remove the end byte (null terminated)
                    if (data.Count != 0)
                    {
                        data.RemoveRange(0, 1);
                    }
                }while (data.Count >= 4);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                //
            }

            if (data.Count != 0)
            {
                throw new CorruptFileException();
            }
        }
		private string CreateDataString (int min_size)
		{
			string src = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

			ByteVector data = new ByteVector ();

			for (int i = 0; data.Count < min_size; i++)
			{
				int index = i % src.Length;
				data.Add (src.Substring (index, src.Length - index));
			}

			return data.ToString ();
		}
Exemple #37
0
        private string CreateDataString(int min_size)
        {
            string src = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

            ByteVector data = new ByteVector();

            for (int i = 0; data.Count < min_size; i++)
            {
                int index = i % src.Length;
                data.Add(src.Substring(index, src.Length - index));
            }

            return(data.ToString());
        }
Exemple #38
0
        protected override void ParseFields(ByteVector data, byte version)
        {
            ByteVector delim = ByteVector.TextDelimiter(StringType.Latin1);
            int        index = data.Find(delim);

            if (index < 0)
            {
                throw new CorruptFileException("Popularimeter frame does not contain a text delimiter");
            }
            if (index + 2 > data.Count)
            {
                throw new CorruptFileException("Popularimeter is too short");
            }
            user       = data.ToString(StringType.Latin1, 0, index);
            rating     = data[index + 1];
            play_count = data.Mid(index + 2).ToULong();
        }
Exemple #39
0
        private void ReadAPP1Segment(ushort length)
        {
            long       position           = Tell;
            ByteVector data               = null;
            int        exif_header_length = 14;

            if ((ImageTag.TagTypes & TagLib.TagTypes.TiffIFD) == 0x00 && length >= exif_header_length)
            {
                data = ReadBlock(exif_header_length);
                if (data.Count == exif_header_length && data.Mid(0, 6).ToString().Equals(EXIF_IDENTIFIER))
                {
                    bool   is_bigendian = data.Mid(6, 2).ToString().Equals("MM");
                    ushort magic        = data.Mid(8, 2).ToUShort(is_bigendian);
                    if (magic != 42)
                    {
                        throw new Exception(String.Format("Invalid TIFF magic: {0}", magic));
                    }
                    uint ifd_offset = data.Mid(10, 4).ToUInt(is_bigendian);
                    var  exif       = new IFDTag();
                    var  reader     = new IFDReader(this, is_bigendian, exif.Structure, position + 6, ifd_offset, (uint)(length - 6));
                    reader.Read();
                    ImageTag.AddTag(exif);
                    AddMetadataBlock(position - 4, length + 4);
                    return;
                }
            }
            int xmp_header_length = XmpTag.XAP_NS.Length + 1;

            if ((ImageTag.TagTypes & TagLib.TagTypes.XMP) == 0x00 && length >= xmp_header_length)
            {
                if (data == null)
                {
                    data = ReadBlock(xmp_header_length);
                }
                else
                {
                    data.Add(ReadBlock(xmp_header_length - exif_header_length));
                }
                if (data.ToString().Equals(XmpTag.XAP_NS + "\0"))
                {
                    ByteVector xmp_data = ReadBlock(length - xmp_header_length);
                    ImageTag.AddTag(new XmpTag(xmp_data.ToString(), this));
                    AddMetadataBlock(position - 4, length + 4);
                }
            }
        }
		/// <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)
		{
			if (data.Count < 4)
				throw new CorruptFileException (
					"Not enough bytes in field.");
			
			encoding = (StringType) data [0];
			language = data.ToString (StringType.Latin1, 1, 3);
			text = data.ToString (encoding, 4, data.Count - 4);
		}
        /// <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)
        {
            if (data.Count < 6)
                throw new CorruptFileException (
                    "Not enough bytes in field.");

            encoding = (StringType) data [0];
            language = data.ToString (StringType.Latin1, 1, 3);
            timestamp_format = (TimestampFormat) data [4];
            lyrics_type = (SynchedTextType) data [5];

            ByteVector delim = ByteVector.TextDelimiter (
                encoding);
            int delim_index = data.Find (delim, 6, delim.Count);

            if (delim_index < 0)
                throw new CorruptFileException (
                    "Text delimiter expected.");

            description = data.ToString (encoding, 6,
                delim_index - 6);

            int offset = delim_index + delim.Count;
            List<SynchedText> l = new List<SynchedText> ();

            while (offset + delim.Count + 4 < data.Count) {
                delim_index = data.Find (delim, offset,
                    delim.Count);

                if (delim_index < offset)
                    throw new CorruptFileException (
                        "Text delimiter expected.");

                string text = data.ToString (encoding, offset,
                    delim_index - offset);
                offset = delim_index + delim.Count;

                if (offset + 4 > data.Count)
                    break;

                l.Add (new SynchedText (data.Mid (offset, 4)
                    .ToUInt (), text));
                offset += 4;
            }

            this.text = l.ToArray ();
        }
 protected override void ParseFields(ByteVector data, byte version)
 {
     if (data.Count < 4)
     {
         throw new CorruptFileException("Not enough bytes in field.");
     }
     this.encoding = (StringType) data[0];
     this.language = data.ToString(StringType.Latin1, 1, 3);
     string[] strArray = data.ToStrings(this.encoding, 4, 2);
     if (strArray.Length == 1)
     {
         this.description = string.Empty;
         this.text = strArray[0];
     }
     else
     {
         this.description = strArray[0];
         this.text = strArray[1];
     }
 }
 protected override void ParseFields(ByteVector data, byte version)
 {
     if (data.Count < 6)
     {
         throw new CorruptFileException("Not enough bytes in field.");
     }
     this.encoding = (StringType) data[0];
     this.language = data.ToString(StringType.Latin1, 1, 3);
     this.timestamp_format = (TimestampFormat) data[4];
     this.lyrics_type = (SynchedTextType) data[5];
     ByteVector pattern = ByteVector.TextDelimiter(this.encoding);
     int num = data.Find(pattern, 6, pattern.Count);
     if (num < 0)
     {
         throw new CorruptFileException("Text delimiter expected.");
     }
     this.description = data.ToString(this.encoding, 6, num - 6);
     int offset = num + pattern.Count;
     List<SynchedText> list = new List<SynchedText>();
     while (((offset + pattern.Count) + 4) < data.Count)
     {
         num = data.Find(pattern, offset, pattern.Count);
         if (num < offset)
         {
             throw new CorruptFileException("Text delimiter expected.");
         }
         string text = data.ToString(this.encoding, offset, num - offset);
         offset = num + pattern.Count;
         if ((offset + 4) > data.Count)
         {
             break;
         }
         list.Add(new SynchedText((long) data.Mid(offset, 4).ToUInt(), text));
         offset += 4;
     }
     this.text = list.ToArray();
 }
Exemple #44
0
		/// <summary>
		///    Converts a raw ASF picture into an <see cref="IPicture"
		///    /> object.
		/// </summary>
		/// <param name="data">
		///    A <see cref="ByteVector" /> object containing raw ASF
		///    picture data.
		/// </param>
		/// <returns>
		///    A <see cref="IPicture" /> object to read from the raw
		///    data.
		/// </returns>
		private static IPicture PictureFromData (ByteVector data)
		{
			if (data.Count < 9)
				return null;
			
			int offset = 0;
			Picture p = new Picture ();
			
			// Get the picture type:
			
			p.Type = (PictureType) data [offset];
			offset += 1;
			
			// Get the picture size:
			
			int size = (int) data.Mid (offset, 4).ToUInt (false);
			offset += 4;
			
			// Get the mime-type:
			
			int found = data.Find (ByteVector.TextDelimiter (
				StringType.UTF16LE), offset, 2);
			if (found < 0)
				return null;
			
			p.MimeType = data.ToString (StringType.UTF16LE, offset,
				found - offset);
			offset = found + 2;
			
			// Get the description:
			
			found = data.Find (ByteVector.TextDelimiter (
				StringType.UTF16LE), offset, 2);
			if (found < 0)
				return null;
			
			p.Description = data.ToString (StringType.UTF16LE,
				offset, found - offset);
			offset = found + 2;
			
			p.Data = data.Mid (offset, size);
			
			return p;
		}
 protected override void ParseFields(ByteVector data, byte version)
 {
     int startIndex = data.Find(ByteVector.TextDelimiter(StringType.Latin1));
     if (startIndex >= 0)
     {
         this.identification = data.ToString(StringType.Latin1, 0, startIndex++);
         while (startIndex <= (data.Count - 4))
         {
             int index = data[startIndex++];
             this.channels[index].VolumeAdjustmentIndex = (short) data.Mid(startIndex, 2).ToUShort();
             startIndex += 2;
             int length = BitsToBytes(data[startIndex++]);
             if (data.Count < (startIndex + length))
             {
                 break;
             }
             this.channels[index].PeakVolumeIndex = data.Mid(startIndex, length).ToULong();
             startIndex += length;
         }
     }
 }
 protected void Parse(ByteVector data, int offset)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (offset < 0)
     {
         throw new ArgumentOutOfRangeException("offset");
     }
     if (data.Count < (offset + 11))
     {
         throw new CorruptFileException("Not enough data for APE Item");
     }
     uint num = data.Mid(offset, 4).ToUInt(false);
     uint num2 = data.Mid(offset + 4, 4).ToUInt(false);
     this.ReadOnly = (num2 & 1) == 1;
     this.Type = ((ItemType) (num2 >> 1)) & (ItemType.Locator | ItemType.Binary);
     int num3 = data.Find(ByteVector.TextDelimiter(StringType.UTF8), offset + 8);
     this.key = data.ToString(StringType.UTF8, offset + 8, (num3 - offset) - 8);
     if (num > ((data.Count - num3) - 1))
     {
         throw new CorruptFileException("Invalid data length.");
     }
     this.size_on_disk = ((num3 + 1) + ((int) num)) - offset;
     if (this.Type == ItemType.Binary)
     {
         this.data = new ReadOnlyByteVector(data.Mid(num3 + 1, (int) num));
     }
     else
     {
         this.text = data.Mid(num3 + 1, (int) num).ToStrings(StringType.UTF8, 0);
     }
 }
Exemple #47
0
		/// <summary>
		///    Populates the current instance by reading in a raw APEv2
		///    item.
		/// </summary>
		/// <param name="data">
		///    A <see cref="ByteVector" /> object containing the item to
		///    read.
		/// </param>
		/// <param name="offset">
		///    A <see cref="int" /> value specifying the offset in
		///    <paramref name="data" /> at which the item data begins.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///    <paramref name="data" /> is <see langword="null" />.
		/// </exception>
		/// <exception cref="ArgumentOutOfRangeException">
		///    <paramref name="offset" /> is less than zero.
		/// </exception>
		/// <exception cref="CorruptFileException">
		///    A complete item could not be read.
		/// </exception>
		protected void Parse (ByteVector data, int offset)
		{
			if (data == null)
				throw new ArgumentNullException ("data");
			
			if (offset < 0)
				throw new ArgumentOutOfRangeException ("offset");
			
			
			// 11 bytes is the minimum size for an APE item
			if(data.Count < offset + 11)
				throw new CorruptFileException (
					"Not enough data for APE Item");
			
			uint value_length = data.Mid (offset, 4).ToUInt (false);
			uint flags = data.Mid (offset + 4, 4).ToUInt (false);
			
			ReadOnly = (flags & 1) == 1;
			Type = (ItemType) ((flags >> 1) & 3);
			
			int pos = data.Find (ByteVector.TextDelimiter (
				StringType.UTF8), offset + 8);
			
			key = data.ToString (StringType.UTF8,
				offset + 8, pos - offset - 8);
			
			if (value_length > data.Count - pos - 1)
				throw new CorruptFileException (
					"Invalid data length.");
			
			size_on_disk = pos + 1 + (int) value_length - offset;
			
			if (Type == ItemType.Binary)
				this.data = new ReadOnlyByteVector (
					data.Mid (pos + 1, (int) value_length));
			else
				this.text = data.Mid (pos + 1,
					(int) value_length).ToStrings (
						StringType.UTF8, 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>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> contains less than 5 bytes.
        /// </exception>
        protected override void ParseFields(ByteVector data,
            byte version)
        {
            int pos = data.Find (ByteVector.TextDelimiter (
                StringType.Latin1));
            if (pos < 0)
                return;

            identification = data.ToString (StringType.Latin1, 0,
                pos++);

            // Each channel is at least 4 bytes.

            while (pos <= data.Count - 4) {
                int type = data [pos++];

                unchecked {
                    channels [type].VolumeAdjustmentIndex =
                        (short) data.Mid (pos,
                            2).ToUShort ();
                }
                pos += 2;

                int bytes = BitsToBytes (data [pos++]);

                if (data.Count < pos + bytes)
                    break;

                channels [type].PeakVolumeIndex = data.Mid (pos,
                    bytes).ToULong ();
                pos += bytes;
            }
        }
Exemple #49
0
		/// <summary>
		///    Populates the current instance by parsing the contents of
		///    a raw AudibleMetadata tag.
		/// </summary>
		/// <param name="data">
		///    	A <see cref="ByteVector" /> object containing the whole tag
		/// 	object
		/// </param>
		/// <exception cref="CorruptFileException">
		///    <paramref name="data" /> is less than 128 bytes or does
		///    not start with <see cref="FileIdentifier" />.
		/// </exception>
		private void Parse (ByteVector data)
		{
			String currentKey, currentValue;
			int keyLen, valueLen;
			
			try
			{
				do
				{
					keyLen = (int) data.ToUInt(true);
					data.RemoveRange (0, 4);
					valueLen = (int) data.ToUInt(true);
					data.RemoveRange (0, 4);
					currentKey = data.ToString ( TagLib.StringType.UTF8, 0, keyLen );
					data.RemoveRange (0, keyLen);
					currentValue = data.ToString ( TagLib.StringType.UTF8, 0, valueLen );
					data.RemoveRange (0, valueLen);
					
					tags.Add( new KeyValuePair<string, string>(currentKey, currentValue) );
					
					//StringHandle (currentKey, currentValue);
					
					// if it is not the last item remove the end byte (null terminated)
					if (data.Count != 0)
						data.RemoveRange(0,1);
				}
				while (data.Count >= 4);
			}
			catch (Exception)
			{
				//
			}
			
			if (data.Count != 0)
				throw new CorruptFileException();
		}
Exemple #50
0
		/// <summary>
		///    Populates the current instance by parsing the contents of
		///    a raw DivX tag.
		/// </summary>
		/// <param name="data">
		///    A <see cref="ByteVector" /> object containing the
		///    starting with an DivX tag.
		/// </param>
		private void Parse (ByteVector data)
		{
			title      = data.ToString (StringType.Latin1,  0, 32).Trim ();
			artist     = data.ToString (StringType.Latin1, 32, 28).Trim ();
			year       = data.ToString (StringType.Latin1, 60,  4).Trim ();
			comment    = data.ToString (StringType.Latin1, 64, 48).Trim ();
			genre      = data.ToString (StringType.Latin1,112,  3).Trim ();
			extra_data = data.Mid (115,  6);
		}
        /// <summary>
        ///    Construcor.
        /// </summary>
        /// <param name="tag">
        ///    A <see cref="System.UInt16"/> with the tag ID of the entry this instance
        ///    represents
        /// </param>
        /// <param name="data">
        ///    A <see cref="ByteVector"/> to be stored
        /// </param>
        /// <param name="file">
        ///    The file that's currently being parsed, used for reporting corruptions.
        /// </param>
        public UserCommentIFDEntry(ushort tag, ByteVector data, TagLib.File file)
        {
            Tag = tag;

            if (data.StartsWith (COMMENT_ASCII_CODE)) {
                Value = TrimNull (data.ToString (StringType.Latin1, COMMENT_ASCII_CODE.Count, data.Count - COMMENT_ASCII_CODE.Count));
                return;
            }

            if (data.StartsWith (COMMENT_UNICODE_CODE)) {
                Value = TrimNull (data.ToString (StringType.UTF8, COMMENT_UNICODE_CODE.Count, data.Count - COMMENT_UNICODE_CODE.Count));
                return;
            }

            var trimmed = data.ToString ().Trim ();
            if (trimmed.Length == 0 || trimmed == "\0") {
                Value = String.Empty;
                return;
            }

            // Some programs like e.g. CanonZoomBrowser inserts just the first 0x00-byte
            // followed by 7-bytes of trash.
            if (data.StartsWith ((byte) 0x00) && data.Count >= 8) {

                // And CanonZoomBrowser fills some trailing bytes of the comment field
                // with '\0'. So we return only the characters before the first '\0'.
                int term = data.Find ("\0", 8);
                if (term != -1) {
                    Value = data.ToString (StringType.Latin1, 8, term - 8);
                } else {
                    Value = data.ToString (StringType.Latin1, 8, data.Count - 8);
                }
                return;
            }

            if (data.Data.Length == 0) {
                Value = String.Empty;
                return;
            }

            // Try to parse anyway
            int offset = 0;
            int length = data.Count - offset;

            // Corruption that starts with a Unicode header and a count byte.
            if (data.StartsWith (COMMENT_BAD_UNICODE_CODE)) {
                offset = COMMENT_BAD_UNICODE_CODE.Count;
                length = data.Count - offset;
            }

            file.MarkAsCorrupt ("UserComment with other encoding than Latin1 or Unicode");
            Value = TrimNull (data.ToString (StringType.UTF8, offset, length));
        }
		/// <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)
		{
			if (data.Count < 4)
				throw new CorruptFileException (
					"Not enough bytes in field.");
			
			encoding = (StringType) data [0];
			language = data.ToString (StringType.Latin1, 1, 3);
			
			// Instead of splitting into two string, in the format
			// [{desc}\0{value}], try splitting into three strings
			// in case of a misformatted [{desc}\0{value}\0].
			string [] split = data.ToStrings (encoding, 4, 3);
			
			if (split.Length == 0) {
				// No data in the frame.
				description = String.Empty;
				text        = String.Empty;
			} else if (split.Length == 1) {
				// Bad comment frame. Assume that it lacks a
				// description.
				description = String.Empty;
				text        = split [0];
			} else {
				description = split [0];
				text        = split [1];
			}
		}
Exemple #53
0
		/// <summary>
		///    Construcor.
		/// </summary>
		/// <param name="tag">
		///    A <see cref="System.UInt16"/> with the tag ID of the entry this instance
		///    represents
		/// </param>
		/// <param name="data">
		///    A <see cref="ByteVector"/> to be stored
		/// </param>
		public UserCommentIFDEntry (ushort tag, ByteVector data)
		{
			Tag = tag;

			if (data.StartsWith (COMMENT_ASCII_CODE)) {
				Value = data.ToString (StringType.Latin1, COMMENT_ASCII_CODE.Count, data.Count - COMMENT_ASCII_CODE.Count);
				return;
			}

			if (data.StartsWith (COMMENT_UNICODE_CODE)) {
				Value = data.ToString (StringType.UTF8, COMMENT_UNICODE_CODE.Count, data.Count - COMMENT_UNICODE_CODE.Count);
				return;
			}
				
			// Some programs like e.g. CanonZoomBrowser inserts just the first 0x00-byte
			// followed by 7-bytes of trash.
			if (data.StartsWith ((byte) 0x00) && data.Count >= 8) {
					
				// And CanonZoomBrowser fills some trailing bytes of the comment field
				// with '\0'. So we return only the characters before the first '\0'.
				int term = data.Find ("\0", 8);
				if (term != -1) {
					Value = data.ToString (StringType.Latin1, 8, term - 8);
				} else {
					Value = data.ToString (StringType.Latin1, 8, data.Count - 8);
				}
				return;
			}

			if (data.Data.Length == 0) {
				Value = String.Empty;
				return;
			}
			
			throw new NotImplementedException ("UserComment with other encoding than Latin1 or Unicode");
		}
Exemple #54
0
		/// <summary>
		///    Checks the CRC for a Chunk.
		/// </summary>
		/// <param name="chunk_type">
		///    A <see cref="ByteVector"/> whith the Chunk type
		/// </param>
		/// <param name="chunk_data">
		///    A <see cref="ByteVector"/> with the Chunk data.
		/// </param>
		/// <param name="crc_data">
		///    A <see cref="ByteVector"/> with the read CRC data.
		/// </param>
		private static void CheckCRC (ByteVector chunk_type, ByteVector chunk_data, ByteVector crc_data)
		{
			ByteVector computed_crc = ComputeCRC (chunk_type, chunk_data);

			if (computed_crc != crc_data)
				throw new CorruptFileException (
					String.Format ("CRC check failed for {0} Chunk (expected: 0x{1:X4}, read: 0x{2:X4}",
					               chunk_type.ToString (), computed_crc.ToUInt (), crc_data.ToUInt ()));
		}
		/// <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)
		{
			if (data.Count < 4)
				throw new CorruptFileException (
					"Not enough bytes in field.");
			
			encoding = (StringType) data [0];
			language = data.ToString (StringType.Latin1, 1, 3);
			
			string [] split = data.ToStrings (encoding, 4, 2);
			
			if (split.Length == 1) {
				// Bad lyrics frame. Assume that it lacks a
				// description.
				description = String.Empty;
				text = split [0];
			} else {
				description = split [0];
				text = split [1];
			}
		}
        /// <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>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> contains less than 5 bytes.
        /// </exception>
        protected override void ParseFields(ByteVector data,
            byte version)
        {
            if (data.Count < 4)
                throw new CorruptFileException (
                    "An object frame must contain at least 4 bytes.");

            int start = 0;

            encoding =  (StringType) data [start++];

            int end = data.Find (
                ByteVector.TextDelimiter (StringType.Latin1),
                start);

            if (end < start)
                return;

            mime_type = data.ToString (StringType.Latin1, start,
                end - start);

            ByteVector delim = ByteVector.TextDelimiter (
                encoding);
            start = end + 1;
            end = data.Find (delim, start, delim.Count);

            if (end < start)
                return;

            file_name = data.ToString (encoding, start,
                end - start);
            start = end + delim.Count;
            end = data.Find (delim, start, delim.Count);

            if (end < start)
                return;

            description = data.ToString (encoding, start,
                end - start);
            start = end + delim.Count;

            data.RemoveRange (0, start);
            this.data = data;
        }
		/// <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)
		{
			ByteVector delim = ByteVector.TextDelimiter (
				StringType.Latin1);
			
			int index = data.Find (delim);
			if (index < 0)
				throw new CorruptFileException (
					"Popularimeter frame does not contain a text delimiter");
			
			user = data.ToString (StringType.Latin1, 0, index);
			rating = data [index + 1];
			play_count = data.Mid (index + 2).ToULong ();
		}
 protected override void ParseFields(ByteVector data, byte version)
 {
     if (data.Count < 4)
     {
         throw new CorruptFileException("An object frame must contain at least 4 bytes.");
     }
     int offset = 0;
     this.encoding = (StringType) data[offset++];
     int num2 = data.Find(ByteVector.TextDelimiter(StringType.Latin1), offset);
     if (num2 >= offset)
     {
         this.mime_type = data.ToString(StringType.Latin1, offset, num2 - offset);
         ByteVector pattern = ByteVector.TextDelimiter(this.encoding);
         offset = num2 + 1;
         num2 = data.Find(pattern, offset, pattern.Count);
         if (num2 >= offset)
         {
             this.file_name = data.ToString(this.encoding, offset, num2 - offset);
             offset = num2 + pattern.Count;
             num2 = data.Find(pattern, offset, pattern.Count);
             if (num2 >= offset)
             {
                 this.description = data.ToString(this.encoding, offset, num2 - offset);
                 offset = num2 + pattern.Count;
                 data.RemoveRange(0, offset);
                 this.data = data;
             }
         }
     }
 }