From 54202bfd5c053a2e6d7316ea726639d26ec4eccd Mon Sep 17 00:00:00 2001 From: Scott Wheeler Date: Wed, 30 Jan 2008 19:50:55 +0000 Subject: [PATCH] This causes TagLib to check to make sure that text values to-be-written as ISO-8859-1 are in fact ISO-8859-1 values (assuming they were passed into TagLib properly) and if not automatically switches those frames to UTF8. FEATURE:90635 CCBUG:90635 git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@768857 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- .../id3v2/frames/attachedpictureframe.cpp | 13 ++++++---- taglib/mpeg/id3v2/frames/commentsframe.cpp | 15 +++++++---- .../id3v2/frames/textidentificationframe.cpp | 8 +++--- .../id3v2/frames/textidentificationframe.h | 10 +++++++ taglib/mpeg/id3v2/frames/urllinkframe.cpp | 9 ++++--- taglib/mpeg/id3v2/id3v2frame.cpp | 17 +++++++++++- taglib/mpeg/id3v2/id3v2frame.h | 11 +++++++- taglib/mpeg/id3v2/id3v2framefactory.cpp | 26 ++++++++++++------- 8 files changed, 81 insertions(+), 28 deletions(-) diff --git a/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp b/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp index 6d5a716b..4fe6c825 100644 --- a/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp +++ b/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp @@ -23,10 +23,11 @@ * http://www.mozilla.org/MPL/ * ***************************************************************************/ -#include - #include "attachedpictureframe.h" +#include +#include + using namespace TagLib; using namespace ID3v2; @@ -145,12 +146,14 @@ ByteVector AttachedPictureFrame::renderFields() const { ByteVector data; - data.append(char(d->textEncoding)); + String::Type encoding = checkEncoding(d->description, d->textEncoding); + + data.append(char(encoding)); data.append(d->mimeType.data(String::Latin1)); data.append(textDelimiter(String::Latin1)); data.append(char(d->type)); - data.append(d->description.data(d->textEncoding)); - data.append(textDelimiter(d->textEncoding)); + data.append(d->description.data(encoding)); + data.append(textDelimiter(encoding)); data.append(d->data); return data; diff --git a/taglib/mpeg/id3v2/frames/commentsframe.cpp b/taglib/mpeg/id3v2/frames/commentsframe.cpp index fc91d5e6..a7db2425 100644 --- a/taglib/mpeg/id3v2/frames/commentsframe.cpp +++ b/taglib/mpeg/id3v2/frames/commentsframe.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "commentsframe.h" @@ -98,7 +99,6 @@ void CommentsFrame::setText(const String &s) d->text = s; } - String::Type CommentsFrame::textEncoding() const { return d->textEncoding; @@ -153,11 +153,16 @@ ByteVector CommentsFrame::renderFields() const { ByteVector v; - v.append(char(d->textEncoding)); + String::Type encoding = d->textEncoding; + + encoding = checkEncoding(d->description, encoding); + encoding = checkEncoding(d->text, encoding); + + v.append(char(encoding)); v.append(d->language.size() == 3 ? d->language : "XXX"); - v.append(d->description.data(d->textEncoding)); - v.append(textDelimiter(d->textEncoding)); - v.append(d->text.data(d->textEncoding)); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); + v.append(d->text.data(encoding)); return v; } diff --git a/taglib/mpeg/id3v2/frames/textidentificationframe.cpp b/taglib/mpeg/id3v2/frames/textidentificationframe.cpp index f461c20b..7c8a7d71 100644 --- a/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +++ b/taglib/mpeg/id3v2/frames/textidentificationframe.cpp @@ -139,9 +139,11 @@ void TextIdentificationFrame::parseFields(const ByteVector &data) ByteVector TextIdentificationFrame::renderFields() const { + String::Type encoding = checkEncoding(d->fieldList, d->textEncoding); + ByteVector v; - v.append(char(d->textEncoding)); + v.append(char(encoding)); for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { @@ -150,9 +152,9 @@ ByteVector TextIdentificationFrame::renderFields() const // encoding. if(it != d->fieldList.begin()) - v.append(textDelimiter(d->textEncoding)); + v.append(textDelimiter(encoding)); - v.append((*it).data(d->textEncoding)); + v.append((*it).data(encoding)); } return v; diff --git a/taglib/mpeg/id3v2/frames/textidentificationframe.h b/taglib/mpeg/id3v2/frames/textidentificationframe.h index 7905d9af..0929af56 100644 --- a/taglib/mpeg/id3v2/frames/textidentificationframe.h +++ b/taglib/mpeg/id3v2/frames/textidentificationframe.h @@ -95,6 +95,10 @@ namespace TagLib { * The ID3v2 Frames document gives a description of each of these formats * and the expected order of strings in each. ID3v2::Header::frameID() can * be used to determine the frame type. + * + * \note If non-Latin1 compatible strings are used with this class, even if + * the text encoding is set to Latin1, the frame will be written using UTF8 + * (with the encoding flag appropriately set in the output). */ class TAGLIB_EXPORT TextIdentificationFrame : public Frame @@ -108,6 +112,8 @@ namespace TagLib { * * \note In this case you must specify the text encoding as it * resolves the ambiguity between constructors. + * + * \note Please see the note in the class description regarding Latin1. */ TextIdentificationFrame(const ByteVector &type, String::Type encoding); @@ -144,6 +150,8 @@ namespace TagLib { * This defaults to the type that was either specified in the constructor * or read from the frame when parsed. * + * \note Please see the note in the class description regarding Latin1. + * * \see setTextEncoding() * \see render() */ @@ -153,6 +161,8 @@ namespace TagLib { * Sets the text encoding to be used when rendering this frame to * \a encoding. * + * \note Please see the note in the class description regarding Latin1. + * * \see textEncoding() * \see render() */ diff --git a/taglib/mpeg/id3v2/frames/urllinkframe.cpp b/taglib/mpeg/id3v2/frames/urllinkframe.cpp index a58e3c87..c06a2d6b 100644 --- a/taglib/mpeg/id3v2/frames/urllinkframe.cpp +++ b/taglib/mpeg/id3v2/frames/urllinkframe.cpp @@ -27,6 +27,7 @@ #include "urllinkframe.h" #include +#include using namespace TagLib; using namespace ID3v2; @@ -174,9 +175,11 @@ ByteVector UserUrlLinkFrame::renderFields() const { ByteVector v; - v.append(char(d->textEncoding)); - v.append(d->description.data(d->textEncoding)); - v.append(textDelimiter(d->textEncoding)); + String::Type encoding = checkEncoding(d->description, d->textEncoding); + + v.append(char(encoding)); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); v.append(url().data(String::Latin1)); return v; diff --git a/taglib/mpeg/id3v2/id3v2frame.cpp b/taglib/mpeg/id3v2/id3v2frame.cpp index 49e57b96..0a849262 100644 --- a/taglib/mpeg/id3v2/id3v2frame.cpp +++ b/taglib/mpeg/id3v2/id3v2frame.cpp @@ -32,6 +32,7 @@ #endif #include +#include #include "id3v2frame.h" #include "id3v2synchdata.h" @@ -222,6 +223,20 @@ String Frame::readStringField(const ByteVector &data, String::Type encoding, int return str; } +String::Type Frame::checkEncoding(const StringList &fields, String::Type encoding) // static +{ + if(encoding != String::Latin1) + return encoding; + + for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) { + if(!(*it).isLatin1()) { + debug("Frame::checkEncoding() -- Rendering using UTF8."); + return String::UTF8; + } + } + + return String::Latin1; +} //////////////////////////////////////////////////////////////////////////////// // Frame::Header class @@ -523,7 +538,7 @@ ByteVector Frame::Header::render() const return v; } -bool Frame::Header::frameAlterPreservation() const // deprecated +bool Frame::Header::frameAlterPreservation() const { return fileAlterPreservation(); } diff --git a/taglib/mpeg/id3v2/id3v2frame.h b/taglib/mpeg/id3v2/id3v2frame.h index 3886c3dd..1307b758 100644 --- a/taglib/mpeg/id3v2/id3v2frame.h +++ b/taglib/mpeg/id3v2/id3v2frame.h @@ -32,6 +32,8 @@ namespace TagLib { + class StringList; + namespace ID3v2 { class Tag; @@ -193,6 +195,13 @@ namespace TagLib { String readStringField(const ByteVector &data, String::Type encoding, int *positon = 0); + /*! + * Checks a the list of string values to see if they can be used with the + * specified encoding and returns the recommended encoding. + */ + static String::Type checkEncoding(const StringList &fields, + String::Type encoding); + private: Frame(const Frame &); Frame &operator=(const Frame &); @@ -387,7 +396,7 @@ namespace TagLib { ByteVector render() const; /*! - * @deprecated + * \deprecated */ bool frameAlterPreservation() const; diff --git a/taglib/mpeg/id3v2/id3v2framefactory.cpp b/taglib/mpeg/id3v2/id3v2framefactory.cpp index 8bbfde96..1e03cd77 100644 --- a/taglib/mpeg/id3v2/id3v2framefactory.cpp +++ b/taglib/mpeg/id3v2/id3v2framefactory.cpp @@ -51,6 +51,12 @@ public: String::Type defaultEncoding; bool useDefaultEncoding; + + template void setTextEncoding(T *frame) + { + if(useDefaultEncoding) + frame->setTextEncoding(defaultEncoding); + } }; FrameFactory *FrameFactory::factory = 0; @@ -142,12 +148,12 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader) // Text Identification (frames 4.2) if(frameID.startsWith("T")) { + TextIdentificationFrame *f = frameID != "TXXX" ? new TextIdentificationFrame(data, header) : new UserTextIdentificationFrame(data, header); - if(d->useDefaultEncoding) - f->setTextEncoding(d->defaultEncoding); + d->setTextEncoding(f); if(frameID == "TCON") updateGenre(f); @@ -159,8 +165,7 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader) if(frameID == "COMM") { CommentsFrame *f = new CommentsFrame(data, header); - if(d->useDefaultEncoding) - f->setTextEncoding(d->defaultEncoding); + d->setTextEncoding(f); return f; } @@ -168,8 +173,7 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader) if(frameID == "APIC") { AttachedPictureFrame *f = new AttachedPictureFrame(data, header); - if(d->useDefaultEncoding) - f->setTextEncoding(d->defaultEncoding); + d->setTextEncoding(f); return f; } @@ -185,8 +189,11 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader) // General Encapsulated Object (frames 4.15) - if(frameID == "GEOB") - return new GeneralEncapsulatedObjectFrame(data, header); + if(frameID == "GEOB") { + GeneralEncapsulatedObjectFrame *f = new GeneralEncapsulatedObjectFrame(data, header); + d->setTextEncoding(f); + return f; + } // URL link (frames 4.3) @@ -196,8 +203,7 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader) } else { UserUrlLinkFrame *f = new UserUrlLinkFrame(data, header); - if(d->useDefaultEncoding) - f->setTextEncoding(d->defaultEncoding); + d->setTextEncoding(f); return f; } }