Support for URL link framesSupport for URL link frames, patch by Urs Fleisch.

BUG:151079
CCMAIL:ufleisch@users.sourceforge.net


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@740080 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
Lukáš Lalinský 2007-11-22 13:48:01 +00:00
parent bb9e6fe65f
commit e06495a7e3
7 changed files with 437 additions and 37 deletions

View File

@ -67,6 +67,7 @@ mpeg/id3v2/frames/relativevolumeframe.cpp
mpeg/id3v2/frames/textidentificationframe.cpp
mpeg/id3v2/frames/uniquefileidentifierframe.cpp
mpeg/id3v2/frames/unknownframe.cpp
mpeg/id3v2/frames/urllinkframe.cpp
)
SET(ogg_SRCS

View File

@ -1,35 +1,10 @@
INSTALL( FILES attachedpictureframe.h commentsframe.h generalencapsulatedobjectframe.h relativevolumeframe.h textidentificationframe.h uniquefileidentifierframe.h unknownframe.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)
#original Makefile.am contents follow:
#INCLUDES = \
# -I$(top_srcdir)/taglib \
# -I$(top_srcdir)/taglib/toolkit \
# -I$(top_srcdir)/taglib/mpeg/id3v2 \
# $(all_includes)
#
#noinst_LTLIBRARIES = libframes.la
#
#libframes_la_SOURCES = \
# attachedpictureframe.cpp \
# commentsframe.cpp \
# generalencapsulatedobjectframe.cpp \
# relativevolumeframe.cpp \
# textidentificationframe.cpp \
# uniquefileidentifierframe.cpp \
# unknownframe.cpp
#
#taglib_include_HEADERS = \
# attachedpictureframe.h \
# commentsframe.h \
# generalencapsulatedobjectframe.h \
# relativevolumeframe.h \
# textidentificationframe.h \
# uniquefileidentifierframe.h \
# unknownframe.h
#
#taglib_includedir = $(includedir)/taglib
#
#EXTRA_DIST = $(libframes_la_SOURCES) $(taglib_include_HEADERS)
INSTALL(FILES
attachedpictureframe.h
commentsframe.h
generalencapsulatedobjectframe.h
relativevolumeframe.h
textidentificationframe.h
uniquefileidentifierframe.h
unknownframe.h
urllinkframe.h
DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)

View File

@ -13,7 +13,8 @@ libframes_la_SOURCES = \
relativevolumeframe.cpp \
textidentificationframe.cpp \
uniquefileidentifierframe.cpp \
unknownframe.cpp
unknownframe.cpp \
urllinkframe.cpp
taglib_include_HEADERS = \
attachedpictureframe.h \
@ -22,6 +23,7 @@ taglib_include_HEADERS = \
relativevolumeframe.h \
textidentificationframe.h \
uniquefileidentifierframe.h \
unknownframe.h
unknownframe.h \
urllinkframe.h
taglib_includedir = $(includedir)/taglib

View File

@ -0,0 +1,186 @@
/***************************************************************************
copyright : (C) 2002, 2003 by Scott Wheeler
email : wheeler@kde.org
copyright : (C) 2006 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include "urllinkframe.h"
#include <tdebug.h>
using namespace TagLib;
using namespace ID3v2;
class UrlLinkFrame::UrlLinkFramePrivate {
public:
String url;
};
class UserUrlLinkFrame::UserUrlLinkFramePrivate {
public:
UserUrlLinkFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
String description;
};
UrlLinkFrame::UrlLinkFrame(const ByteVector &data) :
Frame(data)
{
d = new UrlLinkFramePrivate;
setData(data);
}
UrlLinkFrame::~UrlLinkFrame()
{
delete d;
}
void UrlLinkFrame::setUrl(const String &s)
{
d->url = s;
}
String UrlLinkFrame::url() const
{
return d->url;
}
void UrlLinkFrame::setText(const String &s)
{
setUrl(s);
}
String UrlLinkFrame::toString() const
{
return url();
}
void UrlLinkFrame::parseFields(const ByteVector &data)
{
d->url = String(data);
}
ByteVector UrlLinkFrame::renderFields() const
{
return d->url.data(String::Latin1);
}
UrlLinkFrame::UrlLinkFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new UrlLinkFramePrivate;
parseFields(fieldData(data));
}
UserUrlLinkFrame::UserUrlLinkFrame(String::Type encoding) :
UrlLinkFrame("WXXX")
{
d = new UserUrlLinkFramePrivate;
d->textEncoding = encoding;
}
UserUrlLinkFrame::UserUrlLinkFrame(const ByteVector &data) :
UrlLinkFrame(data)
{
d = new UserUrlLinkFramePrivate;
setData(data);
}
UserUrlLinkFrame::~UserUrlLinkFrame()
{
delete d;
}
String UserUrlLinkFrame::toString() const
{
return "[" + description() + "] " + url();
}
String::Type UserUrlLinkFrame::textEncoding() const
{
return d->textEncoding;
}
void UserUrlLinkFrame::setTextEncoding(String::Type encoding)
{
d->textEncoding = encoding;
}
String UserUrlLinkFrame::description() const
{
return d->description;
}
void UserUrlLinkFrame::setDescription(const String &s)
{
d->description = s;
}
void UserUrlLinkFrame::parseFields(const ByteVector &data)
{
if (data.size() < 2) {
debug("A user URL link frame must contain at least 2 bytes.");
return;
}
int pos = 0;
d->textEncoding = String::Type(data[0]);
pos += 1;
if (d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8) {
int offset = data.find(textDelimiter(d->textEncoding), pos);
if (offset < pos)
return;
d->description = String(data.mid(pos, offset - pos), d->textEncoding);
pos = offset + 1;
} else {
int len = data.mid(pos).find(textDelimiter(d->textEncoding), 0, 2);
if (len < 0)
return;
d->description = String(data.mid(pos, len), d->textEncoding);
pos += len + 2;
}
setUrl(String(data.mid(pos)));
}
ByteVector UserUrlLinkFrame::renderFields() const
{
ByteVector v;
v.append(char(d->textEncoding));
v.append(d->description.data(d->textEncoding));
v.append(textDelimiter(d->textEncoding));
v.append(url().data(String::Latin1));
return v;
}
UserUrlLinkFrame::UserUrlLinkFrame(const ByteVector &data, Header *h) : UrlLinkFrame(data, h)
{
d = new UserUrlLinkFramePrivate;
parseFields(fieldData(data));
}

View File

@ -0,0 +1,167 @@
/***************************************************************************
copyright : (C) 2002, 2003 by Scott Wheeler
email : wheeler@kde.org
copyright : (C) 2006 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_URLLINKFRAME_H
#define TAGLIB_URLLINKFRAME_H
#include <id3v2frame.h>
namespace TagLib {
namespace ID3v2 {
/*!
* An implementation of ID3v2 URL link frames.
*/
class UrlLinkFrame : public Frame {
friend class FrameFactory;
public:
/*!
* This is a dual purpose constructor. \a data can either be binary data
* that should be parsed or (at a minimum) the frame ID.
*/
explicit UrlLinkFrame(const ByteVector &data);
/*!
* Destroys this UrlLinkFrame instance.
*/
virtual ~UrlLinkFrame();
/*!
* Returns the URL.
*/
virtual String url() const;
/*!
* Sets the URL to \a s.
*/
virtual void setUrl(const String &s);
// Reimplementations.
virtual void setText(const String &s);
virtual String toString() const;
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
/*!
* The constructor used by the FrameFactory.
*/
UrlLinkFrame(const ByteVector &data, Header *h);
private:
UrlLinkFrame(const UrlLinkFrame &);
UrlLinkFrame &operator=(const UrlLinkFrame &);
class UrlLinkFramePrivate;
UrlLinkFramePrivate *d;
};
/*!
* This is a specialization of URL link frames that allows for
* user defined entries. Each entry has a description in addition to the
* normal list of fields that a URL link frame has.
*
* This description identifies the frame and must be unique.
*/
class UserUrlLinkFrame : public UrlLinkFrame {
friend class FrameFactory;
public:
/*!
* Constructs an empty user defined URL link frame. For this to be
* a useful frame both a description and text must be set.
*/
explicit UserUrlLinkFrame(String::Type encoding = String::Latin1);
/*!
* This is a dual purpose constructor. \a data can either be binary data
* that should be parsed or (at a minimum) the frame ID.
*/
explicit UserUrlLinkFrame(const ByteVector &data);
/*!
* Destroys this UserUrlLinkFrame instance.
*/
virtual ~UserUrlLinkFrame();
// Reimplementations.
virtual String toString() const;
/*!
* Returns the text encoding that will be used in rendering this frame.
* This defaults to the type that was either specified in the constructor
* or read from the frame when parsed.
*
* \see setTextEncoding()
* \see render()
*/
String::Type textEncoding() const;
/*!
* Sets the text encoding to be used when rendering this frame to
* \a encoding.
*
* \see textEncoding()
* \see render()
*/
void setTextEncoding(String::Type encoding);
/*!
* Returns the description for this frame.
*/
String description() const;
/*!
* Sets the description of the frame to \a s. \a s must be unique.
*/
void setDescription(const String &s);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
/*!
* The constructor used by the FrameFactory.
*/
UserUrlLinkFrame(const ByteVector &data, Header *h);
private:
UserUrlLinkFrame(const UserUrlLinkFrame &);
UserUrlLinkFrame &operator=(const UserUrlLinkFrame &);
class UserUrlLinkFramePrivate;
UserUrlLinkFramePrivate *d;
};
}
}
#endif

