Tag Parser
9.0.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
|
Go to the documentation of this file.
5 #include "../exceptions.h"
7 #include <c++utilities/io/binarywriter.h>
24 MatroskaTagField::MatroskaTagField()
31 MatroskaTagField::MatroskaTagField(
const string &
id,
const TagValue &value)
48 string context(
"parsing Matroska tag field");
49 simpleTagElement.
parse(diag);
50 bool tagDefaultFound =
false;
55 diag.emplace_back(
DiagLevel::Critical,
"Unable to parse children of \"SimpleTag\"-element.", context);
58 switch (child->id()) {
61 setId(child->readString());
62 context =
"parsing Matroska tag field " +
id();
65 "\"SimpleTag\"-element contains multiple \"TagName\"-elements. Surplus TagName elements will be ignored.", context);
70 if (
value().isEmpty()) {
71 unique_ptr<char[]> buffer = make_unique<char[]>(child->dataSize());
72 child->stream().seekg(static_cast<streamoff>(child->dataOffset()));
73 child->stream().read(buffer.get(), static_cast<streamoff>(child->dataSize()));
74 switch (child->id()) {
84 "\"SimpleTag\"-element contains multiple \"TagString\"/\"TagBinary\"-elements. Surplus \"TagName\"/\"TagBinary\"-elements will "
91 string lng = child->readString();
97 "\"SimpleTag\"-element contains multiple \"TagLanguage\"-elements. Surplus \"TagLanguage\"-elements will be ignored.", context);
101 if (!tagDefaultFound) {
103 tagDefaultFound =
true;
106 "\"SimpleTag\"-element contains multiple \"TagDefault\" elements. Surplus \"TagDefault\"-elements will be ignored.", context);
110 if (parseNestedFields) {
115 "Nested fields are currently not supported. Nested tags can not be displayed and will be discarded when rewriting the file.",
125 "\"SimpleTag\"-element contains unknown element ", child->idToString(),
" at ", child->startOffset(),
". It will be ignored."),
143 static const string context(
"making Matroska \"SimpleTag\" element.");
146 diag.emplace_back(
DiagLevel::Critical,
"Can not make \"SimpleTag\" element with empty \"TagName\".", context);
151 }
catch (
const ConversionException &) {
152 diag.emplace_back(
DiagLevel::Critical,
"The assigned tag value can not be converted to be written appropriately.", context);
184 m_stringValue = m_field.value().toString();
185 }
catch (
const ConversionException &) {
187 "The assigned tag value can not be converted to a string and is treated as binary value (which is likely not what you want since "
188 "official Matroska specifiecation doesn't list any binary fields).",
189 "making Matroska \"SimpleTag\" element.");
192 size_t languageSize = m_field.value().language().size();
199 + m_field.id().size()
210 m_nestedMaker.emplace_back(nestedField.prepareMaking(diag));
211 m_simpleTagSize += m_nestedMaker.back().m_totalSize;
225 BinaryWriter writer(&stream);
230 stream.write(buff, sizeDenotationLen);
234 stream.write(buff, sizeDenotationLen);
235 stream.write(m_field.
id().c_str(), m_field.
id().size());
239 stream.put(static_cast<ostream::char_type>(0x80 | 3));
240 stream.write(
"und", 3);
243 stream.write(buff, sizeDenotationLen);
248 stream.put(static_cast<ostream::char_type>(0x80 | 1));
254 stream.write(buff, sizeDenotationLen);
259 stream.write(buff, sizeDenotationLen);
260 stream.write(m_stringValue.data(), m_stringValue.size());
263 for (
const auto &maker : m_nestedMaker) {
MatroskaTagFieldMaker prepareMaking(Diagnostics &diag)
Prepares making.
static std::uint8_t calculateSizeDenotationLength(std::uint64_t size)
Returns the length of the size denotation for the specified size in byte.
void make(std::ostream &stream) const
Saves the field (specified when constructing the object) to the specified stream (makes a "SimpleTag"...
The MatroskaTagFieldMaker class helps making tag fields. It allows to calculate the required size.
The Diagnostics class is a container for DiagMessage.
Contains all classes and functions of the TagInfo library.
const IdentifierType & id() const
Returns the id of the current TagField.
void parse(Diagnostics &diag)
Parses the header information of the element which is read from the related stream at the start offse...
constexpr const TAG_PARSER_EXPORT char * language()
ImplementationType * firstChild()
Returns the first child of the element.
The TagField class is used by FieldMapBasedTag to store the fields.
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
static std::uint8_t makeSizeDenotation(std::uint64_t size, char *buff)
Makes the size denotation for the specified size and stores it to buff.
TagValue & value()
Returns the value of the current TagField.
The EbmlElement class helps to parse EBML files such as Matroska files.
The MatroskaTagField class is used by MatroskaTag to store the fields.
char * dataPointer()
Returns a pointer to the raw data assigned to the current instance.
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
The TagValue class wraps values of different types. It is meant to be assigned to a tag field.
void make(std::ostream &stream, Diagnostics &diag)
Saves the field to the specified stream (makes a "SimpleTag" element).
const std::vector< MatroskaTagField > & nestedFields() const
Returns the nested fields.
void setId(const IdentifierType &id)
Sets the id of the current Tag Field.
void setDefault(bool isDefault)
Sets whether the field is labeled as default.
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
bool isDefault() const
Returns an indication whether the field is labeled as default.
void setLanguage(const std::string &language)
Sets the language.
const std::string & language() const
Returns the language.
void reparse(EbmlElement &simpleTagElement, Diagnostics &diag, bool parseNestedFields=true)
Parses field information from the specified EbmlElement.