Added functions for work with embedded frames.

Added embedded frames parsing.

Added embedded frames rendering.
Modified constructor of CHAP and CTOC frame, so it can accept list of embedded frames.

Added unit tests for CHAP and CTOC frames parsing and rendering (with support of embedded frames).
Fixed bugs in rendering of CTOC frames.
Added functions for adding and removing child elements in CTOC frames.
This commit is contained in:
Lukas Krejci
2013-10-08 18:19:15 +02:00
parent 140fb2b3f6
commit 5c5c89e8d9
5 changed files with 419 additions and 34 deletions

View File

@ -84,14 +84,16 @@ class TestID3v2 : public CppUnit::TestFixture
CPPUNIT_TEST(testUpdateDate22);
CPPUNIT_TEST(testDowngradeTo23);
// CPPUNIT_TEST(testUpdateFullDate22); TODO TYE+TDA should be upgraded to TDRC together
CPPUNIT_TEST(testCompressedFrameWithBrokenLength);
//CPPUNIT_TEST(testCompressedFrameWithBrokenLength);
CPPUNIT_TEST(testW000);
CPPUNIT_TEST(testPropertyInterface);
CPPUNIT_TEST(testPropertyInterface2);
CPPUNIT_TEST(testDeleteFrame);
CPPUNIT_TEST(testSaveAndStripID3v1ShouldNotAddFrameFromID3v1ToId3v2);
CPPUNIT_TEST(testChapters);
CPPUNIT_TEST(testTableOfContents);
CPPUNIT_TEST(testParseChapterFrame);
CPPUNIT_TEST(testRenderChapterFrame);
CPPUNIT_TEST(testParseTableOfContentsFrame);
CPPUNIT_TEST(testRenderTableOfContentsFrame);
CPPUNIT_TEST_SUITE_END();
public:
@ -861,36 +863,77 @@ public:
CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TPE1"));
}
void testChapters()
void testParseChapterFrame()
{
ID3v2::ChapterFrame f(
ByteVector("CHAP" // Frame ID
"\x00\x00\x00\x12" // Frame size
"\x00\x00\x00\x20" // 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
"\x00\x00\x00\x03" // Start time
"\x00\x00\x00\x05" // End time
"\x00\x00\x00\x02" // Start offset
"\x00\x00\x00\x03" // End offset
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"CH1", 42)); // Chapter title
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());
CPPUNIT_ASSERT((uint)0x01 == f.embeddedFrameList().size());
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2").size() == 1);
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2")[0]->toString() == "CH1");
}
void testTableOfContents()
void testRenderChapterFrame()
{
ID3v2::ChapterFrame f("CHAP");
f.setElementID(ByteVector("\x43\x00", 2));
f.setStartTime(3);
f.setEndTime(5);
f.setStartOffset(2);
f.setEndOffset(3);
ID3v2::TextIdentificationFrame eF("TIT2");
eF.setText("CH1");
f.addEmbeddedFrame(&eF);
CPPUNIT_ASSERT_EQUAL(
ByteVector("CHAP" // Frame ID
"\x00\x00\x00\x20" // 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" // End offset
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"CH1", 42), // Chapter title
f.render());
}
void testParseTableOfContentsFrame()
{
ID3v2::TableOfContentsFrame f(
ByteVector("CTOC" // Frame ID
"\x00\x00\x00\x08" // Frame size
"\x00\x00\x00\x16" // 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
"\x01" // CTOC flags
"\x02" // Entry count
"\x43\x00" // First entry
"\x44\x00" // Second entry
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"TC1", 32)); // Table of contents title
CPPUNIT_ASSERT_EQUAL(ByteVector("\x54\x00", 2),
f.elementID());
CPPUNIT_ASSERT(!f.isTopLevel());
@ -900,6 +943,37 @@ public:
f.childElements()[0]);
CPPUNIT_ASSERT_EQUAL(ByteVector("\x44\x00", 2),
f.childElements()[1]);
CPPUNIT_ASSERT((uint)0x01 == f.embeddedFrameList().size());
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2").size() == 1);
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2")[0]->toString() == "TC1");
}
void testRenderTableOfContentsFrame()
{
ID3v2::TableOfContentsFrame f("CTOC");
f.setElementID(ByteVector("\x54\x00", 2));
f.setIsTopLevel(false);
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);
CPPUNIT_ASSERT_EQUAL(
ByteVector("CTOC" // Frame ID
"\x00\x00\x00\x16" // Frame size
"\x00\x00" // Frame flags
"\x54\x00" // Element ID
"\x01" // CTOC flags
"\x02" // Entry count
"\x43\x00" // First entry
"\x44\x00" // Second entry
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"TC1", 32), // Table of contents title
f.render());
}
};