Add support for custom ID3v2 text frames (TXXX).

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@336629 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
Scott Wheeler 2004-08-06 23:41:56 +00:00
parent 43a570f5b2
commit c3c54b570a
4 changed files with 165 additions and 6 deletions

View File

@ -1,4 +1,5 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
$(all_includes)

View File

@ -20,6 +20,7 @@
***************************************************************************/
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include "textidentificationframe.h"
@ -35,7 +36,7 @@ public:
};
////////////////////////////////////////////////////////////////////////////////
// public members
// TextIdentificationFrame public members
////////////////////////////////////////////////////////////////////////////////
TextIdentificationFrame::TextIdentificationFrame(const ByteVector &type, String::Type encoding) :
@ -88,7 +89,7 @@ void TextIdentificationFrame::setTextEncoding(String::Type encoding)
}
////////////////////////////////////////////////////////////////////////////////
// protected members
// TextIdentificationFrame protected members
////////////////////////////////////////////////////////////////////////////////
void TextIdentificationFrame::parseFields(const ByteVector &data)
@ -140,7 +141,7 @@ ByteVector TextIdentificationFrame::renderFields() const
}
////////////////////////////////////////////////////////////////////////////////
// private members
// TextIdentificationFrame private members
////////////////////////////////////////////////////////////////////////////////
TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data, Header *h) : Frame(h)
@ -148,3 +149,97 @@ TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data, Header
d = new TextIdentificationFramePrivate;
parseFields(fieldData(data));
}
////////////////////////////////////////////////////////////////////////////////
// UserTextIdentificationFrame public members
////////////////////////////////////////////////////////////////////////////////
UserTextIdentificationFrame::UserTextIdentificationFrame(String::Type encoding) :
TextIdentificationFrame("TXXX", encoding),
d(0)
{
StringList l;
l.append(String::null);
l.append(String::null);
setText(l);
}
UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data) :
TextIdentificationFrame(data)
{
}
String UserTextIdentificationFrame::toString() const
{
return "[" + description() + "] " + fieldList().toString();
}
String UserTextIdentificationFrame::description() const
{
return !TextIdentificationFrame::fieldList().isEmpty()
? TextIdentificationFrame::fieldList().front()
: String::null;
}
StringList UserTextIdentificationFrame::fieldList() const
{
StringList l = TextIdentificationFrame::fieldList();
if(!l.isEmpty()) {
StringList::Iterator it = l.begin();
l.erase(it);
}
return l;
}
void UserTextIdentificationFrame::setText(const String &text)
{
if(description().isEmpty())
setDescription(String::null);
TextIdentificationFrame::setText(StringList(description()).append(text));
}
void UserTextIdentificationFrame::setText(const StringList &fields)
{
if(description().isEmpty())
setDescription(String::null);
TextIdentificationFrame::setText(StringList(description()).append(fields));
}
void UserTextIdentificationFrame::setDescription(const String &s)
{
StringList l = fieldList();
if(l.isEmpty())
l.append(s);
else
l[0] = s;
TextIdentificationFrame::setText(l);
}
UserTextIdentificationFrame *find(ID3v2::Tag *tag, const String &description) // static
{
FrameList l = tag->frameList("TXXX");
for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) {
UserTextIdentificationFrame *f = dynamic_cast<UserTextIdentificationFrame *>(*it);
if(f && f->description() == description)
return f;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// UserTextIdentificationFrame private members
////////////////////////////////////////////////////////////////////////////////
UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data, Header *h) :
TextIdentificationFrame(data, h)
{
}

View File

@ -30,6 +30,8 @@ namespace TagLib {
namespace ID3v2 {
class Tag;
//! An ID3v2 text identification frame implementation
/*!
@ -162,11 +164,12 @@ namespace TagLib {
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
private:
/*!
* The constructor used by the FrameFactory.
*/
TextIdentificationFrame(const ByteVector &data, Header *h);
private:
TextIdentificationFrame(const TextIdentificationFrame &);
TextIdentificationFrame &operator=(const TextIdentificationFrame &);
@ -174,6 +177,63 @@ namespace TagLib {
TextIdentificationFramePrivate *d;
};
/*!
* This is a specialization of text identification frames that allows for
* user defined entries. Each entry has a description in addition to the
* normal list of fields that a text identification frame has.
*
* This description identifies the frame and must be unique.
*/
class UserTextIdentificationFrame : public TextIdentificationFrame
{
friend class FrameFactory;
public:
/*!
* Constructs an empty user defined text identification frame. For this to be
* a useful frame both a description and text must be set.
*/
explicit UserTextIdentificationFrame(String::Type encoding = String::Latin1);
/*!
* Creates a frame based on \a data.
*/
explicit UserTextIdentificationFrame(const ByteVector &data);
virtual String toString() const;
/*!
* Returns the description for this frame.
*/
String description() const;
/*!
* Sets the description of the frame to \a s. \a s must be unique. You can
* check for the presense of another user defined text frame of the same type
* using find() and testing for null.
*/
void setDescription(const String &s);
StringList fieldList() const;
void setText(const String &text);
void setText(const StringList &fields);
/*!
* Searches for the user defined text frame with the description \a description
* in \a tag. This returns null if no matching frames were found.
*/
static UserTextIdentificationFrame *find(Tag *tag, const String &description);
private:
UserTextIdentificationFrame(const ByteVector &data, Header *h);
UserTextIdentificationFrame(const TextIdentificationFrame &);
UserTextIdentificationFrame &operator=(const UserTextIdentificationFrame &);
class UserTextIdentificationFramePrivate;
UserTextIdentificationFramePrivate *d;
};
}
}
#endif

View File

@ -106,8 +106,11 @@ Frame *FrameFactory::createFrame(const ByteVector &data, uint version) const
// Text Identification (frames 4.2)
if(frameID.startsWith("T") && frameID != "TXXX") {
TextIdentificationFrame *f = new TextIdentificationFrame(data, header);
if(frameID.startsWith("T")) {
TextIdentificationFrame *f = frameID != "TXXX"
? new TextIdentificationFrame(data, header)
: new UserTextIdentificationFrame(data, header);
if(d->useDefaultEncoding)
f->setTextEncoding(d->defaultEncoding);
return f;