4#include "../diagnostics.h"
6#include <initializer_list>
8#include <unordered_map>
22 using namespace MatroskaTagIds;
25 return std::string(
artist());
27 return std::string(
album());
35 return std::string(
title());
37 return std::string(
genre());
47 return std::string(
bpm());
49 return std::string(
bps());
51 return std::string(
rating());
55 return std::string(
lyrics());
57 return std::string(
label());
59 return std::string(
actor());
75 using namespace MatroskaTagIds;
76 static const std::unordered_map<std::string_view, KnownField> fieldMap({
124 static const string context(
"parsing Matroska tag");
126 tagElement.
parse(diag);
127 if (tagElement.
totalSize() > numeric_limits<std::uint32_t>::max()) {
135 switch (child->id()) {
139 field.reparse(*child, diag,
true);
141 auto normalizedId = field.id();
144 field.id() = std::move(normalizedId);
147 fields().emplace(field.id(), std::move(field));
153 parseTargets(*child, diag);
168 static const string context(
"parsing targets of Matroska tag");
170 bool targetTypeValueFound =
false;
171 bool targetTypeFound =
false;
172 targetsElement.
parse(diag);
176 }
catch (
const Failure &) {
177 diag.emplace_back(
DiagLevel::Critical,
"Unable to parse children of Targets element.", context);
180 switch (child->id()) {
182 if (!targetTypeValueFound) {
184 targetTypeValueFound =
true;
187 DiagLevel::Warning,
"Targets element contains multiple TargetTypeValue elements. Surplus elements will be ignored.", context);
191 if (!targetTypeFound) {
193 targetTypeFound =
true;
196 DiagLevel::Warning,
"Targets element contains multiple TargetType elements. Surplus elements will be ignored.", context);
212 diag.emplace_back(
DiagLevel::Warning,
"Targets element contains unknown element. It will be ignored.", context);
231MatroskaTagMaker::MatroskaTagMaker(MatroskaTag &tag, Diagnostics &diag)
236 if (m_tag.target().level() != 50) {
240 if (!m_tag.target().levelName().empty()) {
244 for (
const auto &v : initializer_list<vector<std::uint64_t>>{
245 m_tag.target().tracks(), m_tag.target().editions(), m_tag.target().chapters(), m_tag.target().attachments() }) {
253 m_maker.reserve(m_tag.fields().size());
254 m_simpleTagsSize = 0;
255 for (
auto &pair : m_tag.fields()) {
256 if (pair.second.value().isNull()) {
260 m_maker.emplace_back(pair.second.prepareMaking(diag));
261 m_simpleTagsSize += m_maker.back().requiredSize();
262 }
catch (
const Failure &) {
265 m_tagSize += m_simpleTagsSize;
281 stream.write(buff, 2);
283 stream.write(buff, len);
286 stream.write(buff, 2);
288 stream.write(buff, len);
290 if (t.
level() != 50) {
293 stream.write(buff, 2);
295 stream.put(
static_cast<char>(0x80 | len));
296 stream.write(buff, len);
301 stream.write(buff, 2);
303 stream.write(buff, len);
304 stream.write(t.
levelName().c_str(),
static_cast<std::streamsize
>(t.
levelName().size()));
307 using p = pair<std::uint16_t, vector<std::uint64_t>>;
310 if (!pair.second.empty()) {
311 BE::getBytes(pair.first, buff);
312 for (
auto uid : pair.second) {
314 *(buff + 2) =
static_cast<char>(0x80 | len);
315 stream.write(buff, 3 + len);
320 for (
const auto &maker : m_maker) {
The Diagnostics class is a container for DiagMessage.
The EbmlElement class helps to parse EBML files such as Matroska files.
static std::uint8_t makeUInteger(std::uint64_t value, char *buff)
Writes value to buff.
static std::uint8_t calculateSizeDenotationLength(std::uint64_t size)
Returns the length of the size denotation for the specified size in byte.
static std::uint8_t makeSizeDenotation(std::uint64_t size, char *buff)
Makes the size denotation for the specified size and stores it to buff.
static std::uint8_t calculateUIntegerLength(std::uint64_t integer)
Returns the length of the specified unsigned integer in byte.
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
typename FieldMapBasedTagTraits< MatroskaTag >::FieldType::IdentifierType IdentifierType
const std::multimap< IdentifierType, FieldType, Compare > & fields() const
Returns the fields of the tag by providing direct access to the field map of the tag.
KnownField knownField(const IdentifierType &id) const
Returns the field for the specified ID.
ImplementationType * nextSibling()
Returns the next sibling of the element.
ImplementationType * firstChild()
Returns the first child of the element.
std::uint64_t totalSize() const
Returns the total size of the element.
void parse(Diagnostics &diag)
Parses the header information of the element which is read from the related stream at the start offse...
The MatroskaTagField class is used by MatroskaTag to store the fields.
static void normalizeId(std::string &id)
Ensures the specified id is upper-case as recommended by the Matroska spec.
void make(std::ostream &stream) const
Saves the tag (specified when constructing the object) to the specified stream (makes a "Tag"-element...
void parse(EbmlElement &tagElement, Diagnostics &diag)
Parses tag information from the specified tagElement.
void parse2(EbmlElement &tagElement, MatroskaTagFlags flags, Diagnostics &diag)
Parses tag information from the specified tagElement.
IdentifierType internallyGetFieldId(KnownField field) const
KnownField internallyGetKnownField(const IdentifierType &id) const
This exception is thrown when the an operation is invoked that has not been implemented yet.
The TagTarget class specifies the target of a tag.
const IdContainerType & tracks() const
Returns the tracks.
const IdContainerType & chapters() const
Returns the chapters.
std::uint64_t level() const
Returns the level.
const std::string & levelName() const
Returns the level name.
const IdContainerType & editions() const
Returns the editions.
void clear()
Clears the TagTarget.
const IdContainerType & attachments() const
Returns the attachments.
void setLevel(std::uint64_t level)
Sets the level.
void setLevelName(const std::string &levelName)
Sets the level name.
const TagTarget & target() const
Returns the target of tag.
constexpr TAG_PARSER_EXPORT std::string_view bps()
constexpr TAG_PARSER_EXPORT std::string_view rating()
constexpr TAG_PARSER_EXPORT std::string_view album()
constexpr TAG_PARSER_EXPORT std::string_view encoderSettings()
constexpr TAG_PARSER_EXPORT std::string_view description()
constexpr TAG_PARSER_EXPORT std::string_view title()
constexpr TAG_PARSER_EXPORT std::string_view comment()
constexpr TAG_PARSER_EXPORT std::string_view language()
constexpr TAG_PARSER_EXPORT std::string_view actor()
constexpr TAG_PARSER_EXPORT std::string_view composer()
constexpr TAG_PARSER_EXPORT std::string_view partNumber()
constexpr TAG_PARSER_EXPORT std::string_view bpm()
constexpr TAG_PARSER_EXPORT std::string_view genre()
constexpr TAG_PARSER_EXPORT std::string_view duration()
constexpr TAG_PARSER_EXPORT std::string_view artist()
constexpr TAG_PARSER_EXPORT std::string_view lyrics()
constexpr TAG_PARSER_EXPORT std::string_view encoder()
constexpr TAG_PARSER_EXPORT std::string_view dateRelease()
constexpr TAG_PARSER_EXPORT std::string_view totalParts()
constexpr TAG_PARSER_EXPORT std::string_view dateRecorded()
constexpr TAG_PARSER_EXPORT std::string_view lyricist()
Contains all classes and functions of the TagInfo library.
KnownField
Specifies the field.
MatroskaTagFlags
The MatroskaTagFlags enum specifies flags which controls parsing and making of Matroska tags.