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
This commit is contained in:
Scott Wheeler 2008-01-30 19:50:55 +00:00
parent 7f9526113a
commit 54202bfd5c
8 changed files with 81 additions and 28 deletions

View File

@ -23,10 +23,11 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tdebug.h>
#include "attachedpictureframe.h"
#include <tstringlist.h>
#include <tdebug.h>
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;

View File

@ -26,6 +26,7 @@
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include <tdebug.h>
#include <tstringlist.h>
#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;
}

View File

@ -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;

View File

@ -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()
*/

View File

@ -27,6 +27,7 @@
#include "urllinkframe.h"
#include <tdebug.h>
#include <tstringlist.h>
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;

View File

@ -32,6 +32,7 @@
#endif
#include <tdebug.h>
#include <tstringlist.h>
#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();
}

View File

@ -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;

View File

@ -51,6 +51,12 @@ public:
String::Type defaultEncoding;
bool useDefaultEncoding;
template <class T> 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;
}
}