4 #include "../diagnostics.h" 6 #include <initializer_list> 22 using namespace MatroskaTagIds;
30 case KnownField::RecordDate:
38 case KnownField::PartNumber:
40 case KnownField::TotalParts:
44 case KnownField::EncoderSettings:
64 case KnownField::Length:
66 case KnownField::Language:
73 KnownField MatroskaTag::internallyGetKnownField(
const IdentifierType &
id)
const 75 using namespace MatroskaTagIds;
76 static const map<string, KnownField> map({
88 {
bps(), KnownField::Bps },
97 {
language(), KnownField::Language },
101 }
catch (
const out_of_range &) {
102 return KnownField::Invalid;
115 static const string context(
"parsing Matroska tag");
116 tagElement.
parse(diag);
120 switch (child->id()) {
124 field.
reparse(*child, diag,
true);
125 fields().emplace(field.
id(), move(field));
130 parseTargets(*child, diag);
162 prepareMaking(diag).make(stream);
174 static const string context(
"parsing targets of Matroska tag");
176 bool targetTypeValueFound =
false;
177 bool targetTypeFound =
false;
178 targetsElement.
parse(diag);
182 }
catch (
const Failure &) {
183 diag.emplace_back(DiagLevel::Critical,
"Unable to parse childs of Targets element.", context);
186 switch (child->id()) {
188 if (!targetTypeValueFound) {
189 m_target.setLevel(child->readUInteger());
190 targetTypeValueFound =
true;
193 DiagLevel::Warning,
"Targets element contains multiple TargetTypeValue elements. Surplus elements will be ignored.", context);
197 if (!targetTypeFound) {
198 m_target.setLevelName(child->readString());
199 targetTypeFound =
true;
202 DiagLevel::Warning,
"Targets element contains multiple TargetType elements. Surplus elements will be ignored.", context);
206 m_target.tracks().emplace_back(child->readUInteger());
209 m_target.editions().emplace_back(child->readUInteger());
212 m_target.chapters().emplace_back(child->readUInteger());
215 m_target.attachments().emplace_back(child->readUInteger());
218 diag.emplace_back(DiagLevel::Warning,
"Targets element contains unknown element. It will be ignored.", context);
221 if (!m_target.level()) {
222 m_target.setLevel(50);
237 MatroskaTagMaker::MatroskaTagMaker(MatroskaTag &tag, Diagnostics &diag)
242 if (m_tag.target().level() != 50) {
246 if (!m_tag.target().levelName().empty()) {
250 for (
const auto &v : initializer_list<vector<uint64>>{
251 m_tag.target().tracks(), m_tag.target().editions(), m_tag.target().chapters(), m_tag.target().attachments() }) {
259 m_maker.reserve(m_tag.fields().size());
260 m_simpleTagsSize = 0;
261 for (
auto &pair : m_tag.fields()) {
263 m_maker.emplace_back(pair.second.prepareMaking(diag));
264 m_simpleTagsSize += m_maker.back().requiredSize();
265 }
catch (
const Failure &) {
268 m_tagSize += m_simpleTagsSize;
284 stream.write(buff, 2);
286 stream.write(buff, len);
289 stream.write(buff, 2);
291 stream.write(buff, len);
293 if (t.
level() != 50) {
296 stream.write(buff, 2);
298 stream.put(0x80 | len);
299 stream.write(buff, len);
304 stream.write(buff, 2);
306 stream.write(buff, len);
310 typedef pair<uint16, vector<uint64>> p;
313 if (!pair.second.empty()) {
314 BE::getBytes(pair.first, buff);
315 for (
auto uid : pair.second) {
317 *(buff + 2) = 0x80 | len;
318 stream.write(buff, 3 + len);
323 for (
const auto &maker : m_maker) {
TAG_PARSER_EXPORT const char * composer()
TAG_PARSER_EXPORT const char * language()
FieldMapBasedTagTraits< MatroskaTag >::FieldType::IdentifierType IdentifierType
TAG_PARSER_EXPORT const char * description()
TAG_PARSER_EXPORT const char * lyricist()
TAG_PARSER_EXPORT const char * encoderSettings()
TAG_PARSER_EXPORT const char * genre()
const IdContainerType & attachments() const
Returns the attachments.
ImplementationType * firstChild()
Returns the first child of the element.
TAG_PARSER_EXPORT const char * dateRelease()
TAG_PARSER_EXPORT const char * rating()
static byte calculateSizeDenotationLength(uint64 size)
Returns the length of the size denotation for the specified size in byte.
uint64 level() const
Returns the level.
TAG_PARSER_EXPORT const char * lyrics()
KnownField
Specifies the field.
TAG_PARSER_EXPORT const char * comment()
TAG_PARSER_EXPORT const char * partNumber()
static byte calculateUIntegerLength(uint64 integer)
Returns the length of the specified unsigned integer in byte.
uint64 totalSize() const
Returns the total size of the element.
const TagTarget & target() const
Returns the target of tag.
TAG_PARSER_EXPORT const char * totalParts()
void parse(Diagnostics &diag)
Parses the header information of the element which is read from the related stream at the start offse...
static byte makeUInteger(uint64 value, char *buff)
Writes value to buff.
static byte makeSizeDenotation(uint64 size, char *buff)
Makes the size denotation for the specified size and stores it to buff.
TAG_PARSER_EXPORT const char * artist()
const IdentifierType & id() const
Returns the id of the current TagField.
TAG_PARSER_EXPORT const char * encoder()
TAG_PARSER_EXPORT const char * album()
TAG_PARSER_EXPORT const char * duration()
void make(std::ostream &stream) const
Saves the tag (specified when constructing the object) to the specified stream (makes a "Tag"-element...
const IdContainerType & tracks() const
Returns the tracks.
TAG_PARSER_EXPORT const char * dateRecorded()
TAG_PARSER_EXPORT const char * bps()
TAG_PARSER_EXPORT const char * actor()
const std::string & levelName() const
Returns the level name.
const IdContainerType & editions() const
Returns the editions.
const IdContainerType & chapters() const
Returns the chapters.
TAG_PARSER_EXPORT const char * title()
void reparse(EbmlElement &simpleTagElement, Diagnostics &diag, bool parseNestedFields=true)
Parses field information from the specified EbmlElement.
TAG_PARSER_EXPORT const char * bpm()