ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
if(l.size() == 2) {
- d->description = String(l.front(), d->textEncoding);
- d->text = String(l.back(), d->textEncoding);
+ if(d->textEncoding == String::Latin1) {
+ d->description = Tag::latin1StringHandler()->parse(l.front());
+ d->text = Tag::latin1StringHandler()->parse(l.back());
+ } else {
+ d->description = String(l.front(), d->textEncoding);
+ d->text = String(l.back(), d->textEncoding);
+ }
}
}
for(ByteVectorList::Iterator it = l.begin(); it != l.end(); it++) {
if(!(*it).isEmpty()) {
- String s(*it, d->textEncoding);
- d->fieldList.append(s);
+ if(d->textEncoding == String::Latin1)
+ d->fieldList.append(Tag::latin1StringHandler()->parse(*it));
+ else
+ d->fieldList.append(String(*it, d->textEncoding));
}
}
}
ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
if(l.size() == 2) {
- d->description = String(l.front(), d->textEncoding);
- d->text = String(l.back(), d->textEncoding);
+ if(d->textEncoding == String::Latin1) {
+ d->description = Tag::latin1StringHandler()->parse(l.front());
+ d->text = Tag::latin1StringHandler()->parse(l.back());
+ } else {
+ d->description = String(l.front(), d->textEncoding);
+ d->text = String(l.back(), d->textEncoding);
+ }
}
}
#include <tdebug.h>
#include <tstringlist.h>
+#include "id3v2tag.h"
#include "id3v2frame.h"
#include "id3v2synchdata.h"
#include "tpropertymap.h"
if(end < *position)
return String::null;
- String str = String(data.mid(*position, end - *position), encoding);
+ String str;
+ if(encoding == String::Latin1)
+ str = Tag::latin1StringHandler()->parse(data.mid(*position, end - *position));
+ else
+ str = String(data.mid(*position, end - *position), encoding);
*position = end + delimiter.size();
FrameListMap frameListMap;
FrameList frameList;
+
+ static const Latin1StringHandler *stringHandler;
};
+static const Latin1StringHandler defaultStringHandler;
+const ID3v2::Latin1StringHandler *ID3v2::Tag::TagPrivate::stringHandler = &defaultStringHandler;
+
+////////////////////////////////////////////////////////////////////////////////
+// StringHandler implementation
+////////////////////////////////////////////////////////////////////////////////
+
+Latin1StringHandler::~Latin1StringHandler()
+{
+}
+
+String Latin1StringHandler::parse(const ByteVector &data) const
+{
+ return String(data, String::Latin1);
+}
+
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
return d->header.render() + tagData;
}
+Latin1StringHandler const *ID3v2::Tag::latin1StringHandler()
+{
+ return TagPrivate::stringHandler;
+}
+
+void ID3v2::Tag::setLatin1StringHandler(const Latin1StringHandler *handler)
+{
+ if(handler)
+ TagPrivate::stringHandler = handler;
+ else
+ TagPrivate::stringHandler = &defaultStringHandler;
+}
+
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
typedef List<Frame *> FrameList;
typedef Map<ByteVector, FrameList> FrameListMap;
+ //! An abstraction for the ISO-8859-1 string to data encoding in ID3v2 tags.
+
+ /*!
+ * ID3v2 tag can store strings in ISO-8859-1 (Latin1), and TagLib only
+ * supports genuine ISO-8859-1 by default. However, in practice, non
+ * ISO-8859-1 encodings are often used instead of ISO-8859-1, such as
+ * Windows-1252 for western languages, Shift_JIS for Japanese and so on.
+ *
+ * Here is an option to read such tags by subclassing this class,
+ * reimplementing parse() and setting your reimplementation as the default
+ * with ID3v2::Tag::setStringHandler().
+ *
+ * \note Writing non-ISO-8859-1 tags is not implemented intentionally.
+ * Use UTF-16 or UTF-8 instead.
+ *
+ * \see ID3v2::Tag::setStringHandler()
+ */
+ class TAGLIB_EXPORT Latin1StringHandler
+ {
+ public:
+ virtual ~Latin1StringHandler();
+
+ /*!
+ * 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;
+ };
+
//! The main class in the ID3v2 implementation
/*!
*/
// BIC: combine with the above method
ByteVector render(int version) const;
+
+ /*!
+ * Gets the current string handler that decides how the "Latin-1" data
+ * will be converted to and from binary data.
+ *
+ * \see Latin1StringHandler
+ */
+ static Latin1StringHandler const *latin1StringHandler();
+
+ /*!
+ * Sets the string handler that decides how the "Latin-1" data will be
+ * converted to and from binary data.
+ *
+ * If the parameter \a handler is null, default ISO-8859-1 handler
+ * is restored.
+ *
+ * \see Latin1StringHandler
+ */
+ static void setLatin1StringHandler(const Latin1StringHandler *handler);
protected:
/*!