Tag Parser  9.3.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
mp4tagfield.cpp
Go to the documentation of this file.
1 #include "./mp4tagfield.h"
2 #include "./mp4atom.h"
3 #include "./mp4container.h"
4 #include "./mp4ids.h"
5 
6 #include "../exceptions.h"
7 
8 #include <c++utilities/conversion/stringbuilder.h>
9 #include <c++utilities/io/binaryreader.h>
10 #include <c++utilities/io/binarywriter.h>
11 
12 #include <algorithm>
13 #include <limits>
14 #include <memory>
15 
16 using namespace std;
17 using namespace CppUtilities;
18 
19 namespace TagParser {
20 
29 Mp4TagField::Mp4TagField()
30  : m_parsedRawDataType(RawDataType::Reserved)
31  , m_countryIndicator(0)
32  , m_langIndicator(0)
33 {
34 }
35 
39 Mp4TagField::Mp4TagField(IdentifierType id, const TagValue &value)
40  : TagField<Mp4TagField>(id, value)
41  , m_parsedRawDataType(RawDataType::Reserved)
42  , m_countryIndicator(0)
43  , m_langIndicator(0)
44 {
45 }
46 
56 Mp4TagField::Mp4TagField(const string &mean, const string &name, const TagValue &value)
57  : Mp4TagField(Mp4TagAtomIds::Extended, value)
58 {
59  m_name = name;
60  m_mean = mean;
61 }
62 
73 void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
74 {
75  // prepare reparsing
76  using namespace Mp4AtomIds;
77  using namespace Mp4TagAtomIds;
78  string context("parsing MP4 tag field");
79  ilstChild.parse(diag); // ensure child has been parsed
80  setId(ilstChild.id());
81  context = "parsing MP4 tag field " + ilstChild.idToString();
82  iostream &stream = ilstChild.stream();
83  BinaryReader &reader = ilstChild.container().reader();
84  int dataAtomFound = 0, meanAtomFound = 0, nameAtomFound = 0;
85  for (Mp4Atom *dataAtom = ilstChild.firstChild(); dataAtom; dataAtom = dataAtom->nextSibling()) {
86  try {
87  dataAtom->parse(diag);
88  if (dataAtom->id() == Mp4AtomIds::Data) {
89  if (dataAtom->dataSize() < 8) {
90  diag.emplace_back(DiagLevel::Warning, "Truncated child atom \"data\" in tag atom (ilst child) found. (will be ignored)", context);
91  continue;
92  }
93  if (++dataAtomFound > 1) {
94  if (dataAtomFound == 2) {
95  diag.emplace_back(
96  DiagLevel::Warning, "Multiple \"data\" child atom in tag atom (ilst child) found. (will be ignored)", context);
97  }
98  continue;
99  }
100  stream.seekg(static_cast<streamoff>(dataAtom->dataOffset()));
101  if (reader.readByte() != 0) {
102  diag.emplace_back(DiagLevel::Warning,
103  "The version indicator byte is not zero, the tag atom might be unsupported and hence not be parsed correctly.", context);
104  }
105  setTypeInfo(m_parsedRawDataType = reader.readUInt24BE());
106  try { // try to show warning if parsed raw data type differs from expected raw data type for this atom id
107  const vector<std::uint32_t> expectedRawDataTypes = this->expectedRawDataTypes();
108  if (find(expectedRawDataTypes.cbegin(), expectedRawDataTypes.cend(), m_parsedRawDataType) == expectedRawDataTypes.cend()) {
109  diag.emplace_back(DiagLevel::Warning, "Unexpected data type indicator found.", context);
110  }
111  } catch (const Failure &) {
112  // tag id is unknown, it is not possible to validate parsed data type
113  }
114  m_countryIndicator = reader.readUInt16BE();
115  m_langIndicator = reader.readUInt16BE();
116  switch (m_parsedRawDataType) {
117  case RawDataType::Utf8:
118  case RawDataType::Utf16:
119  stream.seekg(static_cast<streamoff>(dataAtom->dataOffset() + 8));
120  value().assignText(reader.readString(dataAtom->dataSize() - 8),
121  (m_parsedRawDataType == RawDataType::Utf16) ? TagTextEncoding::Utf16BigEndian : TagTextEncoding::Utf8);
122  break;
123  case RawDataType::Gif:
124  case RawDataType::Jpeg:
125  case RawDataType::Png:
126  case RawDataType::Bmp: {
127  switch (m_parsedRawDataType) {
128  case RawDataType::Gif:
129  value().setMimeType("image/gif");
130  break;
131  case RawDataType::Jpeg:
132  value().setMimeType("image/jpeg");
133  break;
134  case RawDataType::Png:
135  value().setMimeType("image/png");
136  break;
137  case RawDataType::Bmp:
138  value().setMimeType("image/bmp");
139  break;
140  default:;
141  }
142  const auto coverSize = static_cast<streamoff>(dataAtom->dataSize() - 8);
143  auto coverData = make_unique<char[]>(static_cast<size_t>(coverSize));
144  stream.read(coverData.get(), coverSize);
145  value().assignData(move(coverData), static_cast<size_t>(coverSize), TagDataType::Picture);
146  break;
147  }
149  int number = 0;
150  if (dataAtom->dataSize() > (8 + 4)) {
151  diag.emplace_back(DiagLevel::Warning, "Data atom stores integer of invalid size. Trying to read data anyways.", context);
152  }
153  if (dataAtom->dataSize() >= (8 + 4)) {
154  number = reader.readInt32BE();
155  } else if (dataAtom->dataSize() == (8 + 2)) {
156  number = reader.readInt16BE();
157  } else if (dataAtom->dataSize() == (8 + 1)) {
158  number = reader.readChar();
159  }
160  switch (ilstChild.id()) {
161  case PreDefinedGenre: // consider number as standard genre index
163  break;
164  default:
165  value().assignInteger(number);
166  }
167  break;
168  }
170  int number = 0;
171  if (dataAtom->dataSize() > (8 + 4)) {
172  diag.emplace_back(DiagLevel::Warning, "Data atom stores integer of invalid size. Trying to read data anyways.", context);
173  }
174  if (dataAtom->dataSize() >= (8 + 4)) {
175  number = static_cast<int>(reader.readUInt32BE());
176  } else if (dataAtom->dataSize() == (8 + 2)) {
177  number = static_cast<int>(reader.readUInt16BE());
178  } else if (dataAtom->dataSize() == (8 + 1)) {
179  number = static_cast<int>(reader.readByte());
180  }
181  switch (ilstChild.id()) {
182  case PreDefinedGenre: // consider number as standard genre index
183  value().assignStandardGenreIndex(number - 1);
184  break;
185  default:
186  value().assignInteger(number);
187  }
188  break;
189  }
190  default:
191  switch (ilstChild.id()) {
192  // track number, disk number and genre have no specific data type id
193  case TrackPosition:
194  case DiskPosition: {
195  if (dataAtom->dataSize() < (8 + 6)) {
196  diag.emplace_back(DiagLevel::Warning, "Track/disk position is truncated. Trying to read data anyways.", context);
197  }
198  std::uint16_t pos = 0, total = 0;
199  if (dataAtom->dataSize() >= (8 + 4)) {
200  stream.seekg(2, ios_base::cur);
201  pos = reader.readUInt16BE();
202  }
203  if (dataAtom->dataSize() >= (8 + 6)) {
204  total = reader.readUInt16BE();
205  }
206  value().assignPosition(PositionInSet(pos, total));
207  break;
208  }
209  case PreDefinedGenre:
210  if (dataAtom->dataSize() < (8 + 2)) {
211  diag.emplace_back(DiagLevel::Warning, "Genre index is truncated.", context);
212  } else {
213  value().assignStandardGenreIndex(reader.readUInt16BE() - 1);
214  }
215  break;
216  default: // no supported data type, read raw data
217  const auto dataSize = static_cast<streamsize>(dataAtom->dataSize() - 8);
218  auto data = make_unique<char[]>(static_cast<size_t>(dataSize));
219  stream.read(data.get(), dataSize);
220  if (ilstChild.id() == Mp4TagAtomIds::Cover) {
221  value().assignData(move(data), static_cast<size_t>(dataSize), TagDataType::Picture);
222  } else {
223  value().assignData(move(data), static_cast<size_t>(dataSize), TagDataType::Undefined);
224  }
225  }
226  }
227  } else if (dataAtom->id() == Mp4AtomIds::Mean) {
228  if (dataAtom->dataSize() < 8) {
229  diag.emplace_back(DiagLevel::Warning, "Truncated child atom \"mean\" in tag atom (ilst child) found. (will be ignored)", context);
230  continue;
231  }
232  if (++meanAtomFound > 1) {
233  if (meanAtomFound == 2) {
234  diag.emplace_back(
235  DiagLevel::Warning, "Tag atom contains more than one mean atom. The addiational mean atoms will be ignored.", context);
236  }
237  continue;
238  }
239  stream.seekg(static_cast<streamoff>(dataAtom->dataOffset() + 4));
240  m_mean = reader.readString(dataAtom->dataSize() - 4);
241  } else if (dataAtom->id() == Mp4AtomIds::Name) {
242  if (dataAtom->dataSize() < 4) {
243  diag.emplace_back(DiagLevel::Warning, "Truncated child atom \"name\" in tag atom (ilst child) found. (will be ignored)", context);
244  continue;
245  }
246  if (++nameAtomFound > 1) {
247  if (nameAtomFound == 2) {
248  diag.emplace_back(
249  DiagLevel::Warning, "Tag atom contains more than one name atom. The addiational name atoms will be ignored.", context);
250  }
251  continue;
252  }
253  stream.seekg(static_cast<streamoff>(dataAtom->dataOffset() + 4));
254  m_name = reader.readString(dataAtom->dataSize() - 4);
255  } else {
256  diag.emplace_back(DiagLevel::Warning,
257  "Unkown child atom \"" % dataAtom->idToString() + "\" in tag atom (ilst child) found. (will be ignored)", context);
258  }
259  } catch (const Failure &) {
260  diag.emplace_back(DiagLevel::Warning, "Unable to parse all children atom in tag atom (ilst child) found. (will be ignored)", context);
261  }
262  }
263  if (value().isEmpty()) {
264  diag.emplace_back(DiagLevel::Warning, "The field value is empty.", context);
265  }
266 }
267 
279 {
280  return Mp4TagFieldMaker(*this, diag);
281 }
282 
290 void Mp4TagField::make(ostream &stream, Diagnostics &diag)
291 {
292  prepareMaking(diag).make(stream);
293 }
294 
298 std::vector<std::uint32_t> Mp4TagField::expectedRawDataTypes() const
299 {
300  using namespace Mp4TagAtomIds;
301  std::vector<std::uint32_t> res;
302  switch (id()) {
303  case Album:
304  case Artist:
305  case Comment:
306  case Year:
307  case Title:
308  case Genre:
309  case Composer:
310  case Encoder:
311  case Grouping:
312  case Description:
313  case Lyrics:
314  case RecordLabel:
315  case Performers:
316  case Lyricist:
317  res.push_back(RawDataType::Utf8);
318  res.push_back(RawDataType::Utf16);
319  break;
320  case PreDefinedGenre:
321  case TrackPosition:
322  case DiskPosition:
323  res.push_back(RawDataType::Reserved);
324  break;
325  case Bpm:
326  case Rating:
327  res.push_back(RawDataType::BeSignedInt);
328  res.push_back(RawDataType::BeUnsignedInt);
329  break;
330  case Cover:
331  res.push_back(RawDataType::Gif);
332  res.push_back(RawDataType::Jpeg);
333  res.push_back(RawDataType::Png);
334  res.push_back(RawDataType::Bmp);
335  break;
336  case Extended:
338  throw Failure();
339  }
340  // assumption that extended "iTunes" tags always use Unicode correct?
341  res.push_back(RawDataType::Utf8);
342  res.push_back(RawDataType::Utf16);
343  break;
344  default:
345  throw Failure();
346  }
347  return res;
348 }
349 
358 {
359  using namespace Mp4TagAtomIds;
360  if (isTypeInfoAssigned()) {
361  // obtain raw data type from tag field if present
362  return typeInfo();
363  }
364 
365  // there is no raw data type assigned (tag field was not present in original file and
366  // has been inserted by the library's user without type)
367  // -> try to derive appropriate raw data type from atom ID
368  switch (id()) {
369  case Album:
370  case Artist:
371  case Comment:
372  case Year:
373  case Title:
374  case Genre:
375  case Composer:
376  case Encoder:
377  case Grouping:
378  case Description:
379  case Lyrics:
380  case RecordLabel:
381  case Performers:
382  case Lyricist:
383  case AlbumArtist:
384  switch (value().dataEncoding()) {
386  return RawDataType::Utf8;
387  case TagTextEncoding::Utf16BigEndian:
388  return RawDataType::Utf16;
389  default:;
390  }
391  break;
392  case TrackPosition:
393  case DiskPosition:
394  return RawDataType::Reserved;
395  case PreDefinedGenre:
396  case Bpm:
397  case Rating:
399  case Cover: {
400  const string &mimeType = value().mimeType();
401  if (mimeType == "image/jpg" || mimeType == "image/jpeg") { // "well-known" type
402  return RawDataType::Jpeg;
403  } else if (mimeType == "image/png") {
404  return RawDataType::Png;
405  } else if (mimeType == "image/bmp") {
406  return RawDataType::Bmp;
407  }
408  } break;
409  case Extended:
411  throw Failure();
412  }
413  switch (value().dataEncoding()) {
415  return RawDataType::Utf8;
416  case TagTextEncoding::Utf16BigEndian:
417  return RawDataType::Utf16;
418  default:;
419  }
420  break;
421  default:;
422  }
423 
424  // do not forget to extend Mp4Tag::internallyGetFieldId() and Mp4Tag::internallyGetKnownField() as well
425 
426  throw Failure();
427 }
428 
432 void Mp4TagField::reset()
433 {
434  m_name.clear();
435  m_mean.clear();
436  m_parsedRawDataType = RawDataType::Reserved;
437  m_countryIndicator = 0;
438  m_langIndicator = 0;
439 }
440 
452 Mp4TagFieldMaker::Mp4TagFieldMaker(Mp4TagField &field, Diagnostics &diag)
453  : m_field(field)
454  , m_convertedData(stringstream::in | stringstream::out | stringstream::binary)
455  , m_writer(&m_convertedData)
456  , m_rawDataType(0)
457 {
458  if (!m_field.id()) {
459  diag.emplace_back(DiagLevel::Warning, "Invalid tag atom id.", "making MP4 tag field");
460  throw InvalidDataException();
461  }
462  const string context("making MP4 tag field " + Mp4TagField::fieldIdToString(m_field.id()));
463  if (m_field.value().isEmpty() && (!m_field.mean().empty() || !m_field.name().empty())) {
464  diag.emplace_back(DiagLevel::Critical, "No tag value assigned.", context);
465  throw InvalidDataException();
466  }
467 
468  try {
469  // try to use appropriate raw data type
470  m_rawDataType = m_field.appropriateRawDataType();
471  } catch (const Failure &) {
472  // unable to obtain appropriate raw data type
473  if (m_field.id() == Mp4TagAtomIds::Cover) {
474  // assume JPEG image
475  m_rawDataType = RawDataType::Utf8;
476  diag.emplace_back(
477  DiagLevel::Warning, "It was not possible to find an appropriate raw data type id. JPEG image will be assumed.", context);
478  } else {
479  // assume UTF-8 text
480  m_rawDataType = RawDataType::Utf8;
481  diag.emplace_back(DiagLevel::Warning, "It was not possible to find an appropriate raw data type id. UTF-8 will be assumed.", context);
482  }
483  }
484 
485  try {
486  if (!m_field.value().isEmpty()) { // there might be only mean and name info, but no data
487  m_convertedData.exceptions(std::stringstream::failbit | std::stringstream::badbit);
488  switch (m_rawDataType) {
489  case RawDataType::Utf8:
490  case RawDataType::Utf16:
491  m_writer.writeString(m_field.value().toString());
492  break;
494  int number = m_field.value().toInteger();
495  if (number <= numeric_limits<std::int16_t>::max() && number >= numeric_limits<std::int16_t>::min()) {
496  m_writer.writeInt16BE(static_cast<std::int16_t>(number));
497  } else {
498  m_writer.writeInt32BE(number);
499  }
500  break;
501  }
503  int number = m_field.value().toInteger();
504  if (number <= numeric_limits<std::uint16_t>::max() && number >= numeric_limits<std::uint16_t>::min()) {
505  m_writer.writeUInt16BE(static_cast<std::uint16_t>(number));
506  } else if (number > 0) {
507  m_writer.writeUInt32BE(static_cast<std::uint32_t>(number));
508  } else {
509  throw ConversionException(
510  "Negative integer can not be assigned to the field with the ID \"" % interpretIntegerAsString<std::uint32_t>(m_field.id())
511  + "\".");
512  }
513  break;
514  }
515  case RawDataType::Bmp:
516  case RawDataType::Jpeg:
517  case RawDataType::Png:
518  break; // leave converted data empty to write original data later
519  default:
520  switch (m_field.id()) {
521  // track number and disk number are exceptions
522  // raw data type 0 is used, information is stored as pair of unsigned integers
525  PositionInSet pos = m_field.value().toPositionInSet();
526  m_writer.writeInt32BE(pos.position());
527  if (pos.total() <= numeric_limits<std::int16_t>::max()) {
528  m_writer.writeInt16BE(static_cast<std::int16_t>(pos.total()));
529  } else {
530  throw ConversionException(
531  "Integer can not be assigned to the field with the id \"" % interpretIntegerAsString<std::uint32_t>(m_field.id())
532  + "\" because it is to big.");
533  }
534  m_writer.writeUInt16BE(0);
535  break;
536  }
538  m_writer.writeUInt16BE(static_cast<std::uint16_t>(m_field.value().toStandardGenreIndex()));
539  break;
540  default:; // leave converted data empty to write original data later
541  }
542  }
543  }
544  } catch (ConversionException &ex) {
545  // it was not possible to perform required conversions
546  if (char_traits<char>::length(ex.what())) {
547  diag.emplace_back(DiagLevel::Critical, ex.what(), context);
548  } else {
549  diag.emplace_back(DiagLevel::Critical, "The assigned tag value can not be converted to be written appropriately.", context);
550  }
551  throw InvalidDataException();
552  }
553 
554  // calculate data size
555  m_dataSize
556  = m_field.value().isEmpty() ? 0 : (m_convertedData.tellp() ? static_cast<size_t>(m_convertedData.tellp()) : m_field.value().dataSize());
557  m_totalSize = 8 // calculate entire size
558  + (m_field.name().empty() ? 0 : (12 + m_field.name().length())) + (m_field.mean().empty() ? 0 : (12 + m_field.mean().length()))
559  + (m_dataSize ? (16 + m_dataSize) : 0);
560  if (m_totalSize > numeric_limits<std::uint32_t>::max()) {
561  diag.emplace_back(DiagLevel::Critical, "Making a such big MP4 tag field is not supported.", context);
562  throw NotImplementedException();
563  }
564 }
565 
573 void Mp4TagFieldMaker::make(ostream &stream)
574 {
575  m_writer.setStream(&stream);
576  // size of entire tag atom
577  m_writer.writeUInt32BE(static_cast<std::uint32_t>(m_totalSize));
578  // id of tag atom
579  m_writer.writeUInt32BE(m_field.id());
580  if (!m_field.mean().empty()) {
581  // write "mean"
582  m_writer.writeUInt32BE(static_cast<std::uint32_t>(12 + m_field.mean().size()));
583  m_writer.writeUInt32BE(Mp4AtomIds::Mean);
584  m_writer.writeUInt32BE(0);
585  m_writer.writeString(m_field.mean());
586  }
587  if (!m_field.name().empty()) {
588  // write "name"
589  m_writer.writeUInt32BE(static_cast<std::uint32_t>(12 + m_field.name().length()));
590  m_writer.writeUInt32BE(Mp4AtomIds::Name);
591  m_writer.writeUInt32BE(0);
592  m_writer.writeString(m_field.name());
593  }
594  if (!m_field.value().isEmpty()) { // write data
595  m_writer.writeUInt32BE(static_cast<std::uint32_t>(16 + m_dataSize)); // size of data atom
596  m_writer.writeUInt32BE(Mp4AtomIds::Data); // id of data atom
597  m_writer.writeByte(0); // version
598  m_writer.writeUInt24BE(m_rawDataType);
599  m_writer.writeUInt16BE(m_field.countryIndicator());
600  m_writer.writeUInt16BE(m_field.languageIndicator());
601  if (m_convertedData.tellp()) {
602  // write converted data
603  stream << m_convertedData.rdbuf();
604  } else {
605  // no conversion was needed, write data directly from tag value
606  stream.write(m_field.value().dataPointer(), static_cast<streamoff>(m_field.value().dataSize()));
607  }
608  }
609 }
610 
611 } // namespace TagParser
TagParser::Mp4TagField::fieldIdToString
static std::string fieldIdToString(IdentifierType id)
Returns the string representation for the specified id.
Definition: mp4tagfield.h:227
TagParser::Mp4TagAtomIds::Extended
@ Extended
Definition: mp4ids.h:99
TagParser::TagValue::mimeType
const std::string & mimeType() const
Returns the MIME type.
Definition: tagvalue.h:552
mp4ids.h
mp4tagfield.h
TagParser::Mp4TagField::countryIndicator
std::uint16_t countryIndicator() const
Returns the country indicator.
Definition: mp4tagfield.h:185
TagParser::RawDataType::Png
@ Png
Definition: mp4tagfield.h:33
TagParser::Mp4TagAtomIds::Album
@ Album
Definition: mp4ids.h:86
mp4atom.h
TagParser::RawDataType::Utf16
@ Utf16
Definition: mp4tagfield.h:22
TagParser::TagField< Mp4TagField >::typeInfo
const TypeInfoType & typeInfo() const
Returns the type info of the current TagField.
Definition: generictagfield.h:176
TagParser::RawDataType::Utf8
@ Utf8
Definition: mp4tagfield.h:21
TagParser::Mp4TagAtomIds::Lyrics
@ Lyrics
Definition: mp4ids.h:105
TagParser::Mp4TagAtomIds::Encoder
@ Encoder
Definition: mp4ids.h:97
TagParser::Mp4TagAtomIds::Cover
@ Cover
Definition: mp4ids.h:94
TagParser::GenericFileElement::stream
std::iostream & stream()
Returns the related stream.
Definition: genericfileelement.h:237
TagParser::Mp4TagFieldMaker
The Mp4TagFieldMaker class helps making tag fields.
Definition: mp4tagfield.h:63
TagParser::TagField< Mp4TagField >::setTypeInfo
void setTypeInfo(const TypeInfoType &typeInfo)
Sets the type info of the current TagField.
Definition: generictagfield.h:184
TagParser::TagValue::assignPosition
void assignPosition(PositionInSet value)
Assigns the given PositionInSet value.
Definition: tagvalue.h:365
TagParser::RawDataType::Gif
@ Gif
Definition: mp4tagfield.h:31
TagParser::Mp4TagField::make
void make(std::ostream &stream, Diagnostics &diag)
Saves the field to the specified stream.
Definition: mp4tagfield.cpp:290
TagParser::Diagnostics
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
TagParser::Mp4TagAtomIds::TrackPosition
@ TrackPosition
Definition: mp4ids.h:116
TagParser::Mp4TagExtendedMeanIds::iTunes
const char * iTunes
Definition: mp4ids.cpp:24
TagParser
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
TagParser::GenericFileElement::id
const IdentifierType & id() const
Returns the element ID.
Definition: genericfileelement.h:278
TagParser::TagField::id
const IdentifierType & id() const
Returns the id of the current TagField.
Definition: generictagfield.h:115
TagParser::TagValue::assignText
void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding=TagTextEncoding::Latin1, TagTextEncoding convertTo=TagTextEncoding::Unspecified)
Assigns a copy of the given text.
Definition: tagvalue.cpp:773
TagParser::GenericFileElement::parse
void parse(Diagnostics &diag)
Parses the header information of the element which is read from the related stream at the start offse...
Definition: genericfileelement.h:771
TagParser::Mp4TagField::languageIndicator
std::uint16_t languageIndicator() const
Returns the language indicator.
Definition: mp4tagfield.h:193
TagParser::Mp4Atom::idToString
std::string idToString() const
Converts the specified atom ID to a printable string.
Definition: mp4atom.h:67
TagParser::TagValue::assignInteger
void assignInteger(int value)
Assigns the given integer value.
Definition: tagvalue.cpp:824
TagParser::MatroskaIds::Title
@ Title
Definition: matroskaid.h:54
TagParser::TagValue::setMimeType
void setMimeType(const std::string &mimeType)
Sets the MIME type.
Definition: tagvalue.h:562
TagParser::GenericFileElement::firstChild
ImplementationType * firstChild()
Returns the first child of the element.
Definition: genericfileelement.h:460
TagParser::Mp4TagAtomIds::AlbumArtist
@ AlbumArtist
Definition: mp4ids.h:87
TagParser::Mp4TagAtomIds::Year
@ Year
Definition: mp4ids.h:122
TagParser::Mp4TagAtomIds::PreDefinedGenre
@ PreDefinedGenre
Definition: mp4ids.h:110
TagParser::TagField
The TagField class is used by FieldMapBasedTag to store the fields.
Definition: generictagfield.h:30
TagParser::Failure
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
Definition: exceptions.h:11
TagParser::TagValue::isEmpty
bool isEmpty() const
Returns whether no or an empty value is assigned.
Definition: tagvalue.h:464
TagParser::TagField< Mp4TagField >::value
TagValue & value()
Returns the value of the current TagField.
Definition: generictagfield.h:144
TagParser::Mp4TagAtomIds::Lyricist
@ Lyricist
Definition: mp4ids.h:104
TagParser::Mp4AtomIds::Name
@ Name
Definition: mp4ids.h:48
TagParser::Mp4TagAtomIds::Description
@ Description
Definition: mp4ids.h:95
TagParser::TagDataType::Text
@ Text
CppUtilities
Definition: abstractcontainer.h:15
TagParser::Mp4TagAtomIds::Genre
@ Genre
Definition: mp4ids.h:101
TagParser::Mp4TagAtomIds::Rating
@ Rating
Definition: mp4ids.h:113
TagParser::Mp4TagFieldMaker::make
void make(std::ostream &stream)
Saves the field (specified when constructing the object) to the specified stream.
Definition: mp4tagfield.cpp:573
TagParser::Mp4TagField::expectedRawDataTypes
std::vector< std::uint32_t > expectedRawDataTypes() const
Returns the expected raw data types for the ID of the field.
Definition: mp4tagfield.cpp:298
TagParser::TagValue::assignStandardGenreIndex
void assignStandardGenreIndex(int index)
Assigns the given standard genre index to be assigned.
Definition: tagvalue.h:396
TagParser::TagValue::dataPointer
char * dataPointer()
Returns a pointer to the raw data assigned to the current instance.
Definition: tagvalue.h:507
TagParser::Mp4TagField::reparse
void reparse(Mp4Atom &ilstChild, Diagnostics &diag)
Parses field information from the specified Mp4Atom.
Definition: mp4tagfield.cpp:73
TagParser::RawDataType::Bmp
@ Bmp
Definition: mp4tagfield.h:43
TagParser::Mp4TagField::prepareMaking
Mp4TagFieldMaker prepareMaking(Diagnostics &diag)
Prepares making.
Definition: mp4tagfield.cpp:278
TagParser::Mp4TagAtomIds::Grouping
@ Grouping
Definition: mp4ids.h:102
TagParser::TagValue::dataSize
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
Definition: tagvalue.h:496
TagParser::Mp4AtomIds::Mean
@ Mean
Definition: mp4ids.h:35
TagParser::RawDataType::Reserved
@ Reserved
Definition: mp4tagfield.h:20
TagParser::TagValue
The TagValue class wraps values of different types.
Definition: tagvalue.h:75
TagParser::Mp4TagAtomIds::Bpm
@ Bpm
Definition: mp4ids.h:89
TagParser::TagField< Mp4TagField >::isTypeInfoAssigned
bool isTypeInfoAssigned() const
Returns an indication whether a type info is assigned.
Definition: generictagfield.h:202
TagParser::PositionInSet
The PositionInSet class describes the position of an element in a set which consists of a certain num...
Definition: positioninset.h:21
TagParser::Mp4AtomIds::Data
@ Data
Definition: mp4ids.h:20
TagParser::TagField< Mp4TagField >::setId
void setId(const IdentifierType &id)
Sets the id of the current Tag Field.
Definition: generictagfield.h:128
TagParser::Mp4TagAtomIds::Artist
@ Artist
Definition: mp4ids.h:88
TagParser::GenericFileElement::container
ContainerType & container()
Returns the related container.
Definition: genericfileelement.h:220
TagParser::RawDataType::BeUnsignedInt
@ BeUnsignedInt
Definition: mp4tagfield.h:39
TagParser::RawDataType::BeSignedInt
@ BeSignedInt
Definition: mp4tagfield.h:38
mp4container.h
TagParser::Mp4TagAtomIds::RecordLabel
@ RecordLabel
Definition: mp4ids.h:114
TagParser::Mp4TagField::mean
const std::string & mean() const
Returns the "mean" for "extended" fields.
Definition: mp4tagfield.h:161
TagParser::Mp4Atom
The Mp4Atom class helps to parse MP4 files.
Definition: mp4atom.h:38
TagParser::TagValue::assignData
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
TagParser::Mp4TagField::Mp4TagField
Mp4TagField()
Constructs a new Mp4TagField.
Definition: mp4tagfield.cpp:29
TagParser::Mp4TagAtomIds::DiskPosition
@ DiskPosition
Definition: mp4ids.h:96
TagParser::Mp4TagAtomIds::Composer
@ Composer
Definition: mp4ids.h:92
TagParser::Mp4TagField
The Mp4TagField class is used by Mp4Tag to store the fields.
Definition: mp4tagfield.h:98
TagParser::Mp4TagAtomIds::Comment
@ Comment
Definition: mp4ids.h:91
TagParser::RawDataType::Jpeg
@ Jpeg
Definition: mp4tagfield.h:32
TagParser::Mp4TagAtomIds::Performers
@ Performers
Definition: mp4ids.h:107
TagParser::Mp4TagField::appropriateRawDataType
std::uint32_t appropriateRawDataType() const
Returns an appropriate raw data type.
Definition: mp4tagfield.cpp:357
TagParser::Mp4TagField::name
const std::string & name() const
Returns the "name" for "extended" fields.
Definition: mp4tagfield.h:145