Tag Parser  10.0.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
id3v2tag.h
Go to the documentation of this file.
1 #ifndef TAG_PARSER_ID3V2TAG_H
2 #define TAG_PARSER_ID3V2TAG_H
3 
4 #include "./id3v2frame.h"
5 
6 #include "../fieldbasedtag.h"
7 
8 #include <c++utilities/misc/flagenumclass.h>
9 
10 #include <map>
11 
12 namespace TagParser {
13 
17 enum class Id3v2HandlingFlags : std::uint64_t {
18  None = 0,
19  ConvertRecordDateFields = (1 << 1),
21 };
22 
23 } // namespace TagParser
24 
26 
27 namespace TagParser {
28 
29 class Id3v2Tag;
30 
32  bool operator()(std::uint32_t lhs, std::uint32_t rhs) const;
33 };
34 
36  friend class Id3v2Tag;
37 
38 public:
39  void make(std::ostream &stream, std::uint32_t padding, Diagnostics &diag);
40  const Id3v2Tag &tag() const;
41  std::uint64_t requiredSize() const;
42 
43 private:
44  Id3v2TagMaker(Id3v2Tag &tag, Diagnostics &diag);
45 
46  Id3v2Tag &m_tag;
47  std::uint32_t m_framesSize;
48  std::uint32_t m_requiredSize;
49  std::vector<Id3v2FrameMaker> m_maker;
50 };
51 
55 inline const Id3v2Tag &Id3v2TagMaker::tag() const
56 {
57  return m_tag;
58 }
59 
64 inline std::uint64_t Id3v2TagMaker::requiredSize() const
65 {
66  return m_requiredSize;
67 }
68 
73 public:
76 };
77 
78 class TAG_PARSER_EXPORT Id3v2Tag final : public FieldMapBasedTag<Id3v2Tag> {
79  friend class FieldMapBasedTag<Id3v2Tag>;
80  friend class Id3v2TagMaker;
81 
82 public:
83  Id3v2Tag();
84 
85  static constexpr TagType tagType = TagType::Id3v2Tag;
86  static constexpr std::string_view tagName = "ID3v2 tag";
87  static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf16LittleEndian;
88  TagTextEncoding proposedTextEncoding() const override;
89  bool canEncodingBeUsed(TagTextEncoding encoding) const override;
90  bool supportsDescription(KnownField field) const override;
91  bool supportsMimeType(KnownField field) const override;
92  bool supportsMultipleValues(KnownField field) const override;
93  void ensureTextValuesAreProperlyEncoded() override;
94 
95  void parse(std::istream &sourceStream, const std::uint64_t maximalSize, Diagnostics &diag);
96  Id3v2TagMaker prepareMaking(Diagnostics &diag);
97  void make(std::ostream &targetStream, std::uint32_t padding, Diagnostics &diag);
98  Id3v2HandlingFlags handlingFlags() const;
99  void setHandlingFlags(Id3v2HandlingFlags flags);
100 
101  std::uint8_t majorVersion() const;
102  std::uint8_t revisionVersion() const;
103  void setVersion(std::uint8_t majorVersion, std::uint8_t revisionVersion);
104  bool isVersionSupported() const;
105  std::uint8_t flags() const;
106  bool isUnsynchronisationUsed() const;
107  bool hasExtendedHeader() const;
108  bool isExperimental() const;
109  bool hasFooter() const;
110  std::uint32_t extendedHeaderSize() const;
111  std::uint64_t paddingSize() const;
112 
113 protected:
114  IdentifierType internallyGetFieldId(KnownField field) const;
115  KnownField internallyGetKnownField(const IdentifierType &id) const;
116  TagDataType internallyGetProposedDataType(const std::uint32_t &id) const;
117  void internallyGetValuesFromField(const FieldType &field, std::vector<const TagValue *> &values) const;
118  bool internallySetValues(const IdentifierType &id, const std::vector<TagValue> &values);
119 
120 private:
121  void convertOldRecordDateFields(const std::string &diagContext, Diagnostics &diag);
122  void removeOldRecordDateRelatedFields();
123  void prepareRecordDataForMaking(const std::string &diagContext, Diagnostics &diag);
124 
125 private:
126  std::uint8_t m_majorVersion;
127  std::uint8_t m_revisionVersion;
128  std::uint8_t m_flags;
129  std::uint32_t m_sizeExcludingHeader;
130  std::uint32_t m_extendedHeaderSize;
131  std::uint64_t m_paddingSize;
132  Id3v2HandlingFlags m_handlingFlags;
133 };
134 
139  : m_majorVersion(4)
140  , m_revisionVersion(0)
141  , m_flags(0)
142  , m_sizeExcludingHeader(0)
143  , m_extendedHeaderSize(0)
144  , m_paddingSize(0)
145  , m_handlingFlags(Id3v2HandlingFlags::Defaults)
146 {
147 }
148 
150 {
151  return m_majorVersion > 3 ? TagTextEncoding::Utf8 : TagTextEncoding::Utf16LittleEndian;
152 }
153 
154 inline bool Id3v2Tag::canEncodingBeUsed(TagTextEncoding encoding) const
155 {
156  return encoding == TagTextEncoding::Latin1 || (encoding == TagTextEncoding::Utf8 && m_majorVersion > 3)
158 }
159 
161 {
162  switch (field) {
163  case KnownField::Cover:
164  case KnownField::Lyrics:
166  return true;
167  default:
168  return false;
169  }
170 }
171 
172 inline bool Id3v2Tag::supportsMimeType(KnownField field) const
173 {
174  return field == KnownField::Cover;
175 }
176 
181 {
182  return m_handlingFlags;
183 }
184 
189 {
190  m_handlingFlags = flags;
191 }
192 
196 inline std::uint8_t Id3v2Tag::majorVersion() const
197 {
198  return m_majorVersion;
199 }
200 
204 inline std::uint8_t Id3v2Tag::revisionVersion() const
205 {
206  return m_revisionVersion;
207 }
208 
215 inline bool Id3v2Tag::isVersionSupported() const
216 {
217  return m_majorVersion == 2 || m_majorVersion == 3 || m_majorVersion == 4;
218 }
219 
223 inline std::uint8_t Id3v2Tag::flags() const
224 {
225  return m_flags;
226 }
227 
232 {
233  return m_flags & 0x80;
234 }
235 
239 inline bool Id3v2Tag::hasExtendedHeader() const
240 {
241  return (m_majorVersion >= 3) && (m_flags & 0x40);
242 }
243 
247 inline bool Id3v2Tag::isExperimental() const
248 {
249  return (m_majorVersion >= 3) && (m_flags & 0x20);
250 }
251 
255 inline bool Id3v2Tag::hasFooter() const
256 {
257  return (m_majorVersion >= 3) && (m_flags & 0x10);
258 }
259 
263 inline std::uint32_t Id3v2Tag::extendedHeaderSize() const
264 {
265  return m_extendedHeaderSize;
266 }
267 
272 inline std::uint64_t Id3v2Tag::paddingSize() const
273 {
274  return m_paddingSize;
275 }
276 
277 } // namespace TagParser
278 
279 #endif // TAG_PARSER_ID3V2TAG_H
The Diagnostics class is a container for DiagMessage.
Definition: diagnostics.h:156
Defines traits for the specified ImplementationType.
Definition: fieldbasedtag.h:17
The FieldMapBasedTag provides a generic implementation of Tag which stores the tag fields using std::...
Definition: fieldbasedtag.h:31
The Id3v2Frame class is used by Id3v2Tag to store the fields.
Definition: id3v2frame.h:86
The Id3v2TagMaker class helps writing ID3v2 tags.
Definition: id3v2tag.h:35
std::uint64_t requiredSize() const
Returns the number of bytes which will be written when making the tag.
Definition: id3v2tag.h:64
const Id3v2Tag & tag() const
Returns the associated tag.
Definition: id3v2tag.h:55
Implementation of TagParser::Tag for ID3v2 tags.
Definition: id3v2tag.h:78
std::uint8_t revisionVersion() const
Returns the revision version if known; otherwise returns 0.
Definition: id3v2tag.h:204
bool hasExtendedHeader() const
Returns an indication whether an extended header is used.
Definition: id3v2tag.h:239
bool isVersionSupported() const
Returns an indication whether the version is supported by the Id3v2Tag class.
Definition: id3v2tag.h:215
void setHandlingFlags(Id3v2HandlingFlags flags)
Sets flags influencing the behavior when parsing/making the ID3v2 tag.
Definition: id3v2tag.h:188
Id3v2HandlingFlags handlingFlags() const
Returns flags influencing the behavior when parsing/making the ID3v2 tag.
Definition: id3v2tag.h:180
bool canEncodingBeUsed(TagTextEncoding encoding) const override
Returns an indication whether the specified encoding can be used to provide string values for the tag...
Definition: id3v2tag.h:154
std::uint8_t flags() const
Returns the flags read from the ID3v2 header.
Definition: id3v2tag.h:223
bool isUnsynchronisationUsed() const
Returns an indication whether unsynchronisation is used.
Definition: id3v2tag.h:231
std::uint32_t extendedHeaderSize() const
Returns the size of the extended header if one is present; otherwise returns 0.
Definition: id3v2tag.h:263
std::uint8_t majorVersion() const
Returns the major version if known; otherwise returns 0.
Definition: id3v2tag.h:196
bool hasFooter() const
Returns an indication whether a footer is present.
Definition: id3v2tag.h:255
bool supportsMimeType(KnownField field) const override
Returns an indications whether the specified field supports mime types.
Definition: id3v2tag.h:172
Id3v2Tag()
Constructs a new tag.
Definition: id3v2tag.h:138
TagTextEncoding proposedTextEncoding() const override
Returns the proposed text encoding.
Definition: id3v2tag.h:149
std::uint64_t paddingSize() const
Returns the size of the padding between the tag and the first MPEG frame if one is present; otherwise...
Definition: id3v2tag.h:272
bool supportsDescription(KnownField field) const override
Returns an indications whether the specified field supports descriptions.
Definition: id3v2tag.h:160
bool isExperimental() const
Returns an indication whether the tag is labeled as experimental.
Definition: id3v2tag.h:247
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
KnownField
Specifies the field.
Definition: tag.h:42
TagTextEncoding
Specifies the text encoding.
Definition: tagvalue.h:28
TagType
Specifies the tag type.
Definition: tag.h:20
Id3v2HandlingFlags
The Id3v2Flags enum specifies flags which controls parsing and making of ID3v2 tags.
Definition: id3v2tag.h:17
TagDataType
Specifies the data type.
Definition: tagvalue.h:74
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(TagParser, TagParser::TagCreationFlags)
Defines the order which is used to store ID3v2 frames.
Definition: id3v2tag.h:31