Fix misc issues

This commit is contained in:
Martchus 2016-07-30 22:35:46 +02:00
parent 302fc76261
commit 8663dedf8c
6 changed files with 75 additions and 26 deletions

View File

@ -142,7 +142,6 @@ set(SRC_FILES
mediaformat.cpp mediaformat.cpp
) )
set(TEST_HEADER_FILES set(TEST_HEADER_FILES
) )
set(TEST_SRC_FILES set(TEST_SRC_FILES
tests/cppunit.cpp tests/cppunit.cpp

View File

@ -89,16 +89,15 @@ void MatroskaTag::parse(EbmlElement &tagElement)
static const string context("parsing Matroska tag"); static const string context("parsing Matroska tag");
tagElement.parse(); tagElement.parse();
m_size = tagElement.totalSize(); m_size = tagElement.totalSize();
EbmlElement *child = tagElement.firstChild();
MatroskaTagField field; MatroskaTagField field;
while(child) { for(EbmlElement *child = tagElement.firstChild(); child; child = child->nextSibling()) {
child->parse(); child->parse();
switch(child->id()) { switch(child->id()) {
case MatroskaIds::SimpleTag: { case MatroskaIds::SimpleTag: {
try { try {
field.invalidateNotifications(); field.invalidateNotifications();
field.reparse(*child, true); field.reparse(*child, true);
fields().insert(pair<string, MatroskaTagField>(field.id(), field)); fields().insert(make_pair(field.id(), field));
} catch(const Failure &) { } catch(const Failure &) {
} }
addNotifications(context, field); addNotifications(context, field);
@ -107,7 +106,6 @@ void MatroskaTag::parse(EbmlElement &tagElement)
parseTargets(*child); parseTargets(*child);
break; break;
} }
child = child->nextSibling();
} }
} }
@ -152,8 +150,7 @@ void MatroskaTag::parseTargets(EbmlElement &targetsElement)
bool targetTypeValueFound = false; bool targetTypeValueFound = false;
bool targetTypeFound = false; bool targetTypeFound = false;
targetsElement.parse(); targetsElement.parse();
EbmlElement *child = targetsElement.firstChild(); for(EbmlElement *child = targetsElement.firstChild(); child; child = child->nextSibling()) {
while(child) {
try { try {
child->parse(); child->parse();
} catch(const Failure &) { } catch(const Failure &) {
@ -192,7 +189,6 @@ void MatroskaTag::parseTargets(EbmlElement &targetsElement)
default: default:
addNotification(NotificationType::Warning, "Targets element contains unknown element. It will be ignored.", context); addNotification(NotificationType::Warning, "Targets element contains unknown element. It will be ignored.", context);
} }
child = child->nextSibling();
} }
if(!m_target.level()) { if(!m_target.level()) {
m_target.setLevel(50); // default level m_target.setLevel(50); // default level

View File

@ -198,11 +198,11 @@ inline void TagTarget::clear()
/*! /*!
* \brief Returns whether the tag targets are equal. * \brief Returns whether the tag targets are equal.
* \remarks Targets where only the level name differs are considered equal though.
*/ */
inline bool TagTarget::operator ==(const TagTarget &other) const inline bool TagTarget::operator ==(const TagTarget &other) const
{ {
return level() == other.level() return level() == other.level()
//&& m_levelName == other.m_levelName // consider targets with the same level number but different level names equal?
&& m_tracks == other.m_tracks && m_tracks == other.m_tracks
&& m_chapters == other.m_chapters && m_chapters == other.m_chapters
&& m_editions == other.m_editions && m_editions == other.m_editions

View File

@ -226,7 +226,15 @@ PositionInSet TagValue::toPositionInSet() const
if(!isEmpty()) { if(!isEmpty()) {
switch(m_type) { switch(m_type) {
case TagDataType::Text: case TagDataType::Text:
return PositionInSet(string(m_ptr.get(), m_size)); switch(m_encoding) {
case TagTextEncoding::Unspecified:
case TagTextEncoding::Latin1:
case TagTextEncoding::Utf8:
return PositionInSet(string(m_ptr.get(), m_size));
case TagTextEncoding::Utf16LittleEndian:
case TagTextEncoding::Utf16BigEndian:
return PositionInSet(u16string(reinterpret_cast<char16_t *>(m_ptr.get()), m_size / 2));
}
case TagDataType::Integer: case TagDataType::Integer:
case TagDataType::PositionInSet: case TagDataType::PositionInSet:
switch(m_size) { switch(m_size) {
@ -468,19 +476,20 @@ void TagValue::toWString(std::u16string &result, TagTextEncoding encoding) const
/*! /*!
* \brief Assigns a copy of the given \a text. * \brief Assigns a copy of the given \a text.
* \param text Specifies the text to be assigned. * \param text Specifies the text to be assigned.
* \param textSize Specifies the size of \a text. (The actual number of bytes, not the number of characters.)
* \param textEncoding Specifies the encoding of the given \a text. * \param textEncoding Specifies the encoding of the given \a text.
* \param convertTo Specifies the encoding to convert \a text to; set to TagTextEncoding::Unspecified to * \param convertTo Specifies the encoding to convert \a text to; set to TagTextEncoding::Unspecified to
* use \a textEncoding without any character set conversions. * use \a textEncoding without any character set conversions.
* \throws Throws a ConversionException if the conversion the specified character set fails. * \throws Throws a ConversionException if the conversion the specified character set fails.
*/ */
void TagValue::assignText(const string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo) void TagValue::assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding, TagTextEncoding convertTo)
{ {
m_type = TagDataType::Text; m_type = TagDataType::Text;
m_encoding = textEncoding; m_encoding = textEncoding;
if(!text.empty()) { if(textSize) {
if(convertTo == TagTextEncoding::Unspecified || textEncoding == convertTo) { if(convertTo == TagTextEncoding::Unspecified || textEncoding == convertTo) {
m_ptr = make_unique<char []>(m_size = text.size()); m_ptr = make_unique<char []>(m_size = textSize);
text.copy(m_ptr.get(), m_size); copy(text, text + textSize, m_ptr.get());
} else { } else {
StringData encodedData; StringData encodedData;
switch(textEncoding) { switch(textEncoding) {
@ -488,13 +497,13 @@ void TagValue::assignText(const string &text, TagTextEncoding textEncoding, TagT
// use pre-defined methods when encoding to UTF-8 // use pre-defined methods when encoding to UTF-8
switch(convertTo) { switch(convertTo) {
case TagTextEncoding::Latin1: case TagTextEncoding::Latin1:
encodedData = convertLatin1ToUtf8(text.data(), text.size()); encodedData = convertLatin1ToUtf8(text, textSize);
break; break;
case TagTextEncoding::Utf16LittleEndian: case TagTextEncoding::Utf16LittleEndian:
encodedData = convertUtf16LEToUtf8(text.data(), text.size()); encodedData = convertUtf16LEToUtf8(text, textSize);
break; break;
case TagTextEncoding::Utf16BigEndian: case TagTextEncoding::Utf16BigEndian:
encodedData = convertUtf16BEToUtf8(text.data(), text.size()); encodedData = convertUtf16BEToUtf8(text, textSize);
break; break;
default: default:
; ;
@ -504,7 +513,7 @@ void TagValue::assignText(const string &text, TagTextEncoding textEncoding, TagT
// otherwise, determine input and output parameter to use general covertString method // otherwise, determine input and output parameter to use general covertString method
const auto inputParameter = encodingParameter(textEncoding); const auto inputParameter = encodingParameter(textEncoding);
const auto outputParameter = encodingParameter(convertTo); const auto outputParameter = encodingParameter(convertTo);
encodedData = convertString(inputParameter.first, outputParameter.first, text.data(), text.size(), outputParameter.second / inputParameter.second); encodedData = convertString(inputParameter.first, outputParameter.first, text, textSize, outputParameter.second / inputParameter.second);
} }
} }
// can't just move the encoded data because it needs to be deleted with free // can't just move the encoded data because it needs to be deleted with free

View File

@ -64,6 +64,7 @@ class LIB_EXPORT TagValue
public: public:
// constructor, destructor // constructor, destructor
TagValue(); TagValue();
TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
TagValue(const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified); TagValue(const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
TagValue(int value); TagValue(int value);
TagValue(const char *data, size_t length, TagDataType type = TagDataType::Undefined, TagTextEncoding encoding = TagTextEncoding::Latin1); TagValue(const char *data, size_t length, TagDataType type = TagDataType::Undefined, TagTextEncoding encoding = TagTextEncoding::Latin1);
@ -107,6 +108,7 @@ public:
TagTextEncoding descriptionEncoding() const; TagTextEncoding descriptionEncoding() const;
static const TagValue &empty(); static const TagValue &empty();
void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
void assignText(const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified); void assignText(const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
void assignInteger(int value); void assignInteger(int value);
void assignStandardGenreIndex(int index); void assignStandardGenreIndex(int index);
@ -140,6 +142,22 @@ inline TagValue::TagValue() :
m_descEncoding(TagTextEncoding::Latin1) m_descEncoding(TagTextEncoding::Latin1)
{} {}
/*!
* \brief Constructs a new TagValue holding a copy of the given \a text.
* \param text Specifies the text to be assigned.
* \param textSize Specifies the size of \a text. (The actual number of bytes, not the number of characters.)
* \param textEncoding Specifies the encoding of the given \a text.
* \param convertTo Specifies the encoding to convert \a text to; set to TagTextEncoding::Unspecified to
* use \a textEncoding without any character set conversions.
* \throws Throws a ConversionException if the conversion the specified character set fails.
*/
inline TagValue::TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding, TagTextEncoding convertTo) :
m_labeledAsReadonly(false),
m_descEncoding(TagTextEncoding::Latin1)
{
assignText(text, textSize, textEncoding, convertTo);
}
/*! /*!
* \brief Constructs a new TagValue holding a copy of the given \a text. * \brief Constructs a new TagValue holding a copy of the given \a text.
* \param text Specifies the text to be assigned. * \param text Specifies the text to be assigned.
@ -215,6 +233,19 @@ inline TagValue::TagValue(const PositionInSet &value) :
TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet) TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet)
{} {}
/*!
* \brief Assigns a copy of the given \a text.
* \param text Specifies the text to be assigned.
* \param textEncoding Specifies the encoding of the given \a text.
* \param convertTo Specifies the encoding to convert \a text to; set to TagTextEncoding::Unspecified to
* use \a textEncoding without any character set conversions.
* \throws Throws a ConversionException if the conversion the specified character set fails.
*/
inline void TagValue::assignText(const std::string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
{
assignText(text.data(), text.size(), textEncoding, convertTo);
}
/*! /*!
* \brief Assigns the given PositionInSet \a value. * \brief Assigns the given PositionInSet \a value.
*/ */

View File

@ -44,15 +44,17 @@ class OverallTests : public TestFixture
{ {
CPPUNIT_TEST_SUITE(OverallTests); CPPUNIT_TEST_SUITE(OverallTests);
CPPUNIT_TEST(testMp4Parsing); CPPUNIT_TEST(testMp4Parsing);
CPPUNIT_TEST(testMp4Making);
CPPUNIT_TEST(testMp3Parsing); CPPUNIT_TEST(testMp3Parsing);
CPPUNIT_TEST(testMp3Making);
CPPUNIT_TEST(testOggParsing); CPPUNIT_TEST(testOggParsing);
CPPUNIT_TEST(testOggMaking);
CPPUNIT_TEST(testFlacParsing); CPPUNIT_TEST(testFlacParsing);
CPPUNIT_TEST(testFlacMaking);
CPPUNIT_TEST(testMkvParsing); CPPUNIT_TEST(testMkvParsing);
#ifdef PLATFORM_UNIX
CPPUNIT_TEST(testMp4Making);
CPPUNIT_TEST(testMp3Making);
CPPUNIT_TEST(testOggMaking);
CPPUNIT_TEST(testFlacMaking);
CPPUNIT_TEST(testMkvMaking); CPPUNIT_TEST(testMkvMaking);
#endif
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
public: public:
@ -99,15 +101,17 @@ public:
void removeAllTags(); void removeAllTags();
void testMkvParsing(); void testMkvParsing();
void testMkvMaking();
void testMp4Parsing(); void testMp4Parsing();
void testMp4Making();
void testMp3Parsing(); void testMp3Parsing();
void testMp3Making();
void testOggParsing(); void testOggParsing();
void testOggMaking();
void testFlacParsing(); void testFlacParsing();
#ifdef PLATFORM_UNIX
void testMkvMaking();
void testMp4Making();
void testMp3Making();
void testOggMaking();
void testFlacMaking(); void testFlacMaking();
#endif
private: private:
MediaFileInfo m_fileInfo; MediaFileInfo m_fileInfo;
@ -1238,6 +1242,7 @@ void OverallTests::testMkvParsing()
parseFile(TestUtilities::testFilePath("matroska_wave1/test8.mkv"), &OverallTests::checkMkvTestfile8); parseFile(TestUtilities::testFilePath("matroska_wave1/test8.mkv"), &OverallTests::checkMkvTestfile8);
} }
#ifdef PLATFORM_UNIX
/*! /*!
* \brief Tests the Matroska maker via MediaFileInfo. * \brief Tests the Matroska maker via MediaFileInfo.
* \remarks Relies on the parser to check results. * \remarks Relies on the parser to check results.
@ -1318,6 +1323,7 @@ void OverallTests::testMkvMaking()
makeFile(TestUtilities::workingCopyPath("matroska_wave1/test8.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile8); makeFile(TestUtilities::workingCopyPath("matroska_wave1/test8.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile8);
} }
} }
#endif
/*! /*!
* \brief Tests the MP4 parser via MediaFileInfo. * \brief Tests the MP4 parser via MediaFileInfo.
@ -1334,6 +1340,7 @@ void OverallTests::testMp4Parsing()
parseFile(TestUtilities::testFilePath("mtx-test-data/aac/he-aacv2-ps.m4a"), &OverallTests::checkMp4Testfile5); parseFile(TestUtilities::testFilePath("mtx-test-data/aac/he-aacv2-ps.m4a"), &OverallTests::checkMp4Testfile5);
} }
#ifdef PLATFORM_UNIX
/*! /*!
* \brief Tests the MP4 maker via MediaFileInfo. * \brief Tests the MP4 maker via MediaFileInfo.
* \remarks Relies on the parser to check results. * \remarks Relies on the parser to check results.
@ -1394,6 +1401,7 @@ void OverallTests::testMp4Making()
makeFile(TestUtilities::workingCopyPath("mtx-test-data/aac/he-aacv2-ps.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile5); makeFile(TestUtilities::workingCopyPath("mtx-test-data/aac/he-aacv2-ps.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile5);
} }
} }
#endif
/*! /*!
* \brief Tests the MP3 parser via MediaFileInfo. * \brief Tests the MP3 parser via MediaFileInfo.
@ -1406,6 +1414,7 @@ void OverallTests::testMp3Parsing()
parseFile(TestUtilities::testFilePath("mtx-test-data/mp3/id3-tag-and-xing-header.mp3"), &OverallTests::checkMp3Testfile1); parseFile(TestUtilities::testFilePath("mtx-test-data/mp3/id3-tag-and-xing-header.mp3"), &OverallTests::checkMp3Testfile1);
} }
#ifdef PLATFORM_UNIX
/*! /*!
* \brief Tests the MP3 maker via MediaFileInfo. * \brief Tests the MP3 maker via MediaFileInfo.
* \remarks Relies on the parser to check results. * \remarks Relies on the parser to check results.
@ -1455,6 +1464,7 @@ void OverallTests::testMp3Making()
makeFile(TestUtilities::workingCopyPath("mtx-test-data/mp3/id3-tag-and-xing-header.mp3"), modifyRoutine, &OverallTests::checkMp3Testfile1); makeFile(TestUtilities::workingCopyPath("mtx-test-data/mp3/id3-tag-and-xing-header.mp3"), modifyRoutine, &OverallTests::checkMp3Testfile1);
} }
} }
#endif
/*! /*!
* \brief Tests the Ogg parser via MediaFileInfo. * \brief Tests the Ogg parser via MediaFileInfo.
@ -1469,6 +1479,7 @@ void OverallTests::testOggParsing()
parseFile(TestUtilities::testFilePath("mtx-test-data/opus/v-opus.ogg"), &OverallTests::checkOggTestfile2); parseFile(TestUtilities::testFilePath("mtx-test-data/opus/v-opus.ogg"), &OverallTests::checkOggTestfile2);
} }
#ifdef PLATFORM_UNIX
/*! /*!
* \brief Tests the Ogg maker via MediaFileInfo. * \brief Tests the Ogg maker via MediaFileInfo.
* \remarks * \remarks
@ -1502,6 +1513,7 @@ void OverallTests::testOggMaking()
makeFile(TestUtilities::workingCopyPath("mtx-test-data/opus/v-opus.ogg"), modifyRoutine, &OverallTests::checkOggTestfile2); makeFile(TestUtilities::workingCopyPath("mtx-test-data/opus/v-opus.ogg"), modifyRoutine, &OverallTests::checkOggTestfile2);
} }
} }
#endif
/*! /*!
* \brief Tests the FLAC parser via MediaFileInfo. * \brief Tests the FLAC parser via MediaFileInfo.
@ -1515,6 +1527,7 @@ void OverallTests::testFlacParsing()
parseFile(TestUtilities::testFilePath("flac/test.ogg"), &OverallTests::checkFlacTestfile2); parseFile(TestUtilities::testFilePath("flac/test.ogg"), &OverallTests::checkFlacTestfile2);
} }
#ifdef PLATFORM_UNIX
/*! /*!
* \brief Tests the FLAC maker via MediaFileInfo. * \brief Tests the FLAC maker via MediaFileInfo.
* \remarks Relies on the parser to check results. * \remarks Relies on the parser to check results.
@ -1545,3 +1558,4 @@ void OverallTests::testFlacMaking()
makeFile(TestUtilities::workingCopyPath("flac/test.ogg"), modifyRoutine, &OverallTests::checkFlacTestfile2); makeFile(TestUtilities::workingCopyPath("flac/test.ogg"), modifyRoutine, &OverallTests::checkFlacTestfile2);
} }
} }
#endif