Support edition, chapter and attachment UIDs in Matroska simple tags (#1311)

This commit is contained in:
Urs Fleisch
2026-02-24 06:53:23 +01:00
committed by GitHub
parent de6e2b15c8
commit 3db0d48f4b
9 changed files with 257 additions and 20 deletions

View File

@ -51,6 +51,21 @@ int main(int argc, char *argv[])
TagLib::Utils::formatString("%llu",trackUid).toCString(false)
);
}
if(auto editionUid = t.editionUid()) {
PRINT_PRETTY("Edition UID",
TagLib::Utils::formatString("%llu",editionUid).toCString(false)
);
}
if(auto chapterUid = t.chapterUid()) {
PRINT_PRETTY("Chapter UID",
TagLib::Utils::formatString("%llu",chapterUid).toCString(false)
);
}
if(auto attachmentUid = t.attachmentUid()) {
PRINT_PRETTY("Attachment UID",
TagLib::Utils::formatString("%llu",attachmentUid).toCString(false)
);
}
const TagLib::String &language = t.language();
PRINT_PRETTY("Language", !language.isEmpty() ? language.toCString(false) : "Not set");

View File

@ -84,6 +84,9 @@ std::unique_ptr<EBML::Element> EBML::Element::factory(File &file)
RETURN_ELEMENT_FOR_CASE(Id::MkCodecID);
RETURN_ELEMENT_FOR_CASE(Id::MkTagTargetTypeValue);
RETURN_ELEMENT_FOR_CASE(Id::MkTagTrackUID);
RETURN_ELEMENT_FOR_CASE(Id::MkTagEditionUID);
RETURN_ELEMENT_FOR_CASE(Id::MkTagChapterUID);
RETURN_ELEMENT_FOR_CASE(Id::MkTagAttachmentUID);
RETURN_ELEMENT_FOR_CASE(Id::MkTagsLanguageDefault);
RETURN_ELEMENT_FOR_CASE(Id::MkAttachedFileUID);
RETURN_ELEMENT_FOR_CASE(Id::MkSeekPosition);

View File

@ -48,6 +48,9 @@ namespace TagLib
MkTagTargets = 0x63C0,
MkTagTargetTypeValue = 0x68CA,
MkTagTrackUID = 0x63C5,
MkTagEditionUID = 0x63C9,
MkTagChapterUID = 0x63C4,
MkTagAttachmentUID = 0x63C6,
MkSimpleTag = 0x67C8,
MkTagName = 0x45A3,
MkTagLanguage = 0x447A,
@ -181,6 +184,9 @@ namespace TagLib
template <> struct GetElementTypeById<Element::Id::MkCodecID> { using type = Latin1StringElement; };
template <> struct GetElementTypeById<Element::Id::MkTagTargetTypeValue> { using type = UIntElement; };
template <> struct GetElementTypeById<Element::Id::MkTagTrackUID> { using type = UIntElement; };
template <> struct GetElementTypeById<Element::Id::MkTagEditionUID> { using type = UIntElement; };
template <> struct GetElementTypeById<Element::Id::MkTagChapterUID> { using type = UIntElement; };
template <> struct GetElementTypeById<Element::Id::MkTagAttachmentUID> { using type = UIntElement; };
template <> struct GetElementTypeById<Element::Id::MkAttachedFileUID> { using type = UIntElement; };
template <> struct GetElementTypeById<Element::Id::MkSeekPosition> { using type = UIntElement; };
template <> struct GetElementTypeById<Element::Id::MkTimestampScale> { using type = UIntElement; };

View File

