Tag Parser  9.1.3
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
id3v2tag.cpp
Go to the documentation of this file.
1 #include "./id3v2tag.h"
2 #include "./id3v2frameids.h"
3 
4 #include "../diagnostics.h"
5 #include "../exceptions.h"
6 
7 #include <c++utilities/conversion/stringbuilder.h>
8 #include <c++utilities/conversion/stringconversion.h>
9 
10 #include <iostream>
11 
12 using namespace std;
13 using namespace CppUtilities;
14 
15 namespace TagParser {
16 
26 bool Id3v2Tag::supportsMultipleValues(KnownField field) const
27 {
28  switch (field) {
29  case KnownField::Album:
30  case KnownField::Artist:
31  case KnownField::Year:
32  case KnownField::RecordDate:
33  case KnownField::Title:
34  case KnownField::Genre:
38  case KnownField::Bpm:
40  case KnownField::Length:
41  case KnownField::Language:
42  case KnownField::EncoderSettings:
47  return m_majorVersion > 3;
48  case KnownField::Rating:
50  case KnownField::Cover:
51  case KnownField::Lyrics:
52  case KnownField::SynchronizedLyrics:
53  return true;
54  default:
55  return false;
56  ;
57  }
58 }
59 
60 void Id3v2Tag::ensureTextValuesAreProperlyEncoded()
61 {
62  const auto encoding = proposedTextEncoding();
63  for (auto &field : fields()) {
64  auto &value = field.second.value();
65  value.convertDataEncoding(encoding);
66  value.convertDescriptionEncoding(encoding);
67  }
68 }
69 
73 std::vector<const TagValue *> Id3v2Tag::internallyGetValues(const IdentifierType &id) const
74 {
75  auto range = fields().equal_range(id);
76  std::vector<const TagValue *> values;
77  for (auto i = range.first; i != range.second; ++i) {
78  const auto &frame(i->second);
79  if (!frame.value().isEmpty()) {
80  values.push_back(&frame.value());
81  }
82  for (const auto &value : frame.additionalValues()) {
83  values.push_back(&value);
84  }
85  }
86  return values;
87 }
88 
95 bool Id3v2Tag::internallySetValues(const IdentifierType &id, const std::vector<TagValue> &values)
96 {
97  // use default implementation for non-text frames
98  if (!Id3v2FrameIds::isTextFrame(id)) {
99  return CRTPBase::internallySetValues(id, values);
100  }
101 
102  // find existing text frame
103  auto range = fields().equal_range(id);
104  auto frameIterator = range.first;
105 
106  // use existing frame or insert new text frame
107  auto valuesIterator = values.cbegin();
108  if (frameIterator != range.second) {
109  ++range.first;
110  // add primary value to existing frame
111  if (valuesIterator != values.cend()) {
112  frameIterator->second.setValue(*valuesIterator);
113  ++valuesIterator;
114  } else {
115  frameIterator->second.value().clearDataAndMetadata();
116  }
117  } else {
118  // skip if there is no existing frame but also no values to be assigned
119  if (valuesIterator == values.cend()) {
120  return true;
121  }
122  // add primary value to new frame
123  frameIterator = fields().insert(make_pair(id, Id3v2Frame(id, *valuesIterator)));
124  ++valuesIterator;
125  }
126 
127  // add additional values to frame
128  frameIterator->second.additionalValues() = vector<TagValue>(valuesIterator, values.cend());
129 
130  // remove remaining existing values (there are more existing values than specified ones)
131  for (; range.first != range.second; ++range.first) {
132  range.first->second.setValue(TagValue());
133  }
134  return true;
135 }
136 
137 Id3v2Tag::IdentifierType Id3v2Tag::internallyGetFieldId(KnownField field) const
138 {
139  using namespace Id3v2FrameIds;
140  if (m_majorVersion >= 3) {
141  switch (field) {
142  case KnownField::Album:
143  return lAlbum;
144  case KnownField::Artist:
145  return lArtist;
146  case KnownField::Comment:
147  return lComment;
148  case KnownField::Year:
149  return lYear;
150  case KnownField::RecordDate:
151  return lRecordDate;
152  case KnownField::Title:
153  return lTitle;
154  case KnownField::Genre:
155  return lGenre;
157  return lTrackPosition;
159  return lDiskPosition;
160  case KnownField::Encoder:
161  return lEncoder;
162  case KnownField::Bpm:
163  return lBpm;
164  case KnownField::Cover:
165  return lCover;
167  return lWriter;
168  case KnownField::Length:
169  return lLength;
170  case KnownField::Language:
171  return lLanguage;
172  case KnownField::EncoderSettings:
173  return lEncoderSettings;
174  case KnownField::Lyrics:
175  return lUnsynchronizedLyrics;
176  case KnownField::SynchronizedLyrics:
177  return lSynchronizedLyrics;
181  return lRecordLabel;
183  return lComposer;
184  case KnownField::Rating:
185  return lRating;
187  return lAlbumArtist;
188  default:;
189  }
190  } else {
191  switch (field) {
192  case KnownField::Album:
193  return sAlbum;
194  case KnownField::Artist:
195  return sArtist;
196  case KnownField::Comment:
197  return sComment;
198  case KnownField::Year:
199  return sYear;
200  case KnownField::RecordDate:
201  return sRecordDate;
202  case KnownField::Title:
203  return sTitle;
204  case KnownField::Genre:
205  return sGenre;
207  return sTrackPosition;
209  return sDiskPosition;
210  case KnownField::Encoder:
211  return sEncoder;
212  case KnownField::Bpm:
213  return sBpm;
214  case KnownField::Cover:
215  return sCover;
217  return sWriter;
218  case KnownField::Length:
219  return sLength;
220  case KnownField::Language:
221  return sLanguage;
222  case KnownField::EncoderSettings:
223  return sEncoderSettings;
224  case KnownField::Lyrics:
225  return sUnsynchronizedLyrics;
226  case KnownField::SynchronizedLyrics:
227  return sSynchronizedLyrics;
231  return sRecordLabel;
233  return sComposer;
234  case KnownField::Rating:
235  return sRating;
237  return sAlbumArtist;
238  default:;
239  }
240  }
241  return 0;
242 }
243 
244 KnownField Id3v2Tag::internallyGetKnownField(const IdentifierType &id) const
245 {
246  using namespace Id3v2FrameIds;
247  switch (id) {
248  case lAlbum:
249  return KnownField::Album;
250  case lArtist:
251  return KnownField::Artist;
252  case lComment:
253  return KnownField::Comment;
254  case lYear:
255  return KnownField::Year;
256  case lRecordDate:
257  return KnownField::RecordDate;
258  case lTitle:
259  return KnownField::Title;
260  case lGenre:
261  return KnownField::Genre;
262  case lTrackPosition:
264  case lDiskPosition:
266  case lEncoder:
267  return KnownField::Encoder;
268  case lBpm:
269  return KnownField::Bpm;
270  case lCover:
271  return KnownField::Cover;
272  case lWriter:
273  return KnownField::Lyricist;
274  case lLanguage:
275  return KnownField::Language;
276  case lLength:
277  return KnownField::Length;
278  case lEncoderSettings:
279  return KnownField::EncoderSettings;
281  return KnownField::Lyrics;
282  case lSynchronizedLyrics:
283  return KnownField::SynchronizedLyrics;
284  case lAlbumArtist:
287  return KnownField::Grouping;
288  case lRecordLabel:
290  case sAlbum:
291  return KnownField::Album;
292  case sArtist:
293  return KnownField::Artist;
294  case sComment:
295  return KnownField::Comment;
296  case sYear:
297  return KnownField::Year;
298  case sRecordDate:
299  return KnownField::RecordDate;
300  case sTitle:
301  return KnownField::Title;
302  case sGenre:
303  return KnownField::Genre;
304  case sTrackPosition:
306  case sEncoder:
307  return KnownField::Encoder;
308  case sBpm:
309  return KnownField::Bpm;
310  case sCover:
311  return KnownField::Cover;
312  case sWriter:
313  return KnownField::Lyricist;
314  case sLanguage:
315  return KnownField::Language;
316  case sLength:
317  return KnownField::Length;
318  case sEncoderSettings:
319  return KnownField::EncoderSettings;
321  return KnownField::Lyrics;
322  case sSynchronizedLyrics:
323  return KnownField::SynchronizedLyrics;
324  case sAlbumArtist:
325  return KnownField::Grouping;
326  case sRecordLabel:
328  default:
329  return KnownField::Invalid;
330  }
331 }
332 
333 TagDataType Id3v2Tag::internallyGetProposedDataType(const std::uint32_t &id) const
334 {
335  using namespace Id3v2FrameIds;
336  switch (id) {
337  case lLength:
338  case sLength:
339  return TagDataType::TimeSpan;
340  case lBpm:
341  case sBpm:
342  return TagDataType::Integer;
343  case lTrackPosition:
344  case sTrackPosition:
345  case lDiskPosition:
346  return TagDataType::PositionInSet;
347  case lCover:
348  case sCover:
349  return TagDataType::Picture;
350  default:
351  if (Id3v2FrameIds::isTextFrame(id)) {
352  return TagDataType::Text;
353  } else {
354  return TagDataType::Undefined;
355  }
356  }
357 }
358 
366 void Id3v2Tag::parse(istream &stream, const std::uint64_t maximalSize, Diagnostics &diag)
367 {
368  // prepare parsing
369  static const string context("parsing ID3v2 tag");
370  BinaryReader reader(&stream);
371  const auto startOffset = static_cast<std::uint64_t>(stream.tellg());
372 
373  // check whether the header is truncated
374  if (maximalSize && maximalSize < 10) {
375  diag.emplace_back(DiagLevel::Critical, "ID3v2 header is truncated (at least 10 bytes expected).", context);
376  throw TruncatedDataException();
377  }
378 
379  // read signature: ID3
380  if (reader.readUInt24BE() != 0x494433u) {
381  diag.emplace_back(DiagLevel::Critical, "Signature is invalid.", context);
382  throw InvalidDataException();
383  }
384  // read header data
385  std::uint8_t majorVersion = reader.readByte();
386  std::uint8_t revisionVersion = reader.readByte();
387  setVersion(majorVersion, revisionVersion);
388  m_flags = reader.readByte();
389  m_sizeExcludingHeader = reader.readSynchsafeUInt32BE();
390  m_size = 10 + m_sizeExcludingHeader;
391  if (m_sizeExcludingHeader == 0) {
392  diag.emplace_back(DiagLevel::Warning, "ID3v2 tag seems to be empty.", context);
393  return;
394  }
395 
396  // check if the version
397  if (!isVersionSupported()) {
398  diag.emplace_back(DiagLevel::Critical, "The ID3v2 tag couldn't be parsed, because its version is not supported.", context);
400  }
401 
402  // read extended header (if present)
403  if (hasExtendedHeader()) {
404  if (maximalSize && maximalSize < 14) {
405  diag.emplace_back(DiagLevel::Critical, "Extended header denoted but not present.", context);
406  throw TruncatedDataException();
407  }
408  m_extendedHeaderSize = reader.readSynchsafeUInt32BE();
409  if (m_extendedHeaderSize < 6 || m_extendedHeaderSize > m_sizeExcludingHeader || (maximalSize && maximalSize < (10 + m_extendedHeaderSize))) {
410  diag.emplace_back(DiagLevel::Critical, "Extended header is invalid/truncated.", context);
411  throw TruncatedDataException();
412  }
413  stream.seekg(m_extendedHeaderSize - 4, ios_base::cur);
414  }
415 
416  // how many bytes remain for frames and padding?
417  std::uint32_t bytesRemaining = m_sizeExcludingHeader - m_extendedHeaderSize;
418  if (maximalSize && bytesRemaining > maximalSize) {
419  bytesRemaining = static_cast<std::uint32_t>(maximalSize);
420  diag.emplace_back(DiagLevel::Critical, "Frames are truncated.", context);
421  }
422 
423  // read frames
424  auto pos = static_cast<std::uint64_t>(stream.tellg());
425  while (bytesRemaining) {
426  // seek to next frame
427  stream.seekg(static_cast<streamoff>(pos));
428  // parse frame
429  Id3v2Frame frame;
430  try {
431  frame.parse(reader, majorVersion, bytesRemaining, diag);
432  if (Id3v2FrameIds::isTextFrame(frame.id()) && fields().count(frame.id()) == 1) {
433  diag.emplace_back(DiagLevel::Warning, "The text frame " % frame.idToString() + " exists more than once.", context);
434  }
435  fields().emplace(frame.id(), move(frame));
436  } catch (const NoDataFoundException &) {
437  if (frame.hasPaddingReached()) {
438  m_paddingSize = startOffset + m_size - pos;
439  break;
440  }
441  } catch (const Failure &) {
442  }
443 
444  // calculate next frame offset
445  if (frame.totalSize() <= bytesRemaining) {
446  pos += frame.totalSize();
447  bytesRemaining -= frame.totalSize();
448  } else {
449  pos += bytesRemaining;
450  bytesRemaining = 0;
451  }
452  }
453 
454  // check for extended header
455  if (!hasFooter()) {
456  return;
457  }
458  if (maximalSize && m_size + 10 < maximalSize) {
459  // the footer does not provide additional information, just check the signature
460  stream.seekg(static_cast<streamoff>(startOffset + (m_size += 10)));
461  if (reader.readUInt24LE() != 0x494433u) {
462  diag.emplace_back(DiagLevel::Critical, "Footer signature is invalid.", context);
463  }
464  // skip remaining footer
465  stream.seekg(7, ios_base::cur);
466  } else {
467  diag.emplace_back(DiagLevel::Critical, "Footer denoted but not present.", context);
468  throw TruncatedDataException();
469  }
470 }
471 
482 Id3v2TagMaker Id3v2Tag::prepareMaking(Diagnostics &diag)
483 {
484  return Id3v2TagMaker(*this, diag);
485 }
486 
494 void Id3v2Tag::make(ostream &stream, std::uint32_t padding, Diagnostics &diag)
495 {
496  prepareMaking(diag).make(stream, padding, diag);
497 }
498 
503 void Id3v2Tag::setVersion(std::uint8_t majorVersion, std::uint8_t revisionVersion)
504 {
505  m_majorVersion = majorVersion;
506  m_revisionVersion = revisionVersion;
507  m_version = argsToString('2', '.', majorVersion, '.', revisionVersion);
508 }
509 
522 bool FrameComparer::operator()(std::uint32_t lhs, std::uint32_t rhs) const
523 {
524  if (lhs == rhs) {
525  return false;
526  }
527 
528  const bool lhsLong = Id3v2FrameIds::isLongId(lhs);
529  const bool rhsLong = Id3v2FrameIds::isLongId(rhs);
530  if (lhsLong != rhsLong) {
531  if (!lhsLong) {
533  if (!lhs) {
534  return true;
535  }
536  } else if (!rhsLong) {
538  if (!rhs) {
539  return true;
540  }
541  }
542  }
543 
545  return true;
546  }
548  return false;
549  }
550  if (lhs == Id3v2FrameIds::lTitle || lhs == Id3v2FrameIds::sTitle) {
551  return true;
552  }
553  if (rhs == Id3v2FrameIds::lTitle || rhs == Id3v2FrameIds::sTitle) {
554  return false;
555  }
556 
557  const bool lhstextfield = Id3v2FrameIds::isTextFrame(lhs);
558  const bool rhstextfield = Id3v2FrameIds::isTextFrame(rhs);
559  if (lhstextfield && !rhstextfield) {
560  return true;
561  }
562  if (!lhstextfield && rhstextfield) {
563  return false;
564  }
565 
566  if (lhs == Id3v2FrameIds::lCover || lhs == Id3v2FrameIds::sCover) {
567  return false;
568  }
569  if (rhs == Id3v2FrameIds::lCover || rhs == Id3v2FrameIds::sCover) {
570  return true;
571  }
572  return lhs < rhs;
573 }
574 
586 Id3v2TagMaker::Id3v2TagMaker(Id3v2Tag &tag, Diagnostics &diag)
587  : m_tag(tag)
588  , m_framesSize(0)
589 {
590  static const string context("making ID3v2 tag");
591 
592  // check if version is supported
593  // (the version could have been changed using setVersion())
594  if (!tag.isVersionSupported()) {
595  diag.emplace_back(DiagLevel::Critical, "The ID3v2 tag version isn't supported.", context);
597  }
598 
599  // prepare frames
600  m_maker.reserve(tag.fields().size());
601  for (auto &pair : tag.fields()) {
602  try {
603  m_maker.emplace_back(pair.second.prepareMaking(tag.majorVersion(), diag));
604  m_framesSize += m_maker.back().requiredSize();
605  } catch (const Failure &) {
606  }
607  }
608 
609  // calculate required size
610  // -> header + size of frames
611  m_requiredSize = 10 + m_framesSize;
612 }
613 
621 void Id3v2TagMaker::make(std::ostream &stream, std::uint32_t padding, Diagnostics &diag)
622 {
623  CPP_UTILITIES_UNUSED(diag)
624 
625  BinaryWriter writer(&stream);
626 
627  // write header
628  // -> signature
629  writer.writeUInt24BE(0x494433u);
630  // -> version
631  writer.writeByte(m_tag.majorVersion());
632  writer.writeByte(m_tag.revisionVersion());
633  // -> flags, but without extended header or compression bit set
634  writer.writeByte(m_tag.flags() & 0xBF);
635  // -> size (excluding header)
636  writer.writeSynchsafeUInt32BE(m_framesSize + padding);
637 
638  // write frames
639  for (auto &maker : m_maker) {
640  maker.make(writer);
641  }
642 
643  // write padding
644  for (; padding; --padding) {
645  stream.put(0);
646  }
647 }
648 
649 } // namespace TagParser
TagParser::Id3v2Tag::isVersionSupported
bool isVersionSupported() const
Returns an indication whether the version is supported by the Id3v2Tag class.
Definition: id3v2tag.h:172
TagParser::Id3v2FrameIds::sTitle
@ sTitle
Definition: id3v2frameids.h:43
TagParser::Id3v2FrameIds::sDiskPosition
@ sDiskPosition
Definition: id3v2frameids.h:46
TagParser::Mp4TagAtomIds::Album
@ Album
Definition: mp4ids.h:86
TagParser::Id3v2TagMaker::make
void make(std::ostream &stream, std::uint32_t padding, Diagnostics &diag)
Saves the tag (specified when constructing the object) to the specified stream.
Definition: id3v2tag.cpp:621
TagParser::Id3v2FrameIds::lCover
@ lCover
Definition: id3v2frameids.h:23
TagParser::Id3v2Frame
The Id3v2Frame class is used by Id3v2Tag to store the fields.
Definition: id3v2frame.h:86
TagParser::Mp4TagAtomIds::Lyrics
@ Lyrics
Definition: mp4ids.h:105
TagParser::Mp4TagAtomIds::Encoder
@ Encoder
Definition: mp4ids.h:97
TagParser::FieldMapBasedTag< Id3v2Tag >::IdentifierType
typename FieldMapBasedTagTraits< Id3v2Tag >::FieldType::IdentifierType IdentifierType
Definition: fieldbasedtag.h:36
TagParser::Mp4TagAtomIds::Cover
@ Cover
Definition: mp4ids.h:94
TagParser::Id3v2Tag::flags
std::uint8_t flags() const
Returns the flags read from the ID3v2 header.
Definition: id3v2tag.h:180
id3v2frameids.h
TagParser::Id3v2FrameIds::lRecordDate
@ lRecordDate
Definition: id3v2frameids.h:16
TagParser::Id3v2FrameIds::lAlbum
@ lAlbum
Definition: id3v2frameids.h:12
TagParser::Id3v2Frame::hasPaddingReached
bool hasPaddingReached() const
Returns whether the padding has reached.
Definition: id3v2frame.h:196
TagParser::Id3v2FrameIds::isLongId
constexpr bool isLongId(std::uint32_t id)
Returns an indication whether the specified id is a long frame id.
Definition: id3v2frameids.h:71
TagParser::Diagnostics
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
TagParser::Mp4TagAtomIds::TrackPosition
@ TrackPosition
Definition: mp4ids.h:116
TagParser::Id3v2FrameIds::sTrackPosition
@ sTrackPosition
Definition: id3v2frameids.h:45
TagParser::Id3v2FrameIds::sCover
@ sCover
Definition: id3v2frameids.h:49
TagParser
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
TagParser::Id3v2FrameIds::lComment
@ lComment
Definition: id3v2frameids.h:14
TagParser::Id3v2Frame::parse
void parse(CppUtilities::BinaryReader &reader, std::uint32_t version, std::uint32_t maximalSize, Diagnostics &diag)
Parses a frame from the stream read using the specified reader.
Definition: id3v2frame.cpp:132
TagParser::Id3v2FrameIds::lTitle
@ lTitle
Definition: id3v2frameids.h:17
TagParser::Id3v2FrameIds::lTrackPosition
@ lTrackPosition
Definition: id3v2frameids.h:19
TagParser::TagField::id
const IdentifierType & id() const
Returns the id of the current TagField.
Definition: generictagfield.h:115
TagParser::Id3v2FrameIds::sRating
@ sRating
Definition: id3v2frameids.h:61
TagParser::Id3v2FrameIds::lLanguage
@ lLanguage
Definition: id3v2frameids.h:26
TagParser::Id3v2FrameIds::sYear
@ sYear
Definition: id3v2frameids.h:41
TagParser::TagDataType
TagDataType
Specifies the data type.
Definition: tagvalue.h:54
TagParser::MatroskaIds::Title
@ Title
Definition: matroskaid.h:54
TagParser::Id3v2FrameIds::lLength
@ lLength
Definition: id3v2frameids.h:25
TagParser::Id3v2FrameIds::lGenre
@ lGenre
Definition: id3v2frameids.h:18
TagParser::Id3v2FrameIds::sSynchronizedLyrics
@ sSynchronizedLyrics
Definition: id3v2frameids.h:55
TagParser::Id3v2FrameIds::sAlbum
@ sAlbum
Definition: id3v2frameids.h:38
TagParser::Mp4TagAtomIds::AlbumArtist
@ AlbumArtist
Definition: mp4ids.h:87
TagParser::Mp4TagAtomIds::Year
@ Year
Definition: mp4ids.h:122
TagParser::Failure
The class inherits from std::exception and serves as base class for exceptions thrown by the elements...
Definition: exceptions.h:11
TagParser::Id3v2FrameIds::sEncoder
@ sEncoder
Definition: id3v2frameids.h:47
TagParser::Id3v2FrameIds::isTextFrame
constexpr bool isTextFrame(std::uint32_t id)
Returns an indication whether the specified id is a text frame id.
Definition: id3v2frameids.h:87
TagParser::Id3v2FrameIds::sBpm
@ sBpm
Definition: id3v2frameids.h:48
TagParser::Id3v2Tag::majorVersion
std::uint8_t majorVersion() const
Returns the major version if known; otherwise returns 0.
Definition: id3v2tag.h:153
TagParser::Mp4TagAtomIds::Lyricist
@ Lyricist
Definition: mp4ids.h:104
TagParser::Id3v2FrameIds::sComposer
@ sComposer
Definition: id3v2frameids.h:60
TagParser::Id3v2FrameIds::sWriter
@ sWriter
Definition: id3v2frameids.h:50
TagParser::DiagLevel::Critical
@ Critical
TagParser::Id3v2FrameIds::sUniqueFileId
@ sUniqueFileId
Definition: id3v2frameids.h:59
TagParser::Id3v2FrameIds::lRecordLabel
@ lRecordLabel
Definition: id3v2frameids.h:32
TagParser::Id3v2FrameIds::sContentGroupDescription
@ sContentGroupDescription
Definition: id3v2frameids.h:57
CppUtilities
Definition: abstractcontainer.h:15
TagParser::Id3v2FrameIds::lComposer
@ lComposer
Definition: id3v2frameids.h:34
TagParser::Mp4TagAtomIds::Genre
@ Genre
Definition: mp4ids.h:101
TagParser::Id3v2FrameIds::lDiskPosition
@ lDiskPosition
Definition: id3v2frameids.h:20
TagParser::Id3v2FrameIds::sLength
@ sLength
Definition: id3v2frameids.h:51
TagParser::Mp4TagAtomIds::Rating
@ Rating
Definition: mp4ids.h:113
TagParser::Id3v2FrameIds::lWriter
@ lWriter
Definition: id3v2frameids.h:24
TagParser::Id3v2FrameIds::lAlbumArtist
@ lAlbumArtist
Definition: id3v2frameids.h:30
TagParser::Id3v2Frame::totalSize
std::uint32_t totalSize() const
Returns the total size of the frame in bytes.
Definition: id3v2frame.h:220
TagParser::Id3v2Tag
Implementation of TagParser::Tag for ID3v2 tags.
Definition: id3v2tag.h:61
TagParser::KnownField
KnownField
Specifies the field.
Definition: tag.h:42
TagParser::Id3v2FrameIds::lUnsynchronizedLyrics
@ lUnsynchronizedLyrics
Definition: id3v2frameids.h:28
TagParser::Id3v2FrameIds::sRecordDate
@ sRecordDate
Definition: id3v2frameids.h:42
id3v2tag.h
TagParser::Id3v2FrameIds::sEncoderSettings
@ sEncoderSettings
Definition: id3v2frameids.h:53
TagParser::VersionNotSupportedException
The exception that is thrown when an operation fails because the detected or specified version is not...
Definition: exceptions.h:53
TagParser::Mp4TagAtomIds::Grouping
@ Grouping
Definition: mp4ids.h:102
TagParser::Id3v2FrameIds::sAlbumArtist
@ sAlbumArtist
Definition: id3v2frameids.h:56
TagParser::FieldMapBasedTag::fields
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.
Definition: fieldbasedtag.h:292
TagParser::Id3v2FrameIds::sUnsynchronizedLyrics
@ sUnsynchronizedLyrics
Definition: id3v2frameids.h:54
TagParser::NoDataFoundException
The exception that is thrown when the data to be parsed holds no parsable information (e....
Definition: exceptions.h:18
TagParser::InvalidDataException
The exception that is thrown when the data to be parsed or to be made seems invalid and therefore can...
Definition: exceptions.h:25
TagParser::TruncatedDataException
The exception that is thrown when the data to be parsed is truncated and therefore can not be parsed ...
Definition: exceptions.h:39
TagParser::TagValue
The TagValue class wraps values of different types. It is meant to be assigned to a tag field.
Definition: tagvalue.h:75
TagParser::Mp4TagAtomIds::Bpm
@ Bpm
Definition: mp4ids.h:89
TagParser::Id3v2FrameIds::lUniqueFileId
@ lUniqueFileId
Definition: id3v2frameids.h:33
TagParser::Id3v2FrameIds::sGenre
@ sGenre
Definition: id3v2frameids.h:44
TagParser::Id3v2FrameIds::lSynchronizedLyrics
@ lSynchronizedLyrics
Definition: id3v2frameids.h:29
TagParser::Id3v2Tag::revisionVersion
std::uint8_t revisionVersion() const
Returns the revision version if known; otherwise returns 0.
Definition: id3v2tag.h:161
TagParser::Id3v2FrameIds::lContentGroupDescription
@ lContentGroupDescription
Definition: id3v2frameids.h:31
TagParser::Id3v2FrameIds::lArtist
@ lArtist
Definition: id3v2frameids.h:13
TagParser::Id3v2FrameIds::lRating
@ lRating
Definition: id3v2frameids.h:35
TagParser::Mp4TagAtomIds::Artist
@ Artist
Definition: mp4ids.h:88
TagParser::Id3v2FrameIds::sComment
@ sComment
Definition: id3v2frameids.h:40
TagParser::Mp4TagAtomIds::RecordLabel
@ RecordLabel
Definition: mp4ids.h:114
TagParser::RawDataType::Undefined
@ Undefined
Definition: mp4tagfield.h:45
TagParser::Id3v2FrameIds::convertToLongId
std::uint32_t convertToLongId(std::uint32_t id)
Converts the specified short frame ID to the equivalent long frame ID.
Definition: id3v2frameids.cpp:77
TagParser::Mp4TagAtomIds::DiskPosition
@ DiskPosition
Definition: mp4ids.h:96
TagParser::Mp4TagAtomIds::Composer
@ Composer
Definition: mp4ids.h:92
TagParser::Mp4TagAtomIds::Comment
@ Comment
Definition: mp4ids.h:91
TagParser::Id3v2FrameIds::lBpm
@ lBpm
Definition: id3v2frameids.h:22
TagParser::Id3v2FrameIds::sRecordLabel
@ sRecordLabel
Definition: id3v2frameids.h:58
TagParser::TagField::idToString
std::string idToString() const
Definition: generictagfield.h:120
TagParser::Id3v2FrameIds::lEncoder
@ lEncoder
Definition: id3v2frameids.h:21
TagParser::Id3v2TagMaker
The Id3v2TagMaker class helps writing ID3v2 tags.
Definition: id3v2tag.h:18
TagParser::Id3v2FrameIds::lEncoderSettings
@ lEncoderSettings
Definition: id3v2frameids.h:27
TagParser::Id3v2FrameIds::sArtist
@ sArtist
Definition: id3v2frameids.h:39
TagParser::Id3v2FrameIds::sLanguage
@ sLanguage
Definition: id3v2frameids.h:52
TagParser::Id3v2FrameIds::lYear
@ lYear
Definition: id3v2frameids.h:15