]> granicus.if.org Git - taglib/commitdiff
Add support for custom ID3v2 text frames (TXXX).
authorScott Wheeler <wheeler@kde.org>
Fri, 6 Aug 2004 23:41:56 +0000 (23:41 +0000)
committerScott Wheeler <wheeler@kde.org>
Fri, 6 Aug 2004 23:41:56 +0000 (23:41 +0000)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@336629 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

mpeg/id3v2/frames/Makefile.am
mpeg/id3v2/frames/textidentificationframe.cpp
mpeg/id3v2/frames/textidentificationframe.h
mpeg/id3v2/id3v2framefactory.cpp

index fe4a48f7a5997f7bd9ad7454d6c23840e4e1518c..5d1966b44be4ec596d3c2c4e686e8797a797a87b 100644 (file)
@@ -1,4 +1,5 @@
 INCLUDES = \
+       -I$(top_srcdir)/taglib \
        -I$(top_srcdir)/taglib/toolkit \
        -I$(top_srcdir)/taglib/mpeg/id3v2 \
        $(all_includes)
index 90e06e5fd6f12b18964a1b75c3af3e3fdbda8d2f..ee213787535c8f5dff7df01a07dd9f428b1ba432 100644 (file)
@@ -20,6 +20,7 @@
  ***************************************************************************/
 
 #include <tbytevectorlist.h>
+#include <id3v2tag.h>
 
 #include "textidentificationframe.h"
 
@@ -35,7 +36,7 @@ public:
 };
 
 ////////////////////////////////////////////////////////////////////////////////
-// public members
+// TextIdentificationFrame public members
 ////////////////////////////////////////////////////////////////////////////////
 
 TextIdentificationFrame::TextIdentificationFrame(const ByteVector &type, String::Type encoding) :
@@ -88,7 +89,7 @@ void TextIdentificationFrame::setTextEncoding(String::Type encoding)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// protected members
+// TextIdentificationFrame protected members
 ////////////////////////////////////////////////////////////////////////////////
 
 void TextIdentificationFrame::parseFields(const ByteVector &data)
@@ -140,7 +141,7 @@ ByteVector TextIdentificationFrame::renderFields() const
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// private members
+// TextIdentificationFrame private members
 ////////////////////////////////////////////////////////////////////////////////
 
 TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data, Header *h) : Frame(h)
