Sylloge
A C# helper library
code/Audio/Metadata/ID3/Frames/Comment.cs
Go to the documentation of this file.
00001 using System;
00002 using System.Collections.Generic;
00003 using System.Linq;
00004 using System.Text;
00005 
00006 namespace Sylloge.Audio.Metadata.ID3.Frames
00007 {
00008     public class Comment : TextFrame
00009     {
00010         public Sylloge.Data.ISO639_2 Language { get; private set; }
00011 
00012         public Comment()
00013             : base(ID3.Frame.Keys.Comment)
00014         {
00015             this.Initialize(0x00, new Data.ISO639_2(Sylloge.Data.ISO639_2.Code.ENG), string.Empty, string.Empty);
00016         }
00017 
00018         public Comment(string text)
00019             : base(ID3.Frame.Keys.Comment)
00020         {
00021             this.Initialize(0x00, new Data.ISO639_2(Sylloge.Data.ISO639_2.Code.ENG), string.Empty, text);
00022         }
00023 
00024         internal Comment(byte encoding, Sylloge.Data.ISO639_2 language, string shortDesc, string text)
00025             : base(ID3.Frame.Keys.Comment)
00026         {
00027             this.Initialize(encoding, language, shortDesc, text);
00028         }
00029 
00030         private Comment(byte encoding, byte[] language, string shortDesc, string text)
00031             : base(ID3.Frame.Keys.Comment)
00032         {
00033             this.Initialize(encoding, Sylloge.Data.ISO639_2.Parse(language), shortDesc, text);
00034         }
00035 
00036         public Comment(Frame other)
00037             : base(other)
00038         {
00039             if (other.ID != ID3.Frame.Keys.Comment) { throw new System.InvalidCastException("Frame ID must be equal to copy the data within it."); }
00040             Comment c = Comment.Parse(other);
00041             this.Description = c.Description;
00042             this.Encoding = c.Encoding;
00043             this.Language = c.Language;
00044             this.Value = c.Value;
00045         }
00046 
00047         public Comment(TextFrame other)
00048             : base(other)
00049         {
00050             if (other.ID != ID3.Frame.Keys.Comment) { throw new System.InvalidCastException("Frame ID must be equal to copy the data within it."); }
00051             this.Language = new Data.ISO639_2(Sylloge.Data.ISO639_2.Code.ENG);
00052         }
00053 
00054         public Comment(Comment other)
00055             : base(other)
00056         {
00057             this.Language = other.Language;
00058         }
00059 
00060         public override byte[] GenerateTag()
00061         {
00062             /* <Header for 'Comment', ID: "COMM"> 
00063             Text encoding           $xx (1 byte)
00064             Language                $xx xx xx (3 bytes)
00065             Short content descrip.  <text string according to encoding> (upto 0x00, plus 1 byte)
00066             The actual text         <full text string according to encoding>
00067             */
00068             byte[] pre_data = new byte[3];
00069             if (this.Language != null) { System.Buffer.BlockCopy(this.Language.Bytes, 0, pre_data, 0, 3); }
00070             return base.GenerateTagData(pre_data);
00071         }
00072 
00073         public void SetLanguage(Sylloge.Data.ISO639_2 lang)
00074         {
00075             if (lang == null) { throw new System.ArgumentNullException("lang"); }
00076             this.Language = lang;
00077             this.GenerateTag();
00078         }
00079 
00080         private void Initialize(byte encoding, Sylloge.Data.ISO639_2 language, string shortDesc, string text)
00081         {
00082             this.Language = language;
00083             this.Initialize(encoding, shortDesc, text);
00084             this.GenerateTag();
00085         }
00086 
00092         public static ID3.Frames.Comment Parse(Frame frame)
00093         {
00094             if (frame.ID != ID3.Frame.Keys.Comment) { throw new System.InvalidCastException("Frame ID must be equal to copy the data within it."); }
00095             Comment ret = new Comment(); // (Comment)frame;
00096             ret.Data = frame.Data;
00097             ret.Format = frame.Format;
00098             ret.Status = frame.Status;
00099             /* <Header for 'Comment', ID: "COMM"> 
00100             Text encoding           $xx (1 byte)
00101             Language                $xx xx xx (3 bytes)
00102             Short content descrip.  <text string according to encoding> (upto 0x00, plus 1 byte)
00103             The actual text         <full text string according to encoding> (the rest of the data)
00104             */
00105             List<byte> bdata = new List<byte>(ret.Data);
00106             ret.Encoding = bdata[0];
00107             ret.Language = Sylloge.Data.ISO639_2.Parse((new byte[] { bdata[1], bdata[2], bdata[3] }));
00108             System.Text.Encoding enc = ID3.Helper.GetEncoding(ret.Encoding);
00109             bdata.RemoveRange(0, 4);
00110             if (bdata[0] != Frame.EOL) {
00111                 ret.Description = enc.GetString(bdata.ToArray());
00112                 int idx = 0;
00113                 for (idx = 0; idx < ret.Description.Length; idx++) {
00114                     if (ret.Description[idx] == '\0') { break; }
00115                 }
00116                 ret.Description = ret.Description.Substring(0, idx);
00117                 int len = enc.GetByteCount(ret.Description);
00118                 if ((len + 1) > bdata.Count) {
00119                     bdata.Clear();
00120                 } else {
00121                     bdata.RemoveRange(0, len + 1);
00122                 }
00123                 if (enc.GetByteCount("A") > 1) {
00124                     // for multi-byte encodings
00125                     bdata.RemoveAt(0);
00126                 }
00127             } else {
00128                 bdata.RemoveAt(0);
00129             }
00130             if (bdata.Count > 0 && bdata[0] != Frame.EOL) {
00131                 ret.Value = enc.GetString(bdata.ToArray());
00132                 int idx = 0;
00133                 for (; idx < ret.Value.Length; idx++) {
00134                     if (ret.Value[idx] == '\0') { break; }
00135                 }
00136                 ret.Value = ret.Value.Substring(0, idx);
00137             }
00138             return ret;
00139         }
00140 
00146         public static ID3.Frames.Comment Parse(byte[] data)
00147         {
00148             /* <Header for 'Comment', ID: "COMM"> 
00149             Text encoding           $xx (1 byte)
00150             Language                $xx xx xx (3 bytes)
00151             Short content descrip.  <text string according to encoding> (upto 0x00, plus 1 byte)
00152             The actual text         <full text string according to encoding> (the rest of the data)
00153             */
00154             List<byte> bdata = new List<byte>(data);
00155             byte[] lang = new byte[3];
00156             string sdesc = string.Empty;
00157             string text = string.Empty;
00158             byte benc = bdata[0];
00159             bdata.RemoveAt(0);
00160             System.Text.Encoding enc = ID3.Helper.GetEncoding(benc);
00161             System.Buffer.BlockCopy(bdata.ToArray(), 0, lang, 0, 3);
00162             bdata.RemoveRange(0, 3);
00163             if (bdata[0] != Frame.EOL) {
00164                 sdesc = enc.GetString(bdata.ToArray());
00165                 int idx = 0;
00166                 for (idx = 0; idx < sdesc.Length; idx++) {
00167                     if (sdesc[idx] == '\0') { break; }
00168                 }
00169                 sdesc = sdesc.Substring(0, idx);
00170                 int len = enc.GetByteCount(sdesc);
00171                 if ((len + 1) > bdata.Count) {
00172                     bdata.Clear();
00173                 } else {
00174                     bdata.RemoveRange(0, len + 1);
00175                 }
00176                 if (enc.GetByteCount("A") > 1) {
00177                     // for multi-byte encodings
00178                     bdata.RemoveAt(0);
00179                 }
00180             } else {
00181                 bdata.RemoveAt(0);
00182             }
00183             if (bdata[0] != Frame.EOL) {
00184                 text = enc.GetString(bdata.ToArray());
00185                 int idx = 0;
00186                 for (; idx < text.Length; idx++) {
00187                     if (text[idx] == '\0') { break; }
00188                 }
00189                 text = text.Substring(0, idx);
00190             }
00191             return (new ID3.Frames.Comment(benc, lang, sdesc, text));
00192         }
00193     }
00194 }
 All Classes Namespaces Files Functions Variables Enumerations Properties Events