diff --git a/mpeg/id3v1/id3v1tag.cpp b/mpeg/id3v1/id3v1tag.cpp
index 482b2def..b8800e97 100644
--- a/mpeg/id3v1/id3v1tag.cpp
+++ b/mpeg/id3v1/id3v1tag.cpp
@@ -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
diff --git a/mpeg/id3v1/id3v1tag.h b/mpeg/id3v1/id3v1tag.h
index b202b036..99c06c1d 100644
--- a/mpeg/id3v1/id3v1tag.h
+++ b/mpeg/id3v1/id3v1tag.h
@@ -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 not 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 not 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.