mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Support for POPM ID3 frame
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@811137 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
parent
51ca869f65
commit
f6994ec26c
@ -63,6 +63,7 @@ SET(frames_SRCS
|
||||
mpeg/id3v2/frames/attachedpictureframe.cpp
|
||||
mpeg/id3v2/frames/commentsframe.cpp
|
||||
mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp
|
||||
mpeg/id3v2/frames/popularimeterframe.cpp
|
||||
mpeg/id3v2/frames/relativevolumeframe.cpp
|
||||
mpeg/id3v2/frames/textidentificationframe.cpp
|
||||
mpeg/id3v2/frames/uniquefileidentifierframe.cpp
|
||||
|
@ -2,6 +2,7 @@ INSTALL(FILES
|
||||
attachedpictureframe.h
|
||||
commentsframe.h
|
||||
generalencapsulatedobjectframe.h
|
||||
popularimeterframe.h
|
||||
relativevolumeframe.h
|
||||
textidentificationframe.h
|
||||
uniquefileidentifierframe.h
|
||||
|
@ -10,6 +10,7 @@ libframes_la_SOURCES = \
|
||||
attachedpictureframe.cpp \
|
||||
commentsframe.cpp \
|
||||
generalencapsulatedobjectframe.cpp \
|
||||
popularimeterframe.cpp \
|
||||
relativevolumeframe.cpp \
|
||||
textidentificationframe.cpp \
|
||||
uniquefileidentifierframe.cpp \
|
||||
@ -21,6 +22,7 @@ taglib_include_HEADERS = \
|
||||
attachedpictureframe.h \
|
||||
commentsframe.h \
|
||||
generalencapsulatedobjectframe.h \
|
||||
popularimeterframe.h \
|
||||
relativevolumeframe.h \
|
||||
textidentificationframe.h \
|
||||
uniquefileidentifierframe.h \
|
||||
|
137
taglib/mpeg/id3v2/frames/popularimeterframe.cpp
Normal file
137
taglib/mpeg/id3v2/frames/popularimeterframe.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2008 by Lukas Lalinsky
|
||||
email : lalinsky@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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 <tdebug.h>
|
||||
|
||||
#include "popularimeterframe.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
||||
class PopularimeterFrame::PopularimeterFramePrivate
|
||||
{
|
||||
public:
|
||||
PopularimeterFramePrivate() : rating(0), counter(0) {}
|
||||
String email;
|
||||
int rating;
|
||||
TagLib::uint counter;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PopularimeterFrame::PopularimeterFrame() : Frame("POPM")
|
||||
{
|
||||
d = new PopularimeterFramePrivate;
|
||||
}
|
||||
|
||||
PopularimeterFrame::PopularimeterFrame(const ByteVector &data) : Frame(data)
|
||||
{
|
||||
d = new PopularimeterFramePrivate;
|
||||
setData(data);
|
||||
}
|
||||
|
||||
PopularimeterFrame::~PopularimeterFrame()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
String PopularimeterFrame::toString() const
|
||||
{
|
||||
return d->email + " rating=" + String::number(d->rating) + " counter=" + String::number(d->counter);
|
||||
}
|
||||
|
||||
String PopularimeterFrame::email() const
|
||||
{
|
||||
return d->email;
|
||||
}
|
||||
|
||||
void PopularimeterFrame::setEmail(const String &s)
|
||||
{
|
||||
d->email = s;
|
||||
}
|
||||
|
||||
int PopularimeterFrame::rating() const
|
||||
{
|
||||
return d->rating;
|
||||
}
|
||||
|
||||
void PopularimeterFrame::setRating(int s)
|
||||
{
|
||||
d->rating = s;
|
||||
}
|
||||
|
||||
TagLib::uint PopularimeterFrame::counter() const
|
||||
{
|
||||
return d->counter;
|
||||
}
|
||||
|
||||
void PopularimeterFrame::setCounter(TagLib::uint s)
|
||||
{
|
||||
d->counter = s;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PopularimeterFrame::parseFields(const ByteVector &data)
|
||||
{
|
||||
int pos = 0, size = int(data.size());
|
||||
|
||||
d->email = readStringField(data, String::Latin1, &pos);
|
||||
|
||||
d->rating = 0;
|
||||
d->counter = 0;
|
||||
if(pos < size) {
|
||||
d->rating = data[pos++];
|
||||
if(pos < size) {
|
||||
d->counter = data.mid(pos, 4).toUInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ByteVector PopularimeterFrame::renderFields() const
|
||||
{
|
||||
ByteVector data;
|
||||
|
||||
data.append(d->email.data(String::Latin1));
|
||||
data.append(textDelimiter(String::Latin1));
|
||||
data.append(char(d->rating));
|
||||
data.append(ByteVector::fromUInt(d->counter));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PopularimeterFrame::PopularimeterFrame(const ByteVector &data, Header *h) : Frame(h)
|
||||
{
|
||||
d = new PopularimeterFramePrivate;
|
||||
parseFields(fieldData(data));
|
||||
}
|
132
taglib/mpeg/id3v2/frames/popularimeterframe.h
Normal file
132
taglib/mpeg/id3v2/frames/popularimeterframe.h
Normal file
@ -0,0 +1,132 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2008 by Lukas Lalinsky
|
||||
email : lalinsky@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_POPULARIMETERFRAME_H
|
||||
#define TAGLIB_POPULARIMETERFRAME_H
|
||||
|
||||
#include <id3v2frame.h>
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace ID3v2 {
|
||||
|
||||
//! An implementation of ID3v2 "popularimeter"
|
||||
|
||||
/*!
|
||||
* This implements the ID3v2 popularimeter (POPM frame). It concists of
|
||||
* an email, a rating and an optional counter.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT PopularimeterFrame : public Frame
|
||||
{
|
||||
friend class FrameFactory;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Construct an empty popularimeter frame.
|
||||
*/
|
||||
explicit PopularimeterFrame();
|
||||
|
||||
/*!
|
||||
* Construct a popularimeter based on the data in \a data.
|
||||
*/
|
||||
explicit PopularimeterFrame(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Destroys this PopularimeterFrame instance.
|
||||
*/
|
||||
virtual ~PopularimeterFrame();
|
||||
|
||||
/*!
|
||||
* Returns the text of this popularimeter.
|
||||
*
|
||||
* \see text()
|
||||
*/
|
||||
virtual String toString() const;
|
||||
|
||||
/*!
|
||||
* Returns the email.
|
||||
*
|
||||
* \see setEmail()
|
||||
*/
|
||||
String email() const;
|
||||
|
||||
/*!
|
||||
* Set the email.
|
||||
*
|
||||
* \see email()
|
||||
*/
|
||||
void setEmail(const String &email);
|
||||
|
||||
/*!
|
||||
* Returns the rating.
|
||||
*
|
||||
* \see setRating()
|
||||
*/
|
||||
int rating() const;
|
||||
|
||||
/*!
|
||||
* Set the rating.
|
||||
*
|
||||
* \see rating()
|
||||
*/
|
||||
void setRating(int rating);
|
||||
|
||||
/*!
|
||||
* Returns the counter.
|
||||
*
|
||||
* \see setCounter()
|
||||
*/
|
||||
uint counter() const;
|
||||
|
||||
/*!
|
||||
* Set the counter.
|
||||
*
|
||||
* \see counter()
|
||||
*/
|
||||
void setCounter(uint counter);
|
||||
|
||||
protected:
|
||||
// Reimplementations.
|
||||
|
||||
virtual void parseFields(const ByteVector &data);
|
||||
virtual ByteVector renderFields() const;
|
||||
|
||||
private:
|
||||
/*!
|
||||
* The constructor used by the FrameFactory.
|
||||
*/
|
||||
PopularimeterFrame(const ByteVector &data, Header *h);
|
||||
PopularimeterFrame(const PopularimeterFrame &);
|
||||
PopularimeterFrame &operator=(const PopularimeterFrame &);
|
||||
|
||||
class PopularimeterFramePrivate;
|
||||
PopularimeterFramePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -41,6 +41,7 @@
|
||||
#include "frames/generalencapsulatedobjectframe.h"
|
||||
#include "frames/urllinkframe.h"
|
||||
#include "frames/unsynchronizedlyricsframe.h"
|
||||
#include "frames/popularimeterframe.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -220,6 +221,12 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader)
|
||||
return f;
|
||||
}
|
||||
|
||||
// Popularimeter (frames 4.17)
|
||||
|
||||
if(frameID == "POPM") {
|
||||
return new PopularimeterFrame(data, header);
|
||||
}
|
||||
|
||||
return new UnknownFrame(data, header);
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ HEADERS += audioproperties.h \
|
||||
mpeg/id3v2/frames/attachedpictureframe.h \
|
||||
mpeg/id3v2/frames/commentsframe.h \
|
||||
mpeg/id3v2/frames/generalencapsulatedobjectframe.h \
|
||||
mpeg/id3v2/frames/popularimeterframe.h \
|
||||
mpeg/id3v2/frames/relativevolumeframe.h \
|
||||
mpeg/id3v2/frames/textidentificationframe.h \
|
||||
mpeg/id3v2/frames/uniquefileidentifierframe.h \
|
||||
@ -148,6 +149,7 @@ SOURCES += audioproperties.cpp \
|
||||
mpeg/id3v2/frames/attachedpictureframe.cpp \
|
||||
mpeg/id3v2/frames/commentsframe.cpp \
|
||||
mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp \
|
||||
mpeg/id3v2/frames/popularimeterframe.cpp \
|
||||
mpeg/id3v2/frames/relativevolumeframe.cpp \
|
||||
mpeg/id3v2/frames/textidentificationframe.cpp \
|
||||
mpeg/id3v2/frames/uniquefileidentifierframe.cpp \
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <attachedpictureframe.h>
|
||||
#include <generalencapsulatedobjectframe.h>
|
||||
#include <relativevolumeframe.h>
|
||||
#include <popularimeterframe.h>
|
||||
#include <urllinkframe.h>
|
||||
#include "utils.h"
|
||||
|
||||
@ -37,6 +38,11 @@ class TestID3v2 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testParseAPIC);
|
||||
CPPUNIT_TEST(testParseAPIC_UTF16_BOM);
|
||||
CPPUNIT_TEST(testParseGEOB);
|
||||
CPPUNIT_TEST(testPOPMtoString);
|
||||
CPPUNIT_TEST(testParsePOPM);
|
||||
CPPUNIT_TEST(testParsePOPMWithoutCounter);
|
||||
CPPUNIT_TEST(testRenderPOPM);
|
||||
CPPUNIT_TEST(testPOPMFromFile);
|
||||
CPPUNIT_TEST(testParseRelativeVolumeFrame);
|
||||
CPPUNIT_TEST(testParseUniqueFileIdentifierFrame);
|
||||
CPPUNIT_TEST(testParseEmptyUniqueFileIdentifierFrame);
|
||||
@ -138,6 +144,75 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(String("d"), f.description());
|
||||
}
|
||||
|
||||
void testParsePOPM()
|
||||
{
|
||||
ID3v2::PopularimeterFrame f(ByteVector("POPM"
|
||||
"\x00\x00\x00\x17"
|
||||
"\x00\x00"
|
||||
"email@example.com\x00"
|
||||
"\x02"
|
||||
"\x00\x00\x00\x03", 33));
|
||||
CPPUNIT_ASSERT_EQUAL(String("email@example.com"), f.email());
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.rating());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), f.counter());
|
||||
}
|
||||
|
||||
void testParsePOPMWithoutCounter()
|
||||
{
|
||||
ID3v2::PopularimeterFrame f(ByteVector("POPM"
|
||||
"\x00\x00\x00\x13"
|
||||
"\x00\x00"
|
||||
"email@example.com\x00"
|
||||
"\x02", 29));
|
||||
CPPUNIT_ASSERT_EQUAL(String("email@example.com"), f.email());
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.rating());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f.counter());
|
||||
}
|
||||
|
||||
void testRenderPOPM()
|
||||
{
|
||||
ID3v2::PopularimeterFrame f;
|
||||
f.setEmail("email@example.com");
|
||||
f.setRating(2);
|
||||
f.setCounter(3);
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("POPM"
|
||||
"\x00\x00\x00\x17"
|
||||
"\x00\x00"
|
||||
"email@example.com\x00"
|
||||
"\x02"
|
||||
"\x00\x00\x00\x03", 33),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testPOPMtoString()
|
||||
{
|
||||
ID3v2::PopularimeterFrame f;
|
||||
f.setEmail("email@example.com");
|
||||
f.setRating(2);
|
||||
f.setCounter(3);
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
String("email@example.com rating=2 counter=3"), f.toString());
|
||||
}
|
||||
|
||||
void testPOPMFromFile()
|
||||
{
|
||||
string newname = copyFile("xing", ".mp3");
|
||||
|
||||
ID3v2::PopularimeterFrame *f = new ID3v2::PopularimeterFrame();
|
||||
f->setEmail("email@example.com");
|
||||
f->setRating(2);
|
||||
f->setCounter(3);
|
||||
|
||||
MPEG::File foo(newname.c_str());
|
||||
foo.ID3v2Tag()->addFrame(f);
|
||||
foo.save();
|
||||
|
||||
MPEG::File bar(newname.c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(String("email@example.com"), dynamic_cast<ID3v2::PopularimeterFrame *>(bar.ID3v2Tag()->frameList("POPM").front())->email());
|
||||
deleteFile(newname);
|
||||
}
|
||||
|
||||
// http://bugs.kde.org/show_bug.cgi?id=150481
|
||||
void testParseRelativeVolumeFrame()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user