View File

@ -37,6 +37,7 @@
#include "frames/uniquefileidentifierframe.h"
#include "frames/unknownframe.h"
#include "frames/generalencapsulatedobjectframe.h"
#include "frames/urllinkframe.h"
using namespace TagLib;
using namespace ID3v2;
@ -187,6 +188,19 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader)
if(frameID == "GEOB")
return new GeneralEncapsulatedObjectFrame(data, header);
// URL link (frames 4.3)
if(frameID.startsWith("W")) {
if(frameID != "WXXX") {
return new UrlLinkFrame(data, header);
} else {
UserUrlLinkFrame *f = new UserUrlLinkFrame(data, header);
if(d->useDefaultEncoding)
f->setTextEncoding(d->defaultEncoding);
return f;
}
}
return new UnknownFrame(data, header);
}

View File

@ -9,6 +9,7 @@
#include <attachedpictureframe.h>
#include <generalencapsulatedobjectframe.h>
#include <relativevolumeframe.h>
#include <urllinkframe.h>
using namespace std;
using namespace TagLib;
@ -39,6 +40,10 @@ class TestID3v2 : public CppUnit::TestFixture
CPPUNIT_TEST(testParseEmptyUniqueFileIdentifierFrame);
CPPUNIT_TEST(testBrokenFrame1);
//CPPUNIT_TEST(testItunes24FrameSize);
CPPUNIT_TEST(testParseUrlLinkFrame);
CPPUNIT_TEST(testRenderUrlLinkFrame);
CPPUNIT_TEST(testParseUserUrlLinkFrame);
CPPUNIT_TEST(testRenderUserUrlLinkFrame);
CPPUNIT_TEST_SUITE_END();
public:
@ -166,6 +171,56 @@ public:
f.identifier());
}
void testParseUrlLinkFrame()
{
ID3v2::UrlLinkFrame f(
ByteVector("WOAF" // Frame ID
"\x00\x00\x00\x12" // Frame size
"\x00\x00" // Frame flags
"http://example.com", 28)); // URL
CPPUNIT_ASSERT_EQUAL(String("http://example.com"), f.url());
}
void testRenderUrlLinkFrame()
{
ID3v2::UrlLinkFrame f("WOAF");
f.setUrl("http://example.com");
CPPUNIT_ASSERT_EQUAL(
ByteVector("WOAF" // Frame ID
"\x00\x00\x00\x12" // Frame size
"\x00\x00" // Frame flags
"http://example.com", 28), // URL
f.render());
}
void testParseUserUrlLinkFrame()
{
ID3v2::UserUrlLinkFrame f(
ByteVector("WXXX" // Frame ID
"\x00\x00\x00\x17" // Frame size
"\x00\x00" // Frame flags
"\x00" // Text encoding
"foo\x00" // Description
"http://example.com", 33)); // URL
CPPUNIT_ASSERT_EQUAL(String("foo"), f.description());
CPPUNIT_ASSERT_EQUAL(String("http://example.com"), f.url());
}
void testRenderUserUrlLinkFrame()
{
ID3v2::UserUrlLinkFrame f;
f.setDescription("foo");
f.setUrl("http://example.com");
CPPUNIT_ASSERT_EQUAL(
ByteVector("WXXX" // Frame ID
"\x00\x00\x00\x17" // Frame size
"\x00\x00" // Frame flags
"\x00" // Text encoding
"foo\x00" // Description
"http://example.com", 33), // URL
f.render());
}
/*void testItunes24FrameSize()
{
MPEG::File f("data/005411.id3", false);