@@ -148,3 +149,97 @@ TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data, Header
   d = new TextIdentificationFramePrivate;
   parseFields(fieldData(data));
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// UserTextIdentificationFrame public members
+////////////////////////////////////////////////////////////////////////////////
+
+UserTextIdentificationFrame::UserTextIdentificationFrame(String::Type encoding) :
+  TextIdentificationFrame("TXXX", encoding),
+  d(0)
+{
+  StringList l;
+  l.append(String::null);
+  l.append(String::null);
+  setText(l);
+}
+
+
+UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data) :
+  TextIdentificationFrame(data)
+{
+
+}
+
+String UserTextIdentificationFrame::toString() const
+{
+  return "[" + description() + "] " + fieldList().toString();
+}
+
+String UserTextIdentificationFrame::description() const
+{
+  return !TextIdentificationFrame::fieldList().isEmpty()
+    ? TextIdentificationFrame::fieldList().front()
+    : String::null;
+}
+
+StringList UserTextIdentificationFrame::fieldList() const
+{
+  StringList l = TextIdentificationFrame::fieldList();
+
+  if(!l.isEmpty()) {
+    StringList::Iterator it = l.begin();
+    l.erase(it);
+  }
+
+  return l;
+}
+
+void UserTextIdentificationFrame::setText(const String &text)
+{
+  if(description().isEmpty())
+    setDescription(String::null);
+
+  TextIdentificationFrame::setText(StringList(description()).append(text));
+}
+
+void UserTextIdentificationFrame::setText(const StringList &fields)
+{
+  if(description().isEmpty())
+    setDescription(String::null);
+
+  TextIdentificationFrame::setText(StringList(description()).append(fields));
+}
+
+void UserTextIdentificationFrame::setDescription(const String &s)
+{
+  StringList l = fieldList();
+
+  if(l.isEmpty())
+    l.append(s);
+  else
+    l[0] = s;
+
+  TextIdentificationFrame::setText(l);
+}
+
+UserTextIdentificationFrame *find(ID3v2::Tag *tag, const String &description) // static
+{
+  FrameList l = tag->frameList("TXXX");
+  for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) {
+    UserTextIdentificationFrame *f = dynamic_cast<UserTextIdentificationFrame *>(*it);
+    if(f && f->description() == description)
+      return f;
+  }
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// UserTextIdentificationFrame private members
+////////////////////////////////////////////////////////////////////////////////
+
+UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data, Header *h) :
+  TextIdentificationFrame(data, h)
+{
+  
+}
index 7f6a6fc5c70a31cffca68baf42961e0a61e45271..dc06b7f2a0059777acfc858a87208a17bda019bd 100644 (file)
@@ -30,6 +30,8 @@ namespace TagLib {
 
   namespace ID3v2 {
 
+    class Tag;
+
     //! An ID3v2 text identification frame implementation
 
     /*!
@@ -162,11 +164,12 @@ namespace TagLib {
       virtual void parseFields(const ByteVector &data);
       virtual ByteVector renderFields() const;
 
-    private:
       /*!
        * The constructor used by the FrameFactory.
        */
       TextIdentificationFrame(const ByteVector &data, Header *h);
+
+    private:
       TextIdentificationFrame(const TextIdentificationFrame &);
       TextIdentificationFrame &operator=(const TextIdentificationFrame &);
 
@@ -174,6 +177,63 @@ namespace TagLib {
       TextIdentificationFramePrivate *d;
     };
 
+    /*!
+     * This is a specialization of text identification frames that allows for
+     * user defined entries.  Each entry has a description in addition to the
+     * normal list of fields that a text identification frame has.
+     *
+     * This description identifies the frame and must be unique.
+     */
+
+    class UserTextIdentificationFrame : public TextIdentificationFrame
+    {
+      friend class FrameFactory;
+
+    public:
+      /*!
+       * Constructs an empty user defined text identification frame.  For this to be
+       * a useful frame both a description and text must be set.
+       */
+      explicit UserTextIdentificationFrame(String::Type encoding = String::Latin1);
+
+      /*!
+       * Creates a frame based on \a data.
+       */
+      explicit UserTextIdentificationFrame(const ByteVector &data);
+
+      virtual String toString() const;
+
+      /*!
+       * Returns the description for this frame.
+       */
+      String description() const;
+
+      /*!
+       * Sets the description of the frame to \a s.  \a s must be unique.  You can
+       * check for the presense of another user defined text frame of the same type
+       * using find() and testing for null.
+       */
+      void setDescription(const String &s);
+
+      StringList fieldList() const;
+      void setText(const String &text);
+      void setText(const StringList &fields);
+
+      /*!
+       * Searches for the user defined text frame with the description \a description
+       * in \a tag.  This returns null if no matching frames were found.
+       */
+      static UserTextIdentificationFrame *find(Tag *tag, const String &description);
+
+    private:
+      UserTextIdentificationFrame(const ByteVector &data, Header *h);
+      UserTextIdentificationFrame(const TextIdentificationFrame &);
+      UserTextIdentificationFrame &operator=(const UserTextIdentificationFrame &);
+
+      class UserTextIdentificationFramePrivate;
+      UserTextIdentificationFramePrivate *d;
+    };
+
   }
 }
 #endif
index f98b8855460e2ec98c4ca76d3706595db8ed79d4..320551d7ac4f8866c6b92496e490f595f5d7be8c 100644 (file)
@@ -106,8 +106,11 @@ Frame *FrameFactory::createFrame(const ByteVector &data, uint version) const
 
   // Text Identification (frames 4.2)
 
-  if(frameID.startsWith("T") && frameID != "TXXX") {
-    TextIdentificationFrame *f = new TextIdentificationFrame(data, header);
+  if(frameID.startsWith("T")) {
+    TextIdentificationFrame *f = frameID != "TXXX"
+      ? new TextIdentificationFrame(data, header)
+      : new UserTextIdentificationFrame(data, header);
+
     if(d->useDefaultEncoding)
       f->setTextEncoding(d->defaultEncoding);
     return f;