Add the ability to override the default ID3v1 string handling in TagLib by
authorScott Wheeler <wheeler@kde.org>
Sun, 4 Apr 2004 14:42:13 +0000 (14:42 +0000)
committerScott Wheeler <wheeler@kde.org>
Sun, 4 Apr 2004 14:42:13 +0000 (14:42 +0000)
adding a ID3v1::StringHandler class that has render and parse methods.

By default this still makes the (correct) assumption that ID3v1 tags contain
ISO-8859-1 data, but this makes it easy for applications to override this to
allow user specified codecs.

CCMAIL:78428@bugs.kde.org
CCMAIL:77710@bugs.kde.org
CCMAIL:amarok-devel@lists.sourceforge.net
CCMAIL:Shlomi Loubaton <loubaton.shlomi@012.net.il>
CCMAIL:Nir Misgav <misgav@ee.bgu.ac.il>

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@301244 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

mpeg/id3v1/id3v1tag.cpp
mpeg/id3v1/id3v1tag.h

index 482b2defd7445f699d8627a944530c75bdf73baf..b8800e97edce3045f71c25b78b10b1af7dfdb8c1 100644 (file)
@@ -43,8 +43,26 @@ public:
   String comment;
   uchar track;
   uchar genre;
+
+  static const StringHandler *stringHandler;
 };
 
+const ID3v1::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = new StringHandler;
+
+////////////////////////////////////////////////////////////////////////////////
+// StringHandler implementation
+////////////////////////////////////////////////////////////////////////////////
+
+String ID3v1::StringHandler::parse(const ByteVector &data) const
+{
+  return String(data, String::Latin1);
+}
+
+ByteVector ID3v1::StringHandler::render(const String &s) const
+{
+  return s.data(String::Latin1);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // public methods
 ////////////////////////////////////////////////////////////////////////////////
@@ -73,11 +91,11 @@ ByteVector ID3v1::Tag::render() const
   ByteVector data;
 
   data.append(fileIdentifier());
-  data.append(d->title.data(String::Latin1).resize(30));
-  data.append(d->artist.data(String::Latin1).resize(30));
-  data.append(d->album.data(String::Latin1).resize(30));
-  data.append(d->year.data(String::Latin1).resize(4));
-  data.append(d->comment.data(String::Latin1).resize(28));
+  data.append(TagPrivate::stringHandler->render(d->title).resize(30));
+  data.append(TagPrivate::stringHandler->render(d->artist).resize(30));
+  data.append(TagPrivate::stringHandler->render(d->album).resize(30));
+  data.append(TagPrivate::stringHandler->render(d->year).resize(4));
+  data.append(TagPrivate::stringHandler->render(d->comment).resize(28));
   data.append(char(0));
   data.append(char(d->track));
   data.append(char(d->genre));
@@ -160,6 +178,12 @@ void ID3v1::Tag::setTrack(uint i)
   d->track = i;
 }
 
+void ID3v1::Tag::setStringHandler(const StringHandler *handler)
+{
+  delete TagPrivate::stringHandler;
+  TagPrivate::stringHandler = handler;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // protected methods
 ////////////////////////////////////////////////////////////////////////////////
@@ -183,16 +207,16 @@ void ID3v1::Tag::parse(const ByteVector &data)
 {
   int offset = 3;
 
-  d->title = data.mid(offset, 30);
+  d->title = TagPrivate::stringHandler->parse(data.mid(offset, 30));
   offset += 30;
 
-  d->artist = data.mid(offset, 30);
+  d->artist = TagPrivate::stringHandler->parse(data.mid(offset, 30));
   offset += 30;
 
-  d->album = data.mid(offset, 30);
+  d->album = TagPrivate::stringHandler->parse(data.mid(offset, 30));
   offset += 30;
 
-  d->year = data.mid(offset, 4);
+  d->year = TagPrivate::stringHandler->parse(data.mid(offset, 4));
   offset += 4;
 
   // Check for ID3v1.1 -- Note that ID3v1 *does not* support "track zero" -- this
@@ -203,7 +227,7 @@ void ID3v1::Tag::parse(const ByteVector &data)
   if(data[offset + 28] == 0 && data[offset + 29] != 0) {
     // ID3v1.1 detected
 
-    d->comment = data.mid(offset, 28);
+    d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 28));
     d->track = uchar(data[offset + 29]);
   }
   else
index b202b036deec9ae2a5185dcb0de9c34722227a84..99c06c1d096d47ddadd2eca5e5c5d959f345ea94 100644 (file)
@@ -33,6 +33,45 @@ namespace TagLib {
 
   namespace ID3v1 {
 
+    //! A abstraction for the string to data encoding in ID3v1 tags.
+
+    /*!
+     * ID3v1 should in theory always contain ISO-8859-1 (Latin1) data.  In
+     * practice it does not.  TagLib by default only supports ISO-8859-1 data
+     * in ID3v1 tags.
+     *
+     * However by subclassing this class and reimplementing parse() and render()
+     * and setting your reimplementation as the default with
+     * ID3v1::Tag::setStringHandler() you can define how you would like these
+     * transformations to be done.
+     *
+     * \warning It is advisable <b>not</b> to write non-ISO-8859-1 data to ID3v1
+     * tags.  Please consider disabling the writing of ID3v1 tags in the case
+     * that the data is ISO-8859-1.
+     *
+     * \see ID3v1::Tag::setStringHandler()
+     */
+
+    class StringHandler
+    {
+    public:
+      /*!
+       * Decode a string from \a data.  The default implementation assumes that
+       * \a data is an ISO-8859-1 (Latin1) character array.
+       */
+      virtual String parse(const ByteVector &data) const;
+
+      /*!
+       * Encode a ByteVector with the data from \a s.  The default implementation
+       * assumes that \a s is an ISO-8859-1 (Latin1) string.
+       *
+       * \warning It is recommended that you <b>not</b> override this method, but
+       * instead do not write an ID3v1 tag in the case that the data is not
+       * ISO-8859-1.
+       */
+      virtual ByteVector render(const String &s) const;
+    };
+
     //! The main class in the ID3v1 implementation
 
     /*!
@@ -95,6 +134,14 @@ namespace TagLib {
       virtual void setYear(uint i);
       virtual void setTrack(uint i);
 
+      /*!
+       * Sets the string handler that decides how the ID3v1 data will be
+       * converted to and from binary data.
+       *
+       * \see StringHandler
+       */
+      static void setStringHandler(const StringHandler *handler);
+
     protected:
       /*!
        * Reads from the file specified in the constructor.