From 6342f00e8bd4eda5c12305abb9b30f0c91c2fa54 Mon Sep 17 00:00:00 2001 From: complexlogic Date: Sun, 8 Oct 2023 08:11:01 -0700 Subject: [PATCH] Support tag language --- examples/matroskareader.cpp | 2 ++ examples/matroskawriter.cpp | 1 + taglib/matroska/ebml/ebmlelement.h | 22 ++++++++++++---------- taglib/matroska/ebml/ebmlmktags.cpp | 9 +++++++++ taglib/matroska/matroskasimpletag.cpp | 22 ++++++++++++++++++++++ taglib/matroska/matroskasimpletag.h | 6 +++++- taglib/matroska/matroskatag.cpp | 15 +++++++++++++-- 7 files changed, 64 insertions(+), 13 deletions(-) diff --git a/examples/matroskareader.cpp b/examples/matroskareader.cpp index e1b6045b..66993e9e 100644 --- a/examples/matroskareader.cpp +++ b/examples/matroskareader.cpp @@ -44,6 +44,8 @@ int main(int argc, char *argv[]) PRINT_PRETTY("Target Type Value", targetTypeValue == 0 ? "None" : TagLib::Utils::formatString("%i", targetTypeValue).toCString(false) ); + const TagLib::String &language = t->language(); + PRINT_PRETTY("Language", !language.isEmpty() ? language.toCString(false) : "Not set"); printf("\n"); } diff --git a/examples/matroskawriter.cpp b/examples/matroskawriter.cpp index 0ad1f929..637876f6 100644 --- a/examples/matroskawriter.cpp +++ b/examples/matroskawriter.cpp @@ -23,6 +23,7 @@ int main(int argc, char *argv[]) simpleTag->setName("Test Name 1"); simpleTag->setTargetTypeValue(TagLib::Matroska::SimpleTag::TargetTypeValue::Track); simpleTag->setValue("Test Value 1"); + simpleTag->setLanguage("en"); tag->addSimpleTag(simpleTag); simpleTag = new TagLib::Matroska::SimpleTagString(); diff --git a/taglib/matroska/ebml/ebmlelement.h b/taglib/matroska/ebml/ebmlelement.h index 0338659e..74efc3fd 100644 --- a/taglib/matroska/ebml/ebmlelement.h +++ b/taglib/matroska/ebml/ebmlelement.h @@ -59,16 +59,18 @@ namespace TagLib { }; namespace ElementIDs { - inline constexpr Element::Id EBMLHeader = 0x1A45DFA3; - inline constexpr Element::Id MkSegment = 0x18538067; - inline constexpr Element::Id MkTags = 0x1254C367; - inline constexpr Element::Id MkTag = 0x7373; - inline constexpr Element::Id MkTagTargets = 0x63C0; - inline constexpr Element::Id MkTagTargetTypeValue = 0x68CA; - inline constexpr Element::Id MkSimpleTag = 0x67C8; - inline constexpr Element::Id MkTagName = 0x45A3; - inline constexpr Element::Id MkTagLanguage = 0x447A; - inline constexpr Element::Id MkTagString = 0x4487; + inline constexpr Element::Id EBMLHeader = 0x1A45DFA3; + inline constexpr Element::Id MkSegment = 0x18538067; + inline constexpr Element::Id MkTags = 0x1254C367; + inline constexpr Element::Id MkTag = 0x7373; + inline constexpr Element::Id MkTagTargets = 0x63C0; + inline constexpr Element::Id MkTagTargetTypeValue = 0x68CA; + inline constexpr Element::Id MkSimpleTag = 0x67C8; + inline constexpr Element::Id MkTagName = 0x45A3; + inline constexpr Element::Id MkTagLanguage = 0x447A; + inline constexpr Element::Id MkTagString = 0x4487; + inline constexpr Element::Id MkTagsTagLanguage = 0x447A; + inline constexpr Element::Id MkTagsLanguageDefault = 0x4484; } } } diff --git a/taglib/matroska/ebml/ebmlmktags.cpp b/taglib/matroska/ebml/ebmlmktags.cpp index ae2db490..bfc3e606 100644 --- a/taglib/matroska/ebml/ebmlmktags.cpp +++ b/taglib/matroska/ebml/ebmlmktags.cpp @@ -71,6 +71,8 @@ Matroska::Tag* EBML::MkTags::parse() const String *tagName = nullptr; const String *tagValueString = nullptr; const ByteVector *tagValueBinary = nullptr; + const String *language = nullptr; + bool defaultLanguageFlag = true; for (auto simpleTagChild : *simpleTag) { Id id = simpleTagChild->getId(); @@ -78,6 +80,10 @@ Matroska::Tag* EBML::MkTags::parse() tagName = &(static_cast(simpleTagChild)->getValue()); else if (id == ElementIDs::MkTagString && !tagValueString) tagValueString = &(static_cast(simpleTagChild)->getValue()); + else if (id == ElementIDs::MkTagsTagLanguage && !language) + language = &(static_cast(simpleTagChild)->getValue()); + else if (id == ElementIDs::MkTagsLanguageDefault) + defaultLanguageFlag = static_cast(simpleTagChild)->getValue() ? true : false; } if (!tagName || (tagValueString && tagValueBinary) || (!tagValueString && !tagValueBinary)) continue; @@ -97,6 +103,9 @@ Matroska::Tag* EBML::MkTags::parse() sTag = sTagBinary; } sTag->setName(*tagName); + if (language) + sTag->setLanguage(*language); + sTag->setDefaultLanguageFlag(defaultLanguageFlag); mTag->addSimpleTag(sTag); } } diff --git a/taglib/matroska/matroskasimpletag.cpp b/taglib/matroska/matroskasimpletag.cpp index 47cf0307..49094fc6 100644 --- a/taglib/matroska/matroskasimpletag.cpp +++ b/taglib/matroska/matroskasimpletag.cpp @@ -31,6 +31,8 @@ class Matroska::SimpleTag::SimpleTagPrivate SimpleTagPrivate() = default; SimpleTag::TargetTypeValue targetTypeValue = TargetTypeValue::None; String name; + String language; + bool defaultLanguageFlag = true; }; @@ -73,6 +75,26 @@ const String& Matroska::SimpleTag::name() const return d->name; } +const String& Matroska::SimpleTag::language() const +{ + return d->language; +} + +void Matroska::SimpleTag::setLanguage(const String &language) +{ + d->language = language; +} + +bool Matroska::SimpleTag::defaultLanguageFlag() const +{ + return d->defaultLanguageFlag; +} + +void Matroska::SimpleTag::setDefaultLanguageFlag(bool flag) +{ + d->defaultLanguageFlag = flag; +} + void Matroska::SimpleTag::setName(const String &name) { d->name = name; diff --git a/taglib/matroska/matroskasimpletag.h b/taglib/matroska/matroskasimpletag.h index 4cdafc7b..74553a97 100644 --- a/taglib/matroska/matroskasimpletag.h +++ b/taglib/matroska/matroskasimpletag.h @@ -44,8 +44,12 @@ namespace TagLib { }; const String& name() const; TargetTypeValue targetTypeValue() const; - void setTargetTypeValue(TargetTypeValue targetTypeValue); + const String& language() const; + bool defaultLanguageFlag() const; void setName(const String &name); + void setTargetTypeValue(TargetTypeValue targetTypeValue); + void setLanguage(const String &language); + void setDefaultLanguageFlag(bool flag); virtual ~SimpleTag(); private: diff --git a/taglib/matroska/matroskatag.cpp b/taglib/matroska/matroskatag.cpp index 1fa2e0ea..31113faf 100644 --- a/taglib/matroska/matroskatag.cpp +++ b/taglib/matroska/matroskatag.cpp @@ -210,7 +210,7 @@ ByteVector Matroska::Tag::render() auto targetTypeValue = frontTag->targetTypeValue(); auto tag = new EBML::MasterElement(EBML::ElementIDs::MkTag); - // Build + // Build element auto targets = new EBML::MasterElement(EBML::ElementIDs::MkTagTargets); if (targetTypeValue != Matroska::SimpleTag::TargetTypeValue::None) { auto element = new EBML::UIntElement(EBML::ElementIDs::MkTagTargetTypeValue); @@ -226,6 +226,7 @@ ByteVector Matroska::Tag::render() tagName->setValue(simpleTag->name()); t->appendElement(tagName); + // Tag Value Matroska::SimpleTagString *tStr = nullptr; Matroska::SimpleTagBinary *tBin = nullptr; if((tStr = dynamic_cast(simpleTag))) { @@ -237,7 +238,17 @@ ByteVector Matroska::Tag::render() // Todo } - // Todo: language + // Language + auto language = new EBML::Latin1StringElement(EBML::ElementIDs::MkTagsTagLanguage); + const String &lang = simpleTag->language(); + language->setValue(!lang.isEmpty() ? lang : "und"); + t->appendElement(language); + + // Default language flag + auto dlf = new EBML::UIntElement(EBML::ElementIDs::MkTagsLanguageDefault); + dlf->setValue(simpleTag->defaultLanguageFlag() ? 1 : 0); + t->appendElement(dlf); + tag->appendElement(t); } tags.appendElement(tag);