mirror of
https://github.com/taglib/taglib.git
synced 2025-06-04 01:28:21 -04:00
Fixed errors in ChapterFrame constructor.
Fixed errors in ChapterFrame method renderFields. Fixed errors in TableOfContentsFrame method parseFields. Added ChapterFrame and TableOfContentsFrame headers and sources to CMakeLists.txt. Added some basic testing of CHAP and CTOC frames parsing.
This commit is contained in:
parent
bcad792e75
commit
4815dbba68
@ -76,6 +76,8 @@ set(tag_HDRS
|
||||
mpeg/id3v2/frames/unknownframe.h
|
||||
mpeg/id3v2/frames/unsynchronizedlyricsframe.h
|
||||
mpeg/id3v2/frames/urllinkframe.h
|
||||
mpeg/id3v2/frames/chapterframe.h
|
||||
mpeg/id3v2/frames/tableofcontentsframe.h
|
||||
ogg/oggfile.h
|
||||
ogg/oggpage.h
|
||||
ogg/oggpageheader.h
|
||||
@ -166,6 +168,8 @@ set(frames_SRCS
|
||||
mpeg/id3v2/frames/unknownframe.cpp
|
||||
mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp
|
||||
mpeg/id3v2/frames/urllinkframe.cpp
|
||||
mpeg/id3v2/frames/chapterframe.cpp
|
||||
mpeg/id3v2/frames/tableofcontentsframe.cpp
|
||||
)
|
||||
|
||||
set(ogg_SRCS
|
||||
|
@ -54,7 +54,7 @@ ChapterFrame::ChapterFrame(const ByteVector &data) :
|
||||
setData(data);
|
||||
}
|
||||
|
||||
ChapterFrame::ChapterFrame(const ByteVector &eID, const int &sT, const int &eT, const int &sO, const int &eO) :
|
||||
ChapterFrame::ChapterFrame(const ByteVector &eID, const uint &sT, const uint &eT, const uint &sO, const uint &eO) :
|
||||
ID3v2::Frame("CHAP")
|
||||
{
|
||||
d = new ChapterFramePrivate;
|
||||
@ -62,7 +62,7 @@ ChapterFrame::ChapterFrame(const ByteVector &eID, const int &sT, const int &eT,
|
||||
d->startTime = sT;
|
||||
d->endTime = eT;
|
||||
d->startOffset = sO;
|
||||
d->endOffset = e0;
|
||||
d->endOffset = eO;
|
||||
}
|
||||
|
||||
ChapterFrame::~ChapterFrame()
|
||||
@ -127,7 +127,7 @@ String ChapterFrame::toString() const
|
||||
return String::null;
|
||||
}
|
||||
|
||||
PropertyMap UniqueFileIdentifierFrame::asProperties() const
|
||||
PropertyMap ChapterFrame::asProperties() const
|
||||
{
|
||||
PropertyMap map;
|
||||
|
||||
@ -176,10 +176,10 @@ ByteVector ChapterFrame::renderFields() const
|
||||
ByteVector data;
|
||||
|
||||
data.append(d->elementID);
|
||||
data.append(ByteVector.fromUInt(d->startTime, true));
|
||||
data.append(ByteVector.fromUInt(d->endTime, true));
|
||||
data.append(ByteVector.fromUInt(d->startOffset, true));
|
||||
data.append(ByteVector.fromUInt(d->endOffset, true));
|
||||
data.append(ByteVector::fromUInt(d->startTime, true));
|
||||
data.append(ByteVector::fromUInt(d->endTime, true));
|
||||
data.append(ByteVector::fromUInt(d->startOffset, true));
|
||||
data.append(ByteVector::fromUInt(d->endOffset, true));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define TAGLIB_CHAPTERFRAME
|
||||
|
||||
#include "id3v2frame.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@ -87,6 +88,7 @@ namespace TagLib {
|
||||
* 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;
|
||||
@ -95,6 +97,7 @@ namespace TagLib {
|
||||
* 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()
|
||||
*/
|
||||
uint endOffset() const;
|
||||
@ -135,7 +138,7 @@ namespace TagLib {
|
||||
*
|
||||
* \see endOffset()
|
||||
*/
|
||||
void endOffset(const uint &eO);
|
||||
void setEndOffset(const uint &eO);
|
||||
|
||||
virtual String toString() const;
|
||||
|
||||
|
@ -169,10 +169,10 @@ void TableOfContentsFrame::parseFields(const ByteVector &data)
|
||||
int pos = 0;
|
||||
d->elementID = readStringField(data, String::Latin1, &pos).data(String::Latin1);
|
||||
d->elementID.append(char(0));
|
||||
d->isTopLevel = (data.at(pos++) & 2) > 0;
|
||||
d->isTopLevel = (data.at(pos) & 2) > 0;
|
||||
d->isOrdered = (data.at(pos++) & 1) > 0;
|
||||
uint entryCount = data.at(pos++);
|
||||
for(int i = 0; i < entryCount; i++)
|
||||
for(uint i = 0; i < entryCount; i++)
|
||||
{
|
||||
ByteVector childElementID = readStringField(data, String::Latin1, &pos).data(String::Latin1);
|
||||
childElementID.append(char(0));
|
||||
@ -193,7 +193,7 @@ ByteVector TableOfContentsFrame::renderFields() const
|
||||
flags += 1;
|
||||
data.append(flags);
|
||||
data.append((char)(entryCount()));
|
||||
ConstIterator it = d->childElements.begin();
|
||||
ByteVectorList::ConstIterator it = d->childElements.begin();
|
||||
while(it != d->childElements.end()) {
|
||||
data.append(*it);
|
||||
data.append(char(0));
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <popularimeterframe.h>
|
||||
#include <urllinkframe.h>
|
||||
#include <ownershipframe.h>
|
||||
#include <chapterframe.h>
|
||||
#include <tableofcontentsframe.h>
|
||||
#include <tdebug.h>
|
||||
#include <tpropertymap.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
@ -77,6 +79,8 @@ class TestID3v2 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testPropertyInterface2);
|
||||
CPPUNIT_TEST(testDeleteFrame);
|
||||
CPPUNIT_TEST(testSaveAndStripID3v1ShouldNotAddFrameFromID3v1ToId3v2);
|
||||
CPPUNIT_TEST(testChapters);
|
||||
CPPUNIT_TEST(testTableOfContents);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -734,6 +738,66 @@ public:
|
||||
CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TPE1"));
|
||||
}
|
||||
|
||||
void testChaptersParsing()
|
||||
{
|
||||
ID3v2::ChapterFrame f(
|
||||
ByteVector("CHAP" // Frame ID
|
||||
"\x00\x00\x00\x12" // Frame size
|
||||
"\x00\x00" // Frame flags
|
||||
"\x43\x00" // Element ID
|
||||
"\x00\x00\x00\x03" // Start time
|
||||
"\x00\x00\x00\x05" // End time
|
||||
"\x00\x00\x00\x02" // Start offset
|
||||
"\x00\x00\x00\x03", 28)); // End offset
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\x43\x00", 2),
|
||||
f.elementID());
|
||||
CPPUNIT_ASSERT((uint)0x03 == f.startTime());
|
||||
CPPUNIT_ASSERT((uint)0x05 == f.endTime());
|
||||
CPPUNIT_ASSERT((uint)0x02 == f.startOffset());
|
||||
CPPUNIT_ASSERT((uint)0x03 == f.endOffset());
|
||||
}
|
||||
|
||||
void testChapters()
|
||||
{
|
||||
ID3v2::ChapterFrame f(
|
||||
ByteVector("CHAP" // Frame ID
|
||||
"\x00\x00\x00\x12" // Frame size
|
||||
"\x00\x00" // Frame flags
|
||||
"\x43\x00" // Element ID
|
||||
"\x00\x00\x00\x03" // Start time
|
||||
"\x00\x00\x00\x05" // End time
|
||||
"\x00\x00\x00\x02" // Start offset
|
||||
"\x00\x00\x00\x03", 28)); // End offset
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\x43\x00", 2),
|
||||
f.elementID());
|
||||
CPPUNIT_ASSERT((uint)0x03 == f.startTime());
|
||||
CPPUNIT_ASSERT((uint)0x05 == f.endTime());
|
||||
CPPUNIT_ASSERT((uint)0x02 == f.startOffset());
|
||||
CPPUNIT_ASSERT((uint)0x03 == f.endOffset());
|
||||
}
|
||||
|
||||
void testTableOfContents()
|
||||
{
|
||||
ID3v2::TableOfContentsFrame f(
|
||||
ByteVector("CTOC" // Frame ID
|
||||
"\x00\x00\x00\x08" // Frame size
|
||||
"\x00\x00" // Frame flags
|
||||
"\x54\x00" // Element ID
|
||||
"\x01" // CTOC flags
|
||||
"\x02" // Entry count
|
||||
"\x43\x00" // First entry
|
||||
"\x44\x00", 18)); // Second entry
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\x54\x00", 2),
|
||||
f.elementID());
|
||||
CPPUNIT_ASSERT(!f.isTopLevel());
|
||||
CPPUNIT_ASSERT(f.isOrdered());
|
||||
CPPUNIT_ASSERT((uint)0x02 == f.entryCount());
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\x43\x00", 2),
|
||||
f.childElements()[0]);
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\x44\x00", 2),
|
||||
f.childElements()[1]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);
|
||||
|
Loading…
x
Reference in New Issue
Block a user