Merge branch 'master' into taglib2

Conflicts:
	tests/test_aiff.cpp
	tests/test_flac.cpp
This commit is contained in:
Scott Wheeler
2014-09-25 16:39:26 +02:00
11 changed files with 80 additions and 58 deletions

2
.gitignore vendored
View File

@ -42,3 +42,5 @@ CMakeFiles/
/taglib/tag.dir/Release
/ALL_BUILD.dir
/ZERO_CHECK.dir
taglib.xcodeproj
CMakeScripts

View File

@ -36,12 +36,16 @@ using namespace ID3v2;
class ChapterFrame::ChapterFramePrivate
{
public:
ChapterFramePrivate()
{
embeddedFrameList.setAutoDelete(true);
}
ByteVector elementID;
uint startTime;
uint endTime;
uint startOffset;
uint endOffset;
const FrameFactory *factory;
FrameListMap embeddedFrameListMap;
FrameList embeddedFrameList;
};
@ -54,11 +58,11 @@ ChapterFrame::ChapterFrame(const ByteVector &data) :
ID3v2::Frame(data)
{
d = new ChapterFramePrivate;
d->factory = FrameFactory::instance();
setData(data);
}
ChapterFrame::ChapterFrame(const ByteVector &eID, const uint &sT, const uint &eT, const uint &sO, const uint &eO, const FrameList &eF) :
ChapterFrame::ChapterFrame(const ByteVector &eID, const uint &sT, const uint &eT,
const uint &sO, const uint &eO, const FrameList &eF) :
ID3v2::Frame("CHAP")
{
d = new ChapterFramePrivate;
@ -70,7 +74,6 @@ ChapterFrame::ChapterFrame(const ByteVector &eID, const uint &sT, const uint &eT
FrameList l = eF;
for(FrameList::ConstIterator it = l.begin(); it != l.end(); ++it)
addEmbeddedFrame(*it);
d->factory = FrameFactory::instance();
}
ChapterFrame::~ChapterFrame()
@ -207,7 +210,8 @@ void ChapterFrame::parseFields(const ByteVector &data)
{
uint size = data.size();
if(size < 18) {
debug("A CHAP frame must contain at least 18 bytes (1 byte element ID terminated by null and 4x4 bytes for start and end time and offset).");
debug("A CHAP frame must contain at least 18 bytes (1 byte element ID "
"terminated by null and 4x4 bytes for start and end time and offset).");
return;
}
@ -225,7 +229,7 @@ void ChapterFrame::parseFields(const ByteVector &data)
size -= pos;
while((uint)embPos < size - Frame::headerSize(4))
{
Frame *frame = d->factory->createFrame(data.mid(pos + embPos));
Frame *frame = FrameFactory::instance()->createFrame(data.mid(pos + embPos));
if(!frame)
return;
@ -261,6 +265,5 @@ ChapterFrame::ChapterFrame(const ByteVector &data, Header *h) :
Frame(h)
{
d = new ChapterFramePrivate;
d->factory = FrameFactory::instance();
parseFields(fieldData(data));
}

View File

@ -35,7 +35,7 @@ namespace TagLib {
namespace ID3v2 {
/*!
* This is an implementation of ID3v2 chapter frames. The purpose of this
* This is an implementation of ID3v2 chapter frames. The purpose of this
* frame is to describe a single chapter within an audio file.
*/
@ -56,48 +56,49 @@ namespace TagLib {
* start time \a sT, end time \a eT, start offset \a sO,
* end offset \a eO and embedded frames, that are in \a eF.
*/
ChapterFrame(const ByteVector &eID, const uint &sT, const uint &eT, const uint &sO, const uint &eO, const FrameList &eF);
ChapterFrame(const ByteVector &eID, const uint &sT, const uint &eT, const uint &sO,
const uint &eO, const FrameList &eF);
/*!
* Destroys the frame.
*/
~ChapterFrame();
/*!
* Returns the element ID of the frame. Element ID
* is a null terminated string, however it's not human-readable.
*
*
* \see setElementID()
*/
ByteVector elementID() const;
/*!
* Returns time of chapter's start (in miliseconds).
*
*
* \see setStartTime()
*/
uint startTime() const;
/*!
* Returns time of chapter's end (in miliseconds).
*
*
* \see setEndTime()
*/
uint endTime() const;
/*!
* Returns zero based byte offset (count of bytes from the beginning
* of the audio file) of chapter's start.
*
*
* \note If returned value is 0xFFFFFFFF, start time should be used instead.
* \see setStartOffset()
*/
uint startOffset() const;
/*!
* Returns zero based byte offset (count of bytes from the beginning
* of the audio file) of chapter's end.
*
*
* \note If returned value is 0xFFFFFFFF, end time should be used instead.
* \see setEndOffset()
*/
@ -106,48 +107,48 @@ namespace TagLib {
/*!
* Sets the element ID of the frame to \a eID. If \a eID isn't
* null terminated, a null char is appended automatically.
*
*
* \see elementID()
*/
void setElementID(const ByteVector &eID);
/*!
* Sets time of chapter's start (in miliseconds) to \a sT.
*
*
* \see startTime()
*/
void setStartTime(const uint &sT);
/*!
* Sets time of chapter's end (in miliseconds) to \a eT.
*
*
* \see endTime()
*/
void setEndTime(const uint &eT);
/*!
* Sets zero based byte offset (count of bytes from the beginning
* of the audio file) of chapter's start to \a sO.
*
*
* \see startOffset()
*/
void setStartOffset(const uint &sO);
/*!
* Sets zero based byte offset (count of bytes from the beginning
* of the audio file) of chapter's end to \a eO.
*
*
* \see endOffset()
*/
void setEndOffset(const uint &eO);
/*!
* Returns a reference to the frame list map. This is an FrameListMap of
* all of the frames embedded in the CHAP frame.
*
* This is the most convenient structure for accessing the CHAP frame's
* embedded frames. Many frame types allow multiple instances of the same
* frame type so this is a map of lists. In most cases however there will
* This is the most convenient structure for accessing the CHAP frame's
* embedded frames. Many frame types allow multiple instances of the same
* frame type so this is a map of lists. In most cases however there will
* only be a single frame of a certain type.
*
* \warning You should not modify this data structure directly, instead
@ -156,13 +157,13 @@ namespace TagLib {
* \see embeddedFrameList()
*/
const FrameListMap &embeddedFrameListMap() const;
/*!
* Returns a reference to the embedded frame list. This is an FrameList
* Returns a reference to the embedded frame list. This is an FrameList
* of all of the frames embedded in the CHAP frame in the order that they
* were parsed.
*
* This can be useful if for example you want iterate over the CHAP frame's
* This can be useful if for example you want iterate over the CHAP frame's
* embedded frames in the order that they occur in the CHAP frame.
*
* \warning You should not modify this data structure directly, instead
@ -171,7 +172,7 @@ namespace TagLib {
const FrameList &embeddedFrameList() const;
/*!
* Returns the embedded frame list for frames with the id \a frameID
* Returns the embedded frame list for frames with the id \a frameID
* or an empty list if there are no embedded frames of that type. This
* is just a convenience and is equivalent to:
*
@ -184,7 +185,7 @@ namespace TagLib {
const FrameList &embeddedFrameList(const ByteVector &frameID) const;
/*!
* Add an embedded frame to the CHAP frame. At this point the CHAP frame
* Add an embedded frame to the CHAP frame. At this point the CHAP frame
* takes ownership of the embedded frame and will handle freeing its memory.
*
* \note Using this method will invalidate any pointers on the list
@ -193,7 +194,7 @@ namespace TagLib {
void addEmbeddedFrame(Frame *frame);
/*!
* Remove an embedded frame from the CHAP frame. If \a del is true the frame's
* Remove an embedded frame from the CHAP frame. If \a del is true the frame's
* memory will be freed; if it is false, it must be deleted by the user.
*
* \note Using this method will invalidate any pointers on the list
@ -202,7 +203,7 @@ namespace TagLib {
void removeEmbeddedFrame(Frame *frame, bool del = true);
/*!
* Remove all embedded frames of type \a id from the CHAP frame and free their
* Remove all embedded frames of type \a id from the CHAP frame and free their
* memory.
*
* \note Using this method will invalidate any pointers on the list

View File

@ -35,11 +35,15 @@ using namespace ID3v2;
class TableOfContentsFrame::TableOfContentsFramePrivate
{
public:
TableOfContentsFramePrivate()
{
embeddedFrameList.setAutoDelete(true);
}
ByteVector elementID;
bool isTopLevel;
bool isOrdered;
ByteVectorList childElements;
const FrameFactory *factory;
FrameListMap embeddedFrameListMap;
FrameList embeddedFrameList;
};
@ -52,11 +56,11 @@ TableOfContentsFrame::TableOfContentsFrame(const ByteVector &data) :
ID3v2::Frame(data)
{
d = new TableOfContentsFramePrivate;
d->factory = FrameFactory::instance();
setData(data);
}
TableOfContentsFrame::TableOfContentsFrame(const ByteVector &eID, const ByteVectorList &ch, const FrameList &eF) :
TableOfContentsFrame::TableOfContentsFrame(const ByteVector &eID, const ByteVectorList &ch,
const FrameList &eF) :
ID3v2::Frame("CTOC")
{
d = new TableOfContentsFramePrivate;
@ -65,7 +69,6 @@ TableOfContentsFrame::TableOfContentsFrame(const ByteVector &eID, const ByteVect
FrameList l = eF;
for(FrameList::ConstIterator it = l.begin(); it != l.end(); ++it)
addEmbeddedFrame(*it);
d->factory = FrameFactory::instance();
}
TableOfContentsFrame::~TableOfContentsFrame()
@ -188,7 +191,8 @@ PropertyMap TableOfContentsFrame::asProperties() const
return map;
}
TableOfContentsFrame *TableOfContentsFrame::findByElementID(const ID3v2::Tag *tag, const ByteVector &eID) // static
TableOfContentsFrame *TableOfContentsFrame::findByElementID(const ID3v2::Tag *tag,
const ByteVector &eID) // static
{
ID3v2::FrameList tablesOfContents = tag->frameList("CTOC");
@ -224,7 +228,9 @@ void TableOfContentsFrame::parseFields(const ByteVector &data)
{
uint size = data.size();
if(size < 6) {
debug("A CTOC frame must contain at least 6 bytes (1 byte element ID terminated by null, 1 byte flags, 1 byte entry count and 1 byte child element ID terminated by null.");
debug("A CTOC frame must contain at least 6 bytes (1 byte element ID terminated by "
"null, 1 byte flags, 1 byte entry count and 1 byte child element ID terminated "
"by null.");
return;
}
@ -244,7 +250,7 @@ void TableOfContentsFrame::parseFields(const ByteVector &data)
size -= pos;
while((uint)embPos < size - Frame::headerSize(4))
{
Frame *frame = d->factory->createFrame(data.mid(pos + embPos));
Frame *frame = FrameFactory::instance()->createFrame(data.mid(pos + embPos));
if(!frame)
return;
@ -288,6 +294,5 @@ TableOfContentsFrame::TableOfContentsFrame(const ByteVector &data, Header *h) :
Frame(h)
{
d = new TableOfContentsFramePrivate;
d->factory = FrameFactory::instance();
parseFields(fieldData(data));
}

View File

@ -25,11 +25,10 @@ public:
RIFF::AIFF::File *f = new RIFF::AIFF::File(filename.c_str());
CPPUNIT_ASSERT_EQUAL(705, f->audioProperties()->bitrate());
CPPUNIT_ASSERT(!f->audioProperties()->isAiffC());
CPPUNIT_ASSERT(f->audioProperties()->isAiffC());
delete f;
}
void testAiffCProperties()
{
ScopedFileCopy copy("alaw", ".aifc");
@ -39,7 +38,6 @@ public:
CPPUNIT_ASSERT(f->audioProperties()->isAiffC());
CPPUNIT_ASSERT_EQUAL(ByteVector("ALAW"), f->audioProperties()->compressionType());
CPPUNIT_ASSERT_EQUAL(String("SGI CCITT G.711 A-law"), f->audioProperties()->compressionName());
delete f;
}

View File

@ -172,6 +172,7 @@ public:
FileRef *f = new FileRef(TEST_FILE_PATH_C("empty_flac.oga"));
CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File *>(f->file()) == NULL);
CPPUNIT_ASSERT(dynamic_cast<Ogg::FLAC::File *>(f->file()) != NULL);
delete f;
}
void testOGA_Vorbis()
@ -179,6 +180,7 @@ public:
FileRef *f = new FileRef(TEST_FILE_PATH_C("empty_vorbis.oga"));
CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File *>(f->file()) != NULL);
CPPUNIT_ASSERT(dynamic_cast<Ogg::FLAC::File *>(f->file()) == NULL);
delete f;
}
void testAPE()

View File

@ -69,6 +69,7 @@ public:
CPPUNIT_ASSERT_EQUAL(String("image/png"), pic->mimeType());
CPPUNIT_ASSERT_EQUAL(String("A pixel."), pic->description());
CPPUNIT_ASSERT_EQUAL(size_t(150), pic->data().size());
delete f;
}
void testAddPicture()

View File

@ -209,6 +209,8 @@ public:
CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), frame->mimeType());
CPPUNIT_ASSERT_EQUAL(ID3v2::AttachedPictureFrame::FileIcon, frame->type());
CPPUNIT_ASSERT_EQUAL(String("d"), frame->description());
delete frame;
}
void testDontRender22()
@ -921,9 +923,9 @@ public:
f.setEndTime(5);
f.setStartOffset(2);
f.setEndOffset(3);
ID3v2::TextIdentificationFrame eF("TIT2");
eF.setText("CH1");
f.addEmbeddedFrame(&eF);
ID3v2::TextIdentificationFrame *eF = new ID3v2::TextIdentificationFrame("TIT2");
eF->setText("CH1");
f.addEmbeddedFrame(eF);
CPPUNIT_ASSERT_EQUAL(
ByteVector("CHAP" // Frame ID
"\x00\x00\x00\x20" // Frame size
@ -979,9 +981,9 @@ public:
f.setIsOrdered(true);
f.addChildElement(ByteVector("\x43\x00", 2));
f.addChildElement(ByteVector("\x44\x00", 2));
ID3v2::TextIdentificationFrame eF("TIT2");
eF.setText("TC1");
f.addEmbeddedFrame(&eF);
ID3v2::TextIdentificationFrame *eF = new ID3v2::TextIdentificationFrame("TIT2");
eF->setText("TC1");
f.addEmbeddedFrame(eF);
CPPUNIT_ASSERT_EQUAL(
ByteVector("CTOC" // Frame ID
"\x00\x00\x00\x16" // Frame size

View File

@ -142,6 +142,7 @@ public:
CPPUNIT_ASSERT_EQUAL(String("82,164"), f->tag()->itemListMap()["----:com.apple.iTunes:replaygain_track_minmax"].toStringList()[0]);
CPPUNIT_ASSERT_EQUAL(String("Pearl Jam"), f->tag()->artist());
CPPUNIT_ASSERT_EQUAL(String("foo"), f->tag()->comment());
delete f;
}
void test64BitAtom()
@ -158,6 +159,7 @@ public:
f->tag()->itemListMap()["pgap"] = true;
f->save();
delete atoms;
delete f;
f = new MP4::File(filename.c_str());
@ -168,6 +170,7 @@ public:
moov = atoms->atoms[0];
// original size + 'pgap' size + padding
CPPUNIT_ASSERT_EQUAL(long(77 + 25 + 974), moov->length);
delete atoms;
delete f;
}

View File

@ -86,6 +86,8 @@ public:
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(2));
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), f->chunkData(2));
delete f;
}
void testLastChunkAtEvenPosition()

View File

@ -11,6 +11,7 @@
#include <sys/stat.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>
@ -26,7 +27,9 @@ inline string testFilePath(const string &filename)
inline string copyFile(const string &filename, const string &ext)
{
string newname = string(tempnam(NULL, NULL)) + ext;
char *newname_c = tempnam(NULL, NULL);
string newname = string(newname_c) + ext;
free(newname_c);
string oldname = testFilePath(filename) + ext;
#ifdef _WIN32
CopyFileA(oldname.c_str(), newname.c_str(), FALSE);