@ -69,6 +69,9 @@ std::unique_ptr<Matroska::Tag> EBML::MkTags::parse() const
// Parse the <Targets> element
Matroska::SimpleTag::TargetTypeValue targetTypeValue = Matroska::SimpleTag::TargetTypeValue::None;
unsigned long long trackUid = 0;
unsigned long long edtionUid = 0;
unsigned long long chapterUid = 0;
unsigned long long attachmentUid = 0;
if(targets) {
for(const auto &targetsChild : *targets) {
if(const Id id = targetsChild->getId(); id == Id::MkTagTargetTypeValue
@ -80,6 +83,15 @@ std::unique_ptr<Matroska::Tag> EBML::MkTags::parse() const
else if(id == Id::MkTagTrackUID) {
trackUid = element_cast<Id::MkTagTrackUID>(targetsChild)->getValue();
}
else if(id == Id::MkTagEditionUID) {
edtionUid = element_cast<Id::MkTagEditionUID>(targetsChild)->getValue();
}
else if(id == Id::MkTagChapterUID) {
chapterUid = element_cast<Id::MkTagChapterUID>(targetsChild)->getValue();
}
else if(id == Id::MkTagAttachmentUID) {
attachmentUid = element_cast<Id::MkTagAttachmentUID>(targetsChild)->getValue();
}
}
}
@ -109,10 +121,10 @@ std::unique_ptr<Matroska::Tag> EBML::MkTags::parse() const
mTag->addSimpleTag(tagValueString
? Matroska::SimpleTag(tagName, *tagValueString,
targetTypeValue, language, defaultLanguageFlag,
trackUid)
trackUid, edtionUid, chapterUid, attachmentUid)
: Matroska::SimpleTag(tagName, *tagValueBinary,
targetTypeValue, language, defaultLanguageFlag,
trackUid));
trackUid, edtionUid, chapterUid, attachmentUid));
}
}
return mTag;

View File

@ -30,19 +30,26 @@ class Matroska::SimpleTag::SimpleTagPrivate
public:
SimpleTagPrivate(const String &name, const String &value,
TargetTypeValue targetTypeValue, const String &language, bool defaultLanguage,
unsigned long long trackUid) :
unsigned long long trackUid, unsigned long long editionUid,
unsigned long long chapterUid, unsigned long long attachmentUid) :
value(value), name(name), language(language), trackUid(trackUid),
editionUid(editionUid), chapterUid(chapterUid), attachmentUid(attachmentUid),
targetTypeValue(targetTypeValue), defaultLanguageFlag(defaultLanguage) {}
SimpleTagPrivate(const String &name, const ByteVector &value,
TargetTypeValue targetTypeValue, const String &language, bool defaultLanguage,
unsigned long long trackUid) :
unsigned long long trackUid, unsigned long long editionUid,
unsigned long long chapterUid, unsigned long long attachmentUid) :
value(value), name(name), language(language), trackUid(trackUid),
editionUid(editionUid), chapterUid(chapterUid), attachmentUid(attachmentUid),
targetTypeValue(targetTypeValue), defaultLanguageFlag(defaultLanguage) {}
const std::variant<String, ByteVector> value;
const String name;
const String language;
const unsigned long long trackUid;
const unsigned long long editionUid;
const unsigned long long chapterUid;
const unsigned long long attachmentUid;
const TargetTypeValue targetTypeValue;
const bool defaultLanguageFlag;
};
@ -56,7 +63,19 @@ Matroska::SimpleTag::SimpleTag(const String &name, const String &value,
const String &language, bool defaultLanguage,
unsigned long long trackUid) :
d(std::make_unique<SimpleTagPrivate>(name, value, targetTypeValue,
language, defaultLanguage, trackUid))
language, defaultLanguage, trackUid, 0, 0, 0))
{
}
Matroska::SimpleTag::SimpleTag(const String &name, const String &value,
TargetTypeValue targetTypeValue,
const String &language, bool defaultLanguage,
unsigned long long trackUid,
unsigned long long editionUid,
unsigned long long chapterUid,
unsigned long long attachmentUid) :
d(std::make_unique<SimpleTagPrivate>(name, value, targetTypeValue,
language, defaultLanguage, trackUid, editionUid, chapterUid, attachmentUid))
{
}
@ -65,7 +84,19 @@ Matroska::SimpleTag::SimpleTag(const String &name, const ByteVector &value,
const String &language, bool defaultLanguage,
unsigned long long trackUid) :
d(std::make_unique<SimpleTagPrivate>(name, value, targetTypeValue,
language, defaultLanguage, trackUid))
language, defaultLanguage, trackUid, 0, 0, 0))
{
}
Matroska::SimpleTag::SimpleTag(const String &name, const ByteVector &value,
TargetTypeValue targetTypeValue,
const String &language, bool defaultLanguage,
unsigned long long trackUid,
unsigned long long editionUid,
unsigned long long chapterUid,
unsigned long long attachmentUid) :
d(std::make_unique<SimpleTagPrivate>(name, value, targetTypeValue,
language, defaultLanguage, trackUid, editionUid, chapterUid, attachmentUid))
{
}
@ -118,6 +149,21 @@ unsigned long long Matroska::SimpleTag::trackUid() const
return d->trackUid;
}
unsigned long long Matroska::SimpleTag::editionUid() const
{
return d->editionUid;
}
unsigned long long Matroska::SimpleTag::chapterUid() const
{
return d->chapterUid;
}
unsigned long long Matroska::SimpleTag::attachmentUid() const
{
return d->attachmentUid;
}
Matroska::SimpleTag::ValueType Matroska::SimpleTag::type() const
{
return std::holds_alternative<ByteVector>(d->value) ? BinaryType : StringType;

View File

@ -60,6 +60,14 @@ namespace TagLib {
const String &language = String(), bool defaultLanguage = true,
unsigned long long trackUid = 0);
/*!
* Construct a string simple tag.
*/
// BIC: merge with constructor above
SimpleTag(const String& name, const String& value, TargetTypeValue targetTypeValue, const String& language,
bool defaultLanguage, unsigned long long trackUid, unsigned long long editionUid,
unsigned long long chapterUid = 0, unsigned long long attachmentUid = 0);
/*!
* Construct a binary simple tag.
*/
@ -68,6 +76,14 @@ namespace TagLib {
const String &language = String(), bool defaultLanguage = true,
unsigned long long trackUid = 0);
/*!
* Construct a binary simple tag.
*/
// BIC: merge with constructor above
SimpleTag(const String& name, const ByteVector& value, TargetTypeValue targetTypeValue, const String& language,
bool defaultLanguage, unsigned long long trackUid, unsigned long long editionUid,
unsigned long long chapterUid = 0, unsigned long long attachmentUid = 0);
/*!
* Construct a simple tag as a copy of \a other.
*/
@ -124,6 +140,24 @@ namespace TagLib {
*/
unsigned long long trackUid() const;
/*!
* Returns the UID that identifies the edition that the tags belong to,
* zero if not defined, the tag applies to all editions
*/
unsigned long long editionUid() const;
/*!
* Returns the UID that identifies the chapter that the tags belong to,
* zero if not defined, the tag applies to all chapters
*/
unsigned long long chapterUid() const;
/*!
* Returns the UID that identifies the attachment that the tags belong to,
* zero if not defined, the tag applies to all attachments
*/
unsigned long long attachmentUid() const;
/*!
* Returns the type of the value.
*/

View File

@ -121,11 +121,21 @@ void Matroska::Tag::removeSimpleTag(unsigned int index)
void Matroska::Tag::removeSimpleTag(const String &name,
SimpleTag::TargetTypeValue targetTypeValue,
unsigned long long trackUid)
{
removeSimpleTag(name, targetTypeValue, trackUid, 0, 0, 0);
}
void Matroska::Tag::removeSimpleTag(const String& name,
SimpleTag::TargetTypeValue targetTypeValue,
unsigned long long trackUid, unsigned long long editionUid,
unsigned long long chapterUid, unsigned long long attachmentUid)
{
const auto it = std::find_if(d->tags.begin(), d->tags.end(),
[&name, targetTypeValue, trackUid](const SimpleTag &t) {
[&name, targetTypeValue, trackUid, editionUid, chapterUid, attachmentUid](
const SimpleTag &t) {
return t.name() == name && t.targetTypeValue() == targetTypeValue &&
t.trackUid() == trackUid;
t.trackUid() == trackUid && t.editionUid() == editionUid &&
t.chapterUid() == chapterUid && t.attachmentUid() == attachmentUid;
}
);
if(it != d->tags.end()) {
@ -260,12 +270,18 @@ ByteVector Matroska::Tag::renderInternal()
for(const auto &tag : std::as_const(d->tags)) {
auto targetTypeValue = tag.targetTypeValue();
auto trackUid = tag.trackUid();
auto editionUid = tag.editionUid();
auto chapterUid = tag.chapterUid();
auto attachmentUid = tag.attachmentUid();
auto it = std::find_if(targetList.begin(),
targetList.end(),
[&](const auto &list) {
const auto &simpleTag = list.front();
return simpleTag.targetTypeValue() == targetTypeValue &&
simpleTag.trackUid() == trackUid;
simpleTag.trackUid() == trackUid &&
simpleTag.editionUid() == editionUid &&
simpleTag.chapterUid() == chapterUid &&
simpleTag.attachmentUid() == attachmentUid;
}
);
if(it == targetList.end()) {
@ -280,6 +296,9 @@ ByteVector Matroska::Tag::renderInternal()
const auto &frontTag = list.front();
const auto targetTypeValue = frontTag.targetTypeValue();
const auto trackUid = frontTag.trackUid();
const auto editionUid = frontTag.editionUid();
const auto chapterUid = frontTag.chapterUid();
const auto attachmentUid = frontTag.attachmentUid();
auto tag = EBML::make_unique_element<EBML::Element::Id::MkTag>();
// Build <Tag Targets> element
@ -294,6 +313,21 @@ ByteVector Matroska::Tag::renderInternal()
element->setValue(trackUid);
targets->appendElement(std::move(element));
}
if(editionUid != 0) {
auto element = EBML::make_unique_element<EBML::Element::Id::MkTagEditionUID>();
element->setValue(editionUid);
targets->appendElement(std::move(element));
}
if(chapterUid != 0) {
auto element = EBML::make_unique_element<EBML::Element::Id::MkTagChapterUID>();
element->setValue(chapterUid);
targets->appendElement(std::move(element));
}
if(attachmentUid != 0) {
auto element = EBML::make_unique_element<EBML::Element::Id::MkTagAttachmentUID>();
element->setValue(attachmentUid);
targets->appendElement(std::move(element));
}
tag->appendElement(std::move(targets));
// Build <Simple Tag> element
@ -446,7 +480,8 @@ String Matroska::Tag::TagPrivate::getTag(const String &key) const
&& t.type() == SimpleTag::StringType
&& (t.targetTypeValue() == targetTypeValue ||
(t.targetTypeValue() == SimpleTag::TargetTypeValue::None && !strict))
&& t.trackUid() == 0;
&& t.trackUid() == 0 && t.editionUid() == 0 && t.chapterUid() == 0
&& t.attachmentUid() == 0;
}
);
return it != tags.end() ? it->toString() : String();
@ -456,7 +491,9 @@ PropertyMap Matroska::Tag::properties() const
{
PropertyMap properties;
for(const auto &simpleTag : std::as_const(d->tags)) {
if(simpleTag.type() == SimpleTag::StringType && simpleTag.trackUid() == 0) {
if(simpleTag.type() == SimpleTag::StringType && simpleTag.trackUid() == 0 &&
simpleTag.editionUid() == 0 && simpleTag.chapterUid() == 0 &&
simpleTag.attachmentUid() == 0) {
if(String key = translateTag(simpleTag.name(), simpleTag.targetTypeValue());
!key.isEmpty())
properties[key].append(simpleTag.toString());
@ -472,7 +509,8 @@ PropertyMap Matroska::Tag::setProperties(const PropertyMap &propertyMap)
// Remove all simple tags which would be returned in properties()
for(auto it = d->tags.begin(); it != d->tags.end();) {
if(it->type() == SimpleTag::StringType &&
it->trackUid() == 0 &&
it->trackUid() == 0 && it->editionUid() == 0 &&
it->chapterUid() == 0 && it->attachmentUid() == 0 &&
!translateTag(it->name(), it->targetTypeValue()).isEmpty()) {
it = d->tags.erase(it);
setNeedsRender(true);
@ -514,7 +552,8 @@ StringList Matroska::Tag::complexPropertyKeys() const
StringList keys;
for(const SimpleTag &t : std::as_const(d->tags)) {
if(t.type() != SimpleTag::StringType ||
t.trackUid() != 0 ||
t.trackUid() != 0 || t.editionUid() != 0 ||
t.chapterUid() != 0 || t.attachmentUid() != 0 ||
translateTag(t.name(), t.targetTypeValue()).isEmpty()) {
keys.append(t.name());
}
@ -529,7 +568,8 @@ List<VariantMap> Matroska::Tag::complexProperties(const String &key) const
for(const SimpleTag &t : std::as_const(d->tags)) {
if(t.name() == key &&
(t.type() != SimpleTag::StringType ||
t.trackUid() != 0 ||
t.trackUid() != 0 || t.editionUid() != 0 ||
t.chapterUid() != 0 || t.attachmentUid() != 0 ||
translateTag(t.name(), t.targetTypeValue()).isEmpty())) {
VariantMap property;
if(t.type() != SimpleTag::StringType) {
@ -545,6 +585,15 @@ List<VariantMap> Matroska::Tag::complexProperties(const String &key) const
if(t.trackUid()) {
property.insert("trackUid", t.trackUid());
}
if(t.editionUid()) {
property.insert("editionUid", t.editionUid());
}
if(t.chapterUid()) {
property.insert("chapterUid", t.chapterUid());
}
if(t.attachmentUid()) {
property.insert("attachmentUid", t.attachmentUid());
}
property.insert("language", t.language());
property.insert("defaultLanguage", t.defaultLanguageFlag());
props.append(property);
@ -564,7 +613,8 @@ bool Matroska::Tag::setComplexProperties(const String &key, const List<VariantMa
[&key](const SimpleTag &t) {
return t.name() == key &&
(t.type() != SimpleTag::StringType ||
t.trackUid() != 0 ||
t.trackUid() != 0 || t.editionUid() != 0 ||
t.chapterUid() != 0 || t.attachmentUid() != 0 ||
translateTag(t.name(), t.targetTypeValue()).isEmpty());
}) > 0) {
setNeedsRender(true);
@ -591,11 +641,16 @@ bool Matroska::Tag::setComplexProperties(const String &key, const List<VariantMa
auto language = property.value("language").value<String>();
const bool defaultLanguage = property.value("defaultLanguage", true).value<bool>();
const auto trackUid = property.value("trackUid", 0ULL).value<unsigned long long>();
const auto editionUid = property.value("editionUid", 0ULL).value<unsigned long long>();
const auto chapterUid = property.value("chapterUid", 0ULL).value<unsigned long long>();
const auto attachmentUid = property.value("attachmentUid", 0ULL).value<unsigned long long>();
d->tags.append(property.contains("data")
? SimpleTag(key, property.value("data").value<ByteVector>(),
targetTypeValue, language, defaultLanguage, trackUid)
targetTypeValue, language, defaultLanguage, trackUid,
editionUid, chapterUid, attachmentUid)
: SimpleTag(key, property.value("value").value<String>(),
targetTypeValue, language, defaultLanguage, trackUid));
targetTypeValue, language, defaultLanguage, trackUid,
editionUid, chapterUid, attachmentUid));
setNeedsRender(true);
result = true;
}

View File

@ -120,6 +120,14 @@ namespace TagLib {
void removeSimpleTag(const String &name, SimpleTag::TargetTypeValue targetTypeValue,
unsigned long long trackUid = 0);
/*!
* Remove a tag attribute.
*/
// BIC: Merge with the method above
void removeSimpleTag(const String &name, SimpleTag::TargetTypeValue targetTypeValue,
unsigned long long trackUid, unsigned long long editionUid,
unsigned long long chapterUid = 0, unsigned long long attachmentUid = 0);
/*!
* Remove all tag attributes.
*/

View File

@ -220,7 +220,8 @@ public:
CPPUNIT_ASSERT(tag->isEmpty());
tag->addSimpleTag(Matroska::SimpleTag(
"Test Name 2", String("Test Value 2"),
Matroska::SimpleTag::TargetTypeValue::Album));
Matroska::SimpleTag::TargetTypeValue::Album,
{}, true, 0x72ac, 0xed17, 0xca97, 0xa7ac));
tag->insertSimpleTag(0, Matroska::SimpleTag(
"Test Name 1", String("Test Value 1"),
Matroska::SimpleTag::TargetTypeValue::Track, "en"));
@ -263,6 +264,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[0].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[0].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[0].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[0].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[0].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[0].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[0].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[1].language());
@ -272,6 +276,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[1].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[1].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[1].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[2].language());
@ -281,6 +288,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[2].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[2].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[2].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[3].language());
@ -290,6 +300,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[3].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[3].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[3].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[4].language());
@ -298,7 +311,10 @@ public:
CPPUNIT_ASSERT_EQUAL(ByteVector(), simpleTags[4].toByteVector());
CPPUNIT_ASSERT_EQUAL(true, simpleTags[4].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Album, simpleTags[4].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[4].trackUid());
CPPUNIT_ASSERT_EQUAL(0x72acULL, simpleTags[4].trackUid());
CPPUNIT_ASSERT_EQUAL(0xed17ULL, simpleTags[4].editionUid());
CPPUNIT_ASSERT_EQUAL(0xca97ULL, simpleTags[4].chapterUid());
CPPUNIT_ASSERT_EQUAL(0xa7acULL, simpleTags[4].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[4].type());
const auto &attachedFiles = attachments->attachedFileList();
@ -315,7 +331,6 @@ public:
expectedProps["DATE"] = StringList("1969");
expectedProps["TEST NAME 1"] = StringList("Test Value 1");
expectedProps["TITLE"] = StringList("Test title");
expectedProps.addUnsupportedData("Test Name 2");
auto props = f.properties();
if (expectedProps != props) {
CPPUNIT_ASSERT_EQUAL(expectedProps.toString(), props.toString());
@ -341,6 +356,10 @@ public:
{"name", "Test Name 2"},
{"value", "Test Value 2"},
{"targetTypeValue", 50},
{"trackUid", 0x72acULL},
{"editionUid", 0xed17ULL},
{"chapterUid", 0xca97ULL},
{"attachmentUid", 0xa7acULL},
};
auto complexProps = f.complexProperties("Test Name 2");
CPPUNIT_ASSERT(List<VariantMap>({expectedComplexProps}) == complexProps);
@ -577,6 +596,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[0].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::None, simpleTags[0].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(9584013959154292683ULL, simpleTags[0].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[0].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[0].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[0].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[0].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[1].language());
@ -586,6 +608,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[1].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[1].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[1].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[1].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[2].language());
@ -595,6 +620,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[2].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[2].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[2].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[2].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[3].language());
@ -604,6 +632,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[3].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[3].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[3].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[3].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[4].language());
@ -613,6 +644,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[4].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[4].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[4].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[4].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[4].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[4].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[4].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[5].language());
@ -622,6 +656,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[5].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[5].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[5].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[5].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[5].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[5].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[5].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[6].language());
@ -631,6 +668,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[6].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[6].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[6].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[6].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[6].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[6].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[6].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[7].language());
@ -640,6 +680,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[7].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[7].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[7].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[7].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[7].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[7].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[7].type());
CPPUNIT_ASSERT_EQUAL(String("und"), simpleTags[8].language());
@ -649,6 +692,9 @@ public:
CPPUNIT_ASSERT_EQUAL(true, simpleTags[8].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Album, simpleTags[8].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[8].trackUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[8].editionUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[8].chapterUid());
CPPUNIT_ASSERT_EQUAL(0ULL, simpleTags[8].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[8].type());
auto props = f.properties();
@ -817,6 +863,9 @@ public:
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("name").value<String>(), simpleTags[0].name());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("defaultLanguage").value<bool>(), simpleTags[0].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("trackUid").value<unsigned long long>(), simpleTags[0].trackUid());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("editionUid").value<unsigned long long>(), simpleTags[0].editionUid());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("chapterUid").value<unsigned long long>(), simpleTags[0].chapterUid());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("attachmentUid").value<unsigned long long>(), simpleTags[0].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::None, simpleTags[0].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(ByteVector(), simpleTags[0].toByteVector());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[0].type());
@ -844,6 +893,9 @@ public:
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("name").value<String>(), simpleTags[0].name());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("defaultLanguage").value<bool>(), simpleTags[0].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("trackUid").value<unsigned long long>(), simpleTags[0].trackUid());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("editionUid").value<unsigned long long>(), simpleTags[0].editionUid());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("chapterUid").value<unsigned long long>(), simpleTags[0].chapterUid());
CPPUNIT_ASSERT_EQUAL(trackUidTag.value("attachmentUid").value<unsigned long long>(), simpleTags[0].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::None, simpleTags[0].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(ByteVector(), simpleTags[0].toByteVector());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[0].type());
@ -853,6 +905,9 @@ public:
CPPUNIT_ASSERT_EQUAL(targetTypeTag.value("name").value<String>(), simpleTags[1].name());
CPPUNIT_ASSERT_EQUAL(targetTypeTag.value("defaultLanguage").value<bool>(), simpleTags[1].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(targetTypeTag.value("trackUid").value<unsigned long long>(), simpleTags[1].trackUid());
CPPUNIT_ASSERT_EQUAL(targetTypeTag.value("editionUid").value<unsigned long long>(), simpleTags[1].editionUid());
CPPUNIT_ASSERT_EQUAL(targetTypeTag.value("chapterUid").value<unsigned long long>(), simpleTags[1].chapterUid());
CPPUNIT_ASSERT_EQUAL(targetTypeTag.value("attachmentUid").value<unsigned long long>(), simpleTags[1].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Subtrack, simpleTags[1].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(ByteVector(), simpleTags[1].toByteVector());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::StringType, simpleTags[1].type());
@ -862,6 +917,9 @@ public:
CPPUNIT_ASSERT_EQUAL(binaryTag.value("name").value<String>(), simpleTags[2].name());
CPPUNIT_ASSERT_EQUAL(binaryTag.value("defaultLanguage").value<bool>(), simpleTags[2].defaultLanguageFlag());
CPPUNIT_ASSERT_EQUAL(binaryTag.value("trackUid").value<unsigned long long>(), simpleTags[2].trackUid());
CPPUNIT_ASSERT_EQUAL(binaryTag.value("editionUid").value<unsigned long long>(), simpleTags[2].editionUid());
CPPUNIT_ASSERT_EQUAL(binaryTag.value("chapterUid").value<unsigned long long>(), simpleTags[2].chapterUid());
CPPUNIT_ASSERT_EQUAL(binaryTag.value("attachmentUid").value<unsigned long long>(), simpleTags[2].attachmentUid());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::TargetTypeValue::Track, simpleTags[2].targetTypeValue());
CPPUNIT_ASSERT_EQUAL(String(), simpleTags[2].toString());
CPPUNIT_ASSERT_EQUAL(Matroska::SimpleTag::ValueType::BinaryType, simpleTags[2].type());