/// <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); }
/// <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; var field_list = new List <string> (); ByteVector delim = ByteVector.TextDelimiter(encoding); if (FrameId != FrameType.WXXX) { field_list.AddRange(data.ToStrings(StringType.Latin1, 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(); }
/// <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> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> protected override ByteVector RenderFields(byte version) { StringType encoding = CorrectEncoding(TextEncoding, version); ByteVector v = new ByteVector(); v.Add((byte)encoding); v.Add(ByteVector.FromString(Language, StringType.Latin1)); v.Add(ByteVector.FromString(description, encoding)); v.Add(ByteVector.TextDelimiter(encoding)); v.Add(ByteVector.FromString(text, encoding)); return(v); }
/// <summary> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> protected override ByteVector RenderFields(byte version) { var encoding = CorrectEncoding(TextEncoding, version); var v = new ByteVector { (byte)encoding, ByteVector.FromString(Language, StringType.Latin1), ByteVector.FromString(description, encoding), ByteVector.TextDelimiter(encoding), ByteVector.FromString(text, encoding) }; return(v); }
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; }
protected override ByteVector RenderFields(byte version) { if (version < 4) { throw new NotImplementedException(); } ByteVector data = new ByteVector(); data.Add(ByteVector.FromString(identification, StringType.Latin1)); data.Add(ByteVector.TextDelimiter(StringType.Latin1)); for (byte i = 0; i < 9; i++) { if (!channels [i].IsSet) { continue; } data.Add(i); unchecked { data.Add(ByteVector.FromUShort( (ushort)channels [i] .VolumeAdjustmentIndex)); } byte bits = 0; for (byte j = 0; j < 64; j++) { if ((channels [i].PeakVolumeIndex & (1UL << j)) != 0) { bits = (byte)(j + 1); } } data.Add(bits); if (bits > 0) { data.Add(ByteVector.FromULong( channels [i].PeakVolumeIndex) .Mid(8 - BitsToBytes(bits))); } } return(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) { if (data.Count < 1) { throw new CorruptFileException("A private frame must contain at least 1 byte."); } var l = ByteVectorCollection.Split(data, ByteVector.TextDelimiter(StringType.Latin1), 1, 2); if (l.Count == 2) { Owner = l[0].ToString(StringType.Latin1); PrivateData = l[1]; } }
/// <summary> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> /// <exception cref="NotImplementedException"> /// <paramref name="version" /> is less than 3. ID3v2.2 does /// not support this frame. /// </exception> protected override ByteVector RenderFields(byte version) { if (version < 3) { throw new NotImplementedException(); } ByteVector v = new ByteVector(); v.Add(ByteVector.FromString(owner, StringType.Latin1)); v.Add(ByteVector.TextDelimiter(StringType.Latin1)); v.Add(data); return(v); }
/// <summary> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> /// <exception cref="NotImplementedException"> /// <paramref name="version" /> is less than 3. ID3v2.2 does /// not support this frame. /// </exception> protected override ByteVector RenderFields(byte version) { if (version < 3) { throw new NotImplementedException(); } var v = new ByteVector { ByteVector.FromString(Owner, StringType.Latin1), ByteVector.TextDelimiter(StringType.Latin1), PrivateData }; return(v); }
/// <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."); } TextEncoding = (StringType)data[0]; language = data.ToString(StringType.Latin1, 1, 3); Format = (TimestampFormat)data[4]; Type = (SynchedTextType)data[5]; var delim = ByteVector.TextDelimiter(TextEncoding); int delim_index = data.Find(delim, 6, delim.Count); if (delim_index < 0) { throw new CorruptFileException("Text delimiter expected."); } Description = data.ToString(TextEncoding, 6, delim_index - 6); int offset = delim_index + delim.Count; var 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(TextEncoding, 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) { 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(); }
/// <summary> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> protected override ByteVector RenderFields(byte version) { if (raw_data != null && raw_version == version) { return(raw_data); } StringType encoding = CorrectEncoding(TextEncoding, version); ByteVector data = new ByteVector(); data.Add((byte)encoding); if (version == 2) { switch (MimeType) { case "image/png": data.Add("PNG"); break; case "image/jpeg": data.Add("JPG"); break; default: data.Add("XXX"); break; } } else { data.Add(ByteVector.FromString(MimeType, StringType.Latin1)); data.Add(ByteVector.TextDelimiter( StringType.Latin1)); } data.Add((byte)type); data.Add(ByteVector.FromString(Description, encoding)); data.Add(ByteVector.TextDelimiter(encoding)); data.Add(this.data); return(data); }
protected override ByteVector RenderFields(byte version) { StringType encoding = CorrectEncoding(TextEncoding, version); ByteVector delim = ByteVector.TextDelimiter(encoding); ByteVector v = new ByteVector(); v.Add((byte)encoding); v.Add(ByteVector.FromString(Language, StringType.Latin1)); v.Add((byte)timestamp_format); v.Add((byte)lyrics_type); v.Add(ByteVector.FromString(description, encoding)); v.Add(delim); foreach (SynchedText t in text) { v.Add(ByteVector.FromString(t.Text, encoding)); v.Add(delim); v.Add(ByteVector.FromUInt((uint)t.Time)); } return(v); }
/// <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> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> protected override ByteVector RenderFields(byte version) { var encoding = CorrectEncoding(TextEncoding, version); var delim = ByteVector.TextDelimiter(encoding); var v = new ByteVector { (byte)encoding, ByteVector.FromString(Language, StringType.Latin1), (byte)Format, (byte)Type, ByteVector.FromString(Description, encoding), delim }; foreach (SynchedText t in text) { v.Add(ByteVector.FromString(t.Text, encoding)); v.Add(delim); v.Add(ByteVector.FromUInt((uint)t.Time)); } return(v); }
protected void ParseRawData() { if (raw_data == null) { return; } ByteVector data = raw_data; raw_data = null; List <string> field_list = new List <string>(); ByteVector delim = ByteVector.TextDelimiter(encoding); if (FrameId != FrameType.WXXX) { field_list.AddRange(data.ToStrings(StringType.Latin1, 0)); } else if (data.Count > 1 && !data.Mid(0, delim.Count).Equals(delim)) { string value = data.ToString(StringType.Latin1, 1, data.Count - 1); 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); } 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(); }
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; }
protected override ByteVector RenderFields(byte version) { StringType encoding = CorrectEncoding(this.encoding, version); ByteVector v = new ByteVector(); v.Add((byte)encoding); if (MimeType != null) { v.Add(ByteVector.FromString(MimeType, StringType.Latin1)); } v.Add(ByteVector.TextDelimiter(StringType.Latin1)); if (FileName != null) { v.Add(ByteVector.FromString(FileName, encoding)); } v.Add(ByteVector.TextDelimiter(encoding)); if (Description != null) { v.Add(ByteVector.FromString(Description, encoding)); } v.Add(ByteVector.TextDelimiter(encoding)); v.Add(data); return(v); }
/// <summary> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> protected override ByteVector RenderFields(byte version) { if (file != null) { Load(); } if (raw_data != null && raw_version == version) { return(raw_data); } StringType encoding = CorrectEncoding(TextEncoding, version); ByteVector data = new ByteVector(); if (header.FrameId == FrameType.APIC) { // Make an ID3v2 Attached Picture (APIC) data.Add((byte)encoding); if (version == 2) { string ext = Picture.GetExtensionFromMime(MimeType); data.Add(ext != null && ext.Length == 3 ? ext.ToUpper() : "XXX"); } else { data.Add(ByteVector.FromString(MimeType, StringType.Latin1)); data.Add(ByteVector.TextDelimiter(StringType.Latin1)); } data.Add((byte)type); data.Add(ByteVector.FromString(Description, encoding)); data.Add(ByteVector.TextDelimiter(encoding)); } else if (header.FrameId == FrameType.GEOB) { // Make an ID3v2 General Encapsulated Object (GEOB) data.Add((byte)encoding); if (MimeType != null) { data.Add(ByteVector.FromString(MimeType, StringType.Latin1)); } data.Add(ByteVector.TextDelimiter(StringType.Latin1)); if (filename != null) { data.Add(ByteVector.FromString(filename, encoding)); } data.Add(ByteVector.TextDelimiter(encoding)); if (Description != null) { data.Add(ByteVector.FromString(Description, encoding)); } data.Add(ByteVector.TextDelimiter(encoding)); } else { throw new InvalidOperationException("Bad Frame type"); } data.Add(this.data); return(data); }
/// <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 (file != null) { Load(); } if (raw_data == null) { return; } data = raw_data; raw_data = null; int pos = 0; int offset; encoding = (StringType)data[pos++]; ByteVector delim = ByteVector.TextDelimiter(encoding); if (header.FrameId == FrameType.APIC) { // Retrieve an ID3v2 Attached Picture (APIC) if (raw_version > 2) { offset = data.Find(ByteVector.TextDelimiter(StringType.Latin1), pos); if (offset < pos) { return; } mime_type = data.ToString(StringType.Latin1, pos, offset - pos); pos = offset + 1; } else { ByteVector ext = data.Mid(pos, 3); mime_type = Picture.GetMimeFromExtension(ext.ToString()); pos += 3; } Type = (PictureType)data[pos++]; offset = data.Find(delim, pos, delim.Count); } else if (header.FrameId == FrameType.GEOB) { // Retrieve an ID3v2 General Encapsulated Object (GEOB) offset = data.Find(ByteVector.TextDelimiter(StringType.Latin1), pos); if (offset < pos) { return; } mime_type = data.ToString(StringType.Latin1, pos, offset - pos); pos = offset + 1; offset = data.Find(delim, pos, delim.Count); if (offset < pos) { return; } filename = data.ToString(encoding, pos, offset - pos); pos = offset + delim.Count; offset = data.Find(delim, pos, delim.Count); Type = PictureType.NotAPicture; } else { throw new InvalidOperationException("Bad Frame type"); } if (offset < pos) { return; } description = data.ToString(encoding, pos, offset - pos); pos = offset + delim.Count; data.RemoveRange(0, pos); }
public static ByteVector TextDelimiter(StringType type) { return(ByteVector.TextDelimiter(type)); }
/// <summary> /// Renders the values in the current instance into field /// data for a specified version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// field data is to be encoded in. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered field data. /// </returns> protected override ByteVector RenderFields(byte version) { if (raw_data != null && raw_version == version) { return(raw_data); } StringType encoding = CorrectEncoding(TextEncoding, version); bool wxxx = FrameId == FrameType.WXXX; ByteVector v; if (wxxx) { v = new ByteVector((byte)encoding); } else { v = new ByteVector(); } string[] text = text_fields; if (version > 3 || wxxx) { if (wxxx) { if (text.Length == 0) { text = new string[] { null, null } } ; else if (text.Length == 1) { text = new string[] { text [0], null } } ; } for (int i = 0; i < text.Length; i++) { // Since the field list is null // delimited, if this is not the first // element in the list, append the // appropriate delimiter for this // encoding. if (i != 0) { v.Add(ByteVector.TextDelimiter( encoding)); } if (text[i] != null) { v.Add(ByteVector.FromString( text[i], encoding)); } } } else { v.Add(ByteVector.FromString( string.Join("/", text), StringType.Latin1)); } return(v); }
protected void ParseRawData() { if (raw_data == null) { return; } ByteVector data = raw_data; raw_data = null; encoding = (StringType)data[0]; List <string> field_list = new List <string>(); ByteVector delim = ByteVector.TextDelimiter(encoding); if (raw_version > 3 || FrameId == FrameType.TXXX) { field_list.AddRange(data.ToStrings(encoding, 1)); } else if (data.Count > 1 && !data.Mid(1, delim.Count).Equals(delim)) { string value = data.ToString(encoding, 1, data.Count - 1); int null_index = value.IndexOf('\x00'); if (null_index >= 0) { value = value.Substring(0, null_index); } if (FrameId == FrameType.TCOM || FrameId == FrameType.TEXT || FrameId == FrameType.TOLY || FrameId == FrameType.TOPE || FrameId == FrameType.TPE1 || FrameId == FrameType.TPE2 || FrameId == FrameType.TPE3 || FrameId == FrameType.TPE4) { field_list.AddRange(value.Split('/')); } else if (FrameId == FrameType.TCON) { while (value.Length > 1 && value[0] == '(') { int closing = value.IndexOf(')'); if (closing < 0) { break; } string number = value.Substring(1, closing - 1); field_list.Add(number); value = value.Substring(closing + 1).TrimStart('/', ' '); string text = Genres.IndexToAudio(number); if (text != null && value.StartsWith(text)) { value = value.Substring(text.Length).TrimStart('/', ' '); } } if (value.Length > 0) { field_list.AddRange(value.Split(new char[] { '/' })); } } else { field_list.Add(value); } } 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(); }
protected override ByteVector RenderFields(byte version) { if (raw_data != null && raw_version == version) { return(raw_data); } StringType encoding = CorrectEncoding(TextEncoding, version); ByteVector v = new ByteVector((byte)encoding); string [] text = text_fields; bool txxx = FrameId == FrameType.TXXX; if (version > 3 || txxx) { if (txxx) { if (text.Length == 0) { text = new string [] { null, null } } ; else if (text.Length == 1) { text = new string [] { text [0], null } } ; } for (int i = 0; i < text.Length; i++) { // Since the field list is null // delimited, if this is not the first // element in the list, append the // appropriate delimiter for this // encoding. if (i != 0) { v.Add(ByteVector.TextDelimiter( encoding)); } if (text [i] != null) { v.Add(ByteVector.FromString( text [i], encoding)); } } } else if (FrameId == FrameType.TCON) { byte id; bool prev_value_indexed = true; StringBuilder data = new StringBuilder(); foreach (string s in text) { if (!prev_value_indexed) { data.Append("/").Append(s); continue; } if (prev_value_indexed = byte.TryParse(s, out id)) { data.AppendFormat( CultureInfo.InvariantCulture, "({0})", id); } else { data.Append(s); } } v.Add(ByteVector.FromString(data.ToString(), encoding)); } else { v.Add(ByteVector.FromString( string.Join("/", text), encoding)); } return(v); }
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 (raw_version > 3 || FrameId == FrameType.TXXX) { field_list.AddRange(data.ToStrings(encoding, 1)); } else if (data.Count > 1 && !data.Mid(1, delim.Count).Equals(delim)) { string value = data.ToString(encoding, 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; } } } if (FrameId == FrameType.TCOM || FrameId == FrameType.TEXT || FrameId == FrameType.TOLY || FrameId == FrameType.TOPE || FrameId == FrameType.TPE1 || FrameId == FrameType.TPE2 || FrameId == FrameType.TPE3 || FrameId == FrameType.TPE4) { field_list.AddRange(value.Split('/')); } else if (FrameId == FrameType.TCON) { while (value.Length > 1 && value [0] == '(') { int closing = value.IndexOf(')'); if (closing < 0) { break; } field_list.Add( value.Substring(1, closing - 1)); value = value.Substring( closing + 1); } if (value.Length > 0) { field_list.AddRange(value.Split(new char [] { '/' })); } } else { 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(); }