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); }
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); }
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); }
/// <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(); }
/// <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); }
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; }
/// <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); }
/// <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); }
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; }
/// <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; } }
/// <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); }
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); }
/// <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); }
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(); } }
/// <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]; } }
/// <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); }
/// <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); }
/// <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); } }
/// <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())); } }
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 string ReadString() { if (file == null) { return(null); } file.Seek((long)data_offset); ByteVector vector = file.ReadBlock((int)ebml_size); return(vector.ToString()); }
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); }
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); } } }
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); }
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(); }
/// <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 (); }
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()); }
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(); }
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(); }
/// <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); } }
/// <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; } }
/// <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(); }
/// <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]; } }
/// <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"); }
/// <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; } } } }