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
////////////////////////////////////////////////////////////////////////////////
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));
d->track = i;
}
+void ID3v1::Tag::setStringHandler(const StringHandler *handler)
+{
+ delete TagPrivate::stringHandler;
+ TagPrivate::stringHandler = handler;
+}
+
////////////////////////////////////////////////////////////////////////////////
// protected methods
////////////////////////////////////////////////////////////////////////////////
{
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
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
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
/*!
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.