protected internal Id3v2UniqueFileIdentifierFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //owner = null; //identifier = null; //ParseFields(FieldData(data)); ParseUniqueFields(FieldData(data)); }
protected internal Id3v2PrivateFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //this.owner = null; //this.data = null; //ParseFields(FieldData(data)); ParsePrivateFields(FieldData(data)); }
protected void ParseHeader(ByteVector data) { if (header != null) header.SetData(data); else header = new Id3v2FrameHeader(data); }
protected internal Id3v2TextIdentificationFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //fieldList = new StringCollection(); textEncoding = StringType.UTF8; //ParseFields(FieldData(data)); ParseTextIdentifierFields(FieldData(data)); }
private static void ConvertFrame(string from, string to, Id3v2FrameHeader header) { if (header.FrameId != from) { return; } header.FrameId = to; }
protected internal Id3v2CommentsFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { textEncoding = StringType.UTF8; //language = null; //fields = null; //type = null; //ParseFields(FieldData(data)); ParseCommentsFields(FieldData(data)); }
protected void ParseHeader(ByteVector data) { if (header != null) { header.SetData(data); } else { header = new Id3v2FrameHeader(data); } }
protected internal Id3v2AttachedPictureFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //textEncoding = StringType.UTF8; //mimeType = null; //type = PictureType.None; //fields = null; //this.data = null; ParseAttachedPictureFields(FieldData(data)); //this.resourceFormat = null; }
protected ByteVector FieldData(ByteVector frameData) { if (frameData != null) { uint headerSize = Id3v2FrameHeader.Size(header.Version); uint frameDataOffset = headerSize; uint frameDataLength = Size; if (header.Compression || header.DataLengthIndicator) { frameDataLength = frameData.Mid((int)headerSize, 4).ToUInt(); frameDataLength += 4; } // FIXME: Impliment compression and encrpytion. /* #if HAVE_ZLIB * if(d->header->compression()) { * ByteVector data(frameDataLength); * uLongf uLongTmp = frameDataLength; * ::uncompress((Bytef *) data.data(), * (uLongf *) &uLongTmp, * (Bytef *) frameData.data() + frameDataOffset, * size()); * return data; * } * else #endif */ return(frameData.Mid((int)frameDataOffset, (int)frameDataLength)); } else { throw new ArgumentNullException("frameData"); } }
private static bool UpdateFrame(Id3v2FrameHeader header) { ByteVector frameId = header.FrameId; switch (header.Version) { case 2: // ID3v2.2 { if (frameId == "CRM" || frameId == "EQU" || frameId == "LNK" || frameId == "RVA" || frameId == "TIM" || frameId == "TSI") { TagLibDebugger.Debug("ID3v2.4 no longer supports the frame type " + frameId.ToString() + ". It will be discarded from the tag."); return false; } // ID3v2.2 only used 3 buffer for the frame ID, so we need to convert all of // the frames to their 4 byte ID3v2.4 equivalent. ConvertFrame("BUF", "RBUF", header); ConvertFrame("CNT", "PCNT", header); ConvertFrame("COM", "COMM", header); ConvertFrame("CRA", "AENC", header); ConvertFrame("ETC", "ETCO", header); ConvertFrame("GEO", "GEOB", header); ConvertFrame("IPL", "TIPL", header); ConvertFrame("MCI", "MCDI", header); ConvertFrame("MLL", "MLLT", header); ConvertFrame("PIC", "APIC", header); ConvertFrame("POP", "POPM", header); ConvertFrame("REV", "RVRB", header); ConvertFrame("SLT", "SYLT", header); ConvertFrame("STC", "SYTC", header); ConvertFrame("TAL", "TALB", header); ConvertFrame("TBP", "TBPM", header); ConvertFrame("TCM", "TCOM", header); ConvertFrame("TCO", "TCON", header); ConvertFrame("TCR", "TCOP", header); ConvertFrame("TDA", "TDRC", header); ConvertFrame("TDY", "TDLY", header); ConvertFrame("TEN", "TENC", header); ConvertFrame("TFT", "TFLT", header); ConvertFrame("TKE", "TKEY", header); ConvertFrame("TLA", "TLAN", header); ConvertFrame("TLE", "TLEN", header); ConvertFrame("TMT", "TMED", header); ConvertFrame("TOA", "TOAL", header); ConvertFrame("TOF", "TOFN", header); ConvertFrame("TOL", "TOLY", header); ConvertFrame("TOR", "TDOR", header); ConvertFrame("TOT", "TOAL", header); ConvertFrame("TP1", "TPE1", header); ConvertFrame("TP2", "TPE2", header); ConvertFrame("TP3", "TPE3", header); ConvertFrame("TP4", "TPE4", header); ConvertFrame("TPA", "TPOS", header); ConvertFrame("TPB", "TPUB", header); ConvertFrame("TRC", "TSRC", header); ConvertFrame("TRD", "TDRC", header); ConvertFrame("TRK", "TRCK", header); ConvertFrame("TSS", "TSSE", header); ConvertFrame("TT1", "TIT1", header); ConvertFrame("TT2", "TIT2", header); ConvertFrame("TT3", "TIT3", header); ConvertFrame("TXT", "TOLY", header); ConvertFrame("TXX", "TXXX", header); ConvertFrame("TYE", "TDRC", header); ConvertFrame("UFI", "UFID", header); ConvertFrame("ULT", "USLT", header); ConvertFrame("WAF", "WOAF", header); ConvertFrame("WAR", "WOAR", header); ConvertFrame("WAS", "WOAS", header); ConvertFrame("WCM", "WCOM", header); ConvertFrame("WCP", "WCOP", header); ConvertFrame("WPB", "WPUB", header); ConvertFrame("WXX", "WXXX", header); } break; case 3: // ID3v2.3 { if (frameId == "EQUA" || frameId == "RVAD" || frameId == "TIME" || frameId == "TRDA" || frameId == "TSIZ" || frameId == "TDAT") { TagLibDebugger.Debug("ID3v2.4 no longer supports the frame type " + frameId.ToString() + ". It will be discarded from the tag."); return false; } ConvertFrame("TORY", "TDOR", header); ConvertFrame("TYER", "TDRC", header); } break; default: { // This should catch a typo that existed in TagLib up to and including // version 1.1 where TRDC was used for the year rather than TDRC. ConvertFrame("TRDC", "TDRC", header); } break; } return true; }
public static Id3v2Frame CreateFrame(ByteVector data, uint version) { Id3v2FrameHeader header = new Id3v2FrameHeader(data, version); ByteVector frameId = header.FrameId; // A quick sanity check -- make sure that the frameId is 4 uppercase // Latin1 characters. Also make sure that there is data in the frame. if (frameId == null || frameId.Count != (version < 3 ? 3 : 4) || header.FrameSize < 0) return null; foreach (byte b in frameId) { char c = (char)b; if ((c < 'A' || c > 'Z') && (c < '1' || c > '9')) return null; } // Windows Media Player may create zero byte frames. Just send them // off as unknown. if (header.FrameSize == 0) return new Id3v2UnknownFrame(data, header); // TagLib doesn'type mess with encrypted frames, so just treat them // as unknown frames. if (header.Compression) { TagLibDebugger.Debug("Compressed frames are currently not supported."); return new Id3v2UnknownFrame(data, header); } if (header.Encryption) { TagLibDebugger.Debug("Encrypted frames are currently not supported."); return new Id3v2UnknownFrame(data, header); } if (!UpdateFrame(header)) { header.TagAlterPreservation = true; return new Id3v2UnknownFrame(data, header); } foreach (FrameCreator creator in frameCreators) { Id3v2Frame frame = creator(data, header); if (frame != null) return frame; } // UpdateFrame() might have updated the frame ID. frameId = header.FrameId; // This is where things get necissarily nasty. Here we determine which // Frame subclass (or if none is found simply an Frame) based // on the frame ID. Since there are a lot of possibilities, that means // a lot of if blocks. // Text Identification (frames 4.2) if (frameId.StartsWith("T")) { Id3v2TextIdentificationFrame frame = frameId != "TXXX" ? new Id3v2TextIdentificationFrame(data, header) : new Id3v2UserTextIdentificationFrame(data, header); if (useDefaultEncoding) frame.TextEncoding = defaultEncoding; return frame; } // Comments (frames 4.10) if (frameId == "COMM") { Id3v2CommentsFrame frame = new Id3v2CommentsFrame(data, header); if (useDefaultEncoding) frame.TextEncoding = defaultEncoding; return frame; } // Attached Picture (frames 4.14) if (frameId == "APIC") { Id3v2AttachedPictureFrame f = new Id3v2AttachedPictureFrame(data, header); if (useDefaultEncoding) f.TextEncoding = defaultEncoding; return f; } // Relative Volume Adjustment (frames 4.11) if (frameId == "RVA2") return new Id3v2RelativeVolumeFrame(data, header); // Unique File Identifier (frames 4.1) if (frameId == "UFID") return new Id3v2UniqueFileIdentifierFrame(data, header); // Private (frames 4.27) if (frameId == "PRIV") return new Id3v2PrivateFrame(data, header); return new Id3v2UnknownFrame(data, header); }
private static void ConvertFrame(string from, string to, Id3v2FrameHeader header) { if (header.FrameId != from) return; header.FrameId = to; }
protected internal Id3v2UserTextIdentificationFrame(ByteVector data, Id3v2FrameHeader header) : base(data, header) { }
protected internal Id3v2RelativeVolumeFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //ParseFields(FieldData(data)); ParseRelativeVolumeFields(FieldData(data)); }
protected Id3v2Frame(Id3v2FrameHeader header) { this.header = header; }
protected internal Id3v2UnknownFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //fieldData = null; //ParseFields(FieldData(data)); ParseUnknownFields(FieldData(data)); }
protected void Parse(ByteVector data) { if (data != null) { try { int frameDataPosition = 0; int frameDataLength = data.Count; // check for extended header if (header.ExtendedHeader) { if (ExtendedHeader == null) { extendedHeader = new Id3v2ExtendedHeader(); } ExtendedHeader.SetData(data); if (ExtendedHeader.Size <= data.Count) { frameDataPosition += (int)ExtendedHeader.Size; frameDataLength -= (int)ExtendedHeader.Size; } } // check for footer -- we don'type actually need to parse it, as it *must* // contain the same data as the header, but we do need to account for its // size. if (header.FooterPresent && Id3v2Footer.Size <= frameDataLength) { frameDataLength -= (int)Id3v2Footer.Size; } // parse frames // Make sure that there is at least enough room in the remaining frame data for // a frame header. while (frameDataPosition < frameDataLength - Id3v2FrameHeader.Size(header.MajorVersion)) { // If the next data is position is 0, assume that we've hit the padding // portion of the frame data. if (data[frameDataPosition] == 0) { if (header.FooterPresent) { TagLibDebugger.Debug("Padding *and* a footer found. This is not allowed by the spec."); } return; } Id3v2Frame frame = Id3v2FrameFactory.CreateFrame(data.Mid(frameDataPosition), header.MajorVersion); if (frame == null) { return; } // Checks to make sure that frame parsed correctly. if (frame.Size < 0) { return; } frameDataPosition += (int)(frame.Size + Id3v2FrameHeader.Size(header.MajorVersion)); // Only add frames with content so we don'type send out just we got in. if (frame.Size > 0) { AddFrame(frame); } } } catch (Exception ex) { throw new ApplicationException("There was an error parsing this ID3 tag", ex); } } else { throw new ArgumentNullException("data"); } }
private static bool UpdateFrame(Id3v2FrameHeader header) { ByteVector frameId = header.FrameId; switch (header.Version) { case 2: // ID3v2.2 { if (frameId == "CRM" || frameId == "EQU" || frameId == "LNK" || frameId == "RVA" || frameId == "TIM" || frameId == "TSI") { TagLibDebugger.Debug("ID3v2.4 no longer supports the frame type " + frameId.ToString() + ". It will be discarded from the tag."); return(false); } // ID3v2.2 only used 3 buffer for the frame ID, so we need to convert all of // the frames to their 4 byte ID3v2.4 equivalent. ConvertFrame("BUF", "RBUF", header); ConvertFrame("CNT", "PCNT", header); ConvertFrame("COM", "COMM", header); ConvertFrame("CRA", "AENC", header); ConvertFrame("ETC", "ETCO", header); ConvertFrame("GEO", "GEOB", header); ConvertFrame("IPL", "TIPL", header); ConvertFrame("MCI", "MCDI", header); ConvertFrame("MLL", "MLLT", header); ConvertFrame("PIC", "APIC", header); ConvertFrame("POP", "POPM", header); ConvertFrame("REV", "RVRB", header); ConvertFrame("SLT", "SYLT", header); ConvertFrame("STC", "SYTC", header); ConvertFrame("TAL", "TALB", header); ConvertFrame("TBP", "TBPM", header); ConvertFrame("TCM", "TCOM", header); ConvertFrame("TCO", "TCON", header); ConvertFrame("TCR", "TCOP", header); ConvertFrame("TDA", "TDRC", header); ConvertFrame("TDY", "TDLY", header); ConvertFrame("TEN", "TENC", header); ConvertFrame("TFT", "TFLT", header); ConvertFrame("TKE", "TKEY", header); ConvertFrame("TLA", "TLAN", header); ConvertFrame("TLE", "TLEN", header); ConvertFrame("TMT", "TMED", header); ConvertFrame("TOA", "TOAL", header); ConvertFrame("TOF", "TOFN", header); ConvertFrame("TOL", "TOLY", header); ConvertFrame("TOR", "TDOR", header); ConvertFrame("TOT", "TOAL", header); ConvertFrame("TP1", "TPE1", header); ConvertFrame("TP2", "TPE2", header); ConvertFrame("TP3", "TPE3", header); ConvertFrame("TP4", "TPE4", header); ConvertFrame("TPA", "TPOS", header); ConvertFrame("TPB", "TPUB", header); ConvertFrame("TRC", "TSRC", header); ConvertFrame("TRD", "TDRC", header); ConvertFrame("TRK", "TRCK", header); ConvertFrame("TSS", "TSSE", header); ConvertFrame("TT1", "TIT1", header); ConvertFrame("TT2", "TIT2", header); ConvertFrame("TT3", "TIT3", header); ConvertFrame("TXT", "TOLY", header); ConvertFrame("TXX", "TXXX", header); ConvertFrame("TYE", "TDRC", header); ConvertFrame("UFI", "UFID", header); ConvertFrame("ULT", "USLT", header); ConvertFrame("WAF", "WOAF", header); ConvertFrame("WAR", "WOAR", header); ConvertFrame("WAS", "WOAS", header); ConvertFrame("WCM", "WCOM", header); ConvertFrame("WCP", "WCOP", header); ConvertFrame("WPB", "WPUB", header); ConvertFrame("WXX", "WXXX", header); } break; case 3: // ID3v2.3 { if (frameId == "EQUA" || frameId == "RVAD" || frameId == "TIME" || frameId == "TRDA" || frameId == "TSIZ" || frameId == "TDAT") { TagLibDebugger.Debug("ID3v2.4 no longer supports the frame type " + frameId.ToString() + ". It will be discarded from the tag."); return(false); } ConvertFrame("TORY", "TDOR", header); ConvertFrame("TYER", "TDRC", header); } break; default: { // This should catch a typo that existed in TagLib up to and including // version 1.1 where TRDC was used for the year rather than TDRC. ConvertFrame("TRDC", "TDRC", header); } break; } return(true); }
public static Id3v2Frame CreateFrame(ByteVector data, uint version) { Id3v2FrameHeader header = new Id3v2FrameHeader(data, version); ByteVector frameId = header.FrameId; // A quick sanity check -- make sure that the frameId is 4 uppercase // Latin1 characters. Also make sure that there is data in the frame. if (frameId == null || frameId.Count != (version < 3 ? 3 : 4) || header.FrameSize < 0) { return(null); } foreach (byte b in frameId) { char c = (char)b; if ((c < 'A' || c > 'Z') && (c < '1' || c > '9')) { return(null); } } // Windows Media Player may create zero byte frames. Just send them // off as unknown. if (header.FrameSize == 0) { return(new Id3v2UnknownFrame(data, header)); } // TagLib doesn'type mess with encrypted frames, so just treat them // as unknown frames. if (header.Compression) { TagLibDebugger.Debug("Compressed frames are currently not supported."); return(new Id3v2UnknownFrame(data, header)); } if (header.Encryption) { TagLibDebugger.Debug("Encrypted frames are currently not supported."); return(new Id3v2UnknownFrame(data, header)); } if (!UpdateFrame(header)) { header.TagAlterPreservation = true; return(new Id3v2UnknownFrame(data, header)); } foreach (FrameCreator creator in frameCreators) { Id3v2Frame frame = creator(data, header); if (frame != null) { return(frame); } } // UpdateFrame() might have updated the frame ID. frameId = header.FrameId; // This is where things get necissarily nasty. Here we determine which // Frame subclass (or if none is found simply an Frame) based // on the frame ID. Since there are a lot of possibilities, that means // a lot of if blocks. // Text Identification (frames 4.2) if (frameId.StartsWith("T")) { Id3v2TextIdentificationFrame frame = frameId != "TXXX" ? new Id3v2TextIdentificationFrame(data, header) : new Id3v2UserTextIdentificationFrame(data, header); if (useDefaultEncoding) { frame.TextEncoding = defaultEncoding; } return(frame); } // Comments (frames 4.10) if (frameId == "COMM") { Id3v2CommentsFrame frame = new Id3v2CommentsFrame(data, header); if (useDefaultEncoding) { frame.TextEncoding = defaultEncoding; } return(frame); } // Attached Picture (frames 4.14) if (frameId == "APIC") { Id3v2AttachedPictureFrame f = new Id3v2AttachedPictureFrame(data, header); if (useDefaultEncoding) { f.TextEncoding = defaultEncoding; } return(f); } // Relative Volume Adjustment (frames 4.11) if (frameId == "RVA2") { return(new Id3v2RelativeVolumeFrame(data, header)); } // Unique File Identifier (frames 4.1) if (frameId == "UFID") { return(new Id3v2UniqueFileIdentifierFrame(data, header)); } // Private (frames 4.27) if (frameId == "PRIV") { return(new Id3v2PrivateFrame(data, header)); } return(new Id3v2UnknownFrame(data, header)); }