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.