Tag Parser  9.2.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
tagvalue.h
Go to the documentation of this file.
1 #ifndef TAG_PARSER_TAGVALUE_H
2 #define TAG_PARSER_TAGVALUE_H
3 
4 #include "./positioninset.h"
5 
6 #include <c++utilities/chrono/datetime.h>
7 #include <c++utilities/chrono/timespan.h>
8 #include <c++utilities/conversion/binaryconversion.h>
9 #include <c++utilities/misc/flagenumclass.h>
10 #include <c++utilities/misc/traits.h>
11 
12 #include <cstring>
13 #include <iosfwd>
14 #include <memory>
15 #include <string>
16 
17 namespace TagParser {
18 
19 class Tag;
20 class Id3v2Frame;
21 
25 enum class TagTextEncoding : unsigned int {
26  Latin1,
27  Utf8,
31 };
32 
37 constexpr int characterSize(TagTextEncoding encoding)
38 {
39  switch (encoding) {
42  return 1;
45  return 2;
46  default:
47  return 0;
48  }
49 }
50 
54 enum class TagDataType : unsigned int {
55  Text,
56  Integer,
59  TimeSpan,
60  DateTime,
61  Picture,
62  Binary,
63  Undefined
64 };
65 
69 enum class TagValueComparisionFlags : unsigned int {
70  None,
71  CaseInsensitive = 0x1,
72  IgnoreMetaData = 0x2,
73 };
74 
76 public:
77  // constructor, destructor
78  TagValue();
79  TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
82  TagValue(
83  const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
84  TagValue(int value);
85  TagValue(const char *data, std::size_t length, TagDataType type = TagDataType::Undefined, TagTextEncoding encoding = TagTextEncoding::Latin1);
86  TagValue(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
88  TagValue(PositionInSet value);
89  TagValue(CppUtilities::DateTime value);
90  TagValue(CppUtilities::TimeSpan value);
91  TagValue(const TagValue &other);
92  TagValue(TagValue &&other) = default;
93  ~TagValue();
94 
95  // operators
96  TagValue &operator=(const TagValue &other);
97  TagValue &operator=(TagValue &&other) = default;
98  bool operator==(const TagValue &other) const;
99  bool operator!=(const TagValue &other) const;
100  operator bool() const;
101 
102  // methods
103  bool isNull() const;
104  bool isEmpty() const;
105  void clearData();
106  void clearMetadata();
107  void clearDataAndMetadata();
108  TagDataType type() const;
109  std::string toString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
110  void toString(std::string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
111  std::u16string toWString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
112  void toWString(std::u16string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
113  std::int32_t toInteger() const;
114  int toStandardGenreIndex() const;
115  PositionInSet toPositionInSet() const;
116  CppUtilities::TimeSpan toTimeSpan() const;
117  CppUtilities::DateTime toDateTime() const;
118  std::size_t dataSize() const;
119  char *dataPointer();
120  const char *dataPointer() const;
121  const std::string &description() const;
122  void setDescription(const std::string &value, TagTextEncoding encoding = TagTextEncoding::Latin1);
123  const std::string &mimeType() const;
124  void setMimeType(const std::string &mimeType);
125  const std::string &language() const;
126  void setLanguage(const std::string &language);
127  bool isLabeledAsReadonly() const;
128  void setReadonly(bool readOnly);
129  TagTextEncoding dataEncoding() const;
130  void convertDataEncoding(TagTextEncoding encoding);
131  void convertDataEncodingForTag(const Tag *tag);
132  TagTextEncoding descriptionEncoding() const;
133  void convertDescriptionEncoding(TagTextEncoding encoding);
134  static const TagValue &empty();
135 
136  void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
138  void assignText(
139  const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
140  void assignInteger(int value);
141  void assignStandardGenreIndex(int index);
142  void assignData(const char *data, std::size_t length, TagDataType type = TagDataType::Binary, TagTextEncoding encoding = TagTextEncoding::Latin1);
143  void assignData(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
145  void assignPosition(PositionInSet value);
146  void assignTimeSpan(CppUtilities::TimeSpan value);
147  void assignDateTime(CppUtilities::DateTime value);
148 
149  static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding);
150  static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding);
151  template <typename ContainerType,
152  CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsIteratable<ContainerType>,
153  std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>>
154  * = nullptr>
155  static std::vector<std::string> toStrings(const ContainerType &values, TagTextEncoding encoding = TagTextEncoding::Utf8);
156  bool compareTo(const TagValue &other, TagValueComparisionFlags options = TagValueComparisionFlags::None) const;
157  bool compareData(const TagValue &other, bool ignoreCase = false) const;
158  static bool compareData(const std::string &data1, const std::string &data2, bool ignoreCase = false);
159  static bool compareData(const char *data1, std::size_t size1, const char *data2, std::size_t size2, bool ignoreCase = false);
160 
161 private:
162  std::unique_ptr<char[]> m_ptr;
163  std::size_t m_size;
164  std::string m_desc;
165  std::string m_mimeType;
166  std::string m_language;
167  TagDataType m_type;
168  TagTextEncoding m_encoding;
169  TagTextEncoding m_descEncoding;
170  bool m_labeledAsReadonly;
171 };
172 
177  : m_size(0)
178  , m_type(TagDataType::Undefined)
179  , m_encoding(TagTextEncoding::Latin1)
180  , m_descEncoding(TagTextEncoding::Latin1)
181  , m_labeledAsReadonly(false)
182 {
183 }
184 
189 {
190 }
191 
202 inline TagValue::TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding, TagTextEncoding convertTo)
203  : m_descEncoding(TagTextEncoding::Latin1)
204  , m_labeledAsReadonly(false)
205 {
206  assignText(text, textSize, textEncoding, convertTo);
207 }
208 
218 inline TagValue::TagValue(const char *text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
219 {
220  assignText(text, std::strlen(text), textEncoding, convertTo);
221 }
222 
232 inline TagValue::TagValue(const std::string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
233  : m_descEncoding(TagTextEncoding::Latin1)
234  , m_labeledAsReadonly(false)
235 {
236  assignText(text, textEncoding, convertTo);
237 }
238 
242 inline TagValue::TagValue(int value)
243  : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::Integer)
244 {
245 }
246 
257 inline TagValue::TagValue(const char *data, std::size_t length, TagDataType type, TagTextEncoding encoding)
258  : m_size(length)
259  , m_type(type)
260  , m_encoding(encoding)
261  , m_descEncoding(TagTextEncoding::Latin1)
262  , m_labeledAsReadonly(false)
263 {
264  if (length) {
265  if (type == TagDataType::Text) {
266  stripBom(data, m_size, encoding);
267  }
268  m_ptr = std::make_unique<char[]>(m_size);
269  std::copy(data, data + m_size, m_ptr.get());
270  }
271 }
272 
285 inline TagValue::TagValue(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type, TagTextEncoding encoding)
286  : m_size(length)
287  , m_type(type)
288  , m_encoding(encoding)
289  , m_descEncoding(TagTextEncoding::Latin1)
290  , m_labeledAsReadonly(false)
291 {
292  if (length) {
293  m_ptr = move(data);
294  }
295 }
296 
301  : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet)
302 {
303 }
304 
308 inline TagValue::TagValue(CppUtilities::DateTime value)
309  : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTime)
310 {
311 }
312 
316 inline TagValue::TagValue(CppUtilities::TimeSpan value)
317  : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::TimeSpan)
318 {
319 }
320 
325 inline bool TagValue::operator==(const TagValue &other) const
326 {
328 }
329 
334 inline bool TagValue::operator!=(const TagValue &other) const
335 {
337 }
338 
343 inline TagParser::TagValue::operator bool() const
344 {
345  return !isEmpty();
346 }
347 
357 inline void TagValue::assignText(const std::string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
358 {
359  assignText(text.data(), text.size(), textEncoding, convertTo);
360 }
361 
366 {
367  if (value.isNull()) {
369  clearData();
370  } else {
371  assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet);
372  }
373 }
374 
378 inline void TagValue::assignTimeSpan(CppUtilities::TimeSpan value)
379 {
380  assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::TimeSpan);
381 }
382 
386 inline void TagValue::assignDateTime(CppUtilities::DateTime value)
387 {
388  assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTime);
389 }
390 
397 {
398  assignInteger(index);
400 }
401 
406 {
407  return m_type;
408 }
409 
422 inline std::string TagValue::toString(TagTextEncoding encoding) const
423 {
424  std::string res;
425  toString(res, encoding);
426  return res;
427 }
428 
435 inline std::u16string TagValue::toWString(TagTextEncoding encoding) const
436 {
437  std::u16string res;
438  toWString(res, encoding);
439  return res;
440 }
441 
450 inline bool TagValue::isNull() const
451 {
452  return m_ptr == nullptr;
453 }
454 
464 inline bool TagValue::isEmpty() const
465 {
466  return m_ptr == nullptr || m_size == 0;
467 }
468 
475 inline void TagValue::clearData()
476 {
477  m_size = 0;
478  m_ptr.reset();
479 }
480 
487 {
488  clearData();
489  clearMetadata();
490 }
491 
496 inline std::size_t TagValue::dataSize() const
497 {
498  return m_size;
499 }
500 
507 inline char *TagValue::dataPointer()
508 {
509  return m_ptr.get();
510 }
511 
512 inline const char *TagValue::dataPointer() const
513 {
514  return m_ptr.get();
515 }
516 
526 inline const std::string &TagValue::description() const
527 {
528  return m_desc;
529 }
530 
541 inline void TagValue::setDescription(const std::string &value, TagTextEncoding encoding)
542 {
543  m_desc = value;
544  m_descEncoding = encoding;
545 }
546 
552 inline const std::string &TagValue::mimeType() const
553 {
554  return m_mimeType;
555 }
556 
562 inline void TagValue::setMimeType(const std::string &mimeType)
563 {
564  m_mimeType = mimeType;
565 }
566 
572 inline const std::string &TagValue::language() const
573 {
574  return m_language;
575 }
576 
582 inline void TagValue::setLanguage(const std::string &language)
583 {
584  m_language = language;
585 }
586 
595 inline bool TagValue::isLabeledAsReadonly() const
596 {
597  return m_labeledAsReadonly;
598 }
599 
608 inline void TagValue::setReadonly(bool readOnly)
609 {
610  m_labeledAsReadonly = readOnly;
611 }
612 
619 {
620  return m_encoding;
621 }
622 
629 {
630  return m_descEncoding;
631 }
632 
638 template <typename ContainerType,
639  CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsIteratable<ContainerType>,
640  std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>> *>
641 std::vector<std::string> TagValue::toStrings(const ContainerType &values, TagTextEncoding encoding)
642 {
643  std::vector<std::string> res;
644  res.reserve(values.size());
645  for (const auto &value : values) {
646  res.emplace_back(CppUtilities::Traits::dereferenceMaybe(value).toString(encoding));
647  }
648  return res;
649 }
650 
654 inline bool TagValue::compareData(const TagValue &other, bool ignoreCase) const
655 {
656  return compareData(m_ptr.get(), m_size, other.m_ptr.get(), other.m_size, ignoreCase);
657 }
658 
662 inline bool TagValue::compareData(const std::string &data1, const std::string &data2, bool ignoreCase)
663 {
664  return compareData(data1.data(), data1.size(), data2.data(), data2.size(), ignoreCase);
665 }
666 
667 } // namespace TagParser
668 
670 
671 #endif // TAG_PARSER_TAGVALUE_H
positioninset.h
TagParser::TagValue::mimeType
const std::string & mimeType() const
Returns the MIME type.
Definition: tagvalue.h:552
TagParser::TagValueComparisionFlags::IgnoreMetaData
@ IgnoreMetaData
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(TagParser, TagParser::TagCreationFlags)
TagParser::TagValue::setReadonly
void setReadonly(bool readOnly)
Sets whether the TagValue is labeled as read-only.
Definition: tagvalue.h:608
TagParser::TagValue::assignTimeSpan
void assignTimeSpan(CppUtilities::TimeSpan value)
Assigns the given TimeSpan value.
Definition: tagvalue.h:378
TagParser::TagDataType::TimeSpan
@ TimeSpan
TagParser::TagValue::TagValue
TagValue(TagValue &&other)=default
TagParser::TagTextEncoding::Utf8
@ Utf8
TagParser::MatroskaTagIds::description
constexpr TAG_PARSER_EXPORT const char * description()
Definition: matroskatagid.h:231
TagParser::TagValue::assignDateTime
void assignDateTime(CppUtilities::DateTime value)
Assigns the given DateTime value.
Definition: tagvalue.h:386
TagParser::TagValue::TagValue
TagValue()
Constructs an empty TagValue.
Definition: tagvalue.h:176
TagParser::TagValue::clearDataAndMetadata
void clearDataAndMetadata()
Wipes assigned data including meta data.
Definition: tagvalue.h:486
TagParser::TagTextEncoding
TagTextEncoding
Specifies the text encoding.
Definition: tagvalue.h:25
TagParser::TagValue::descriptionEncoding
TagTextEncoding descriptionEncoding() const
Returns the description encoding.
Definition: tagvalue.h:628
TagParser::TagValue::assignPosition
void assignPosition(PositionInSet value)
Assigns the given PositionInSet value.
Definition: tagvalue.h:365
TagParser::TagTextEncoding::Utf16BigEndian
@ Utf16BigEndian
TagParser::TagValue::compareData
bool compareData(const TagValue &other, bool ignoreCase=false) const
Returns whether the raw data of the current instance equals the raw data of other.
Definition: tagvalue.h:654
TagParser::TagTextEncoding::Unspecified
@ Unspecified
TagParser::Tag
The Tag class is used to store, read and write tag information.
Definition: tag.h:108
TagParser::TagValue::operator!=
bool operator!=(const TagValue &other) const
Returns whether both instances are not equal.
Definition: tagvalue.h:334
TagParser::TagValue::stripBom
static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding)
Strips the byte order mask from the specified text.
Definition: tagvalue.cpp:882
TagParser::TagDataType::PositionInSet
@ PositionInSet
TagParser::TagDataType::StandardGenreIndex
@ StandardGenreIndex
TagParser
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:10
TagParser::TagValueComparisionFlags::None
@ None
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::characterSize
constexpr int characterSize(TagTextEncoding encoding)
Returns the size of one character for the specified encoding in bytes.
Definition: tagvalue.h:37
TagParser::TagValue::operator=
TagValue & operator=(TagValue &&other)=default
TagParser::TagValue::assignInteger
void assignInteger(int value)
Assigns the given integer value.
Definition: tagvalue.cpp:824
TagParser::TagValue::clearData
void clearData()
Clears the assigned data.
Definition: tagvalue.h:475
TagParser::TagDataType
TagDataType
Specifies the data type.
Definition: tagvalue.h:54
TagParser::TagValue::description
const std::string & description() const
Returns the description.
Definition: tagvalue.h:526
TagParser::TagValue::setMimeType
void setMimeType(const std::string &mimeType)
Sets the MIME type.
Definition: tagvalue.h:562
TagParser::TagValue::compareTo
bool compareTo(const TagValue &other, TagValueComparisionFlags options=TagValueComparisionFlags::None) const
Returns whether both instances are equal.
Definition: tagvalue.cpp:181
TagParser::operator==
constexpr bool operator==(std::uint8_t lhs, FlacMetaDataBlockType type)
Definition: flacmetadata.h:18
TagParser::TagValue::isEmpty
bool isEmpty() const
Returns whether no or an empty value is assigned.
Definition: tagvalue.h:464
TagParser::TagValue::toStrings
static std::vector< std::string > toStrings(const ContainerType &values, TagTextEncoding encoding=TagTextEncoding::Utf8)
Converts the specified values to string using the specified encoding.
Definition: tagvalue.h:641
TagParser::PositionInSet::isNull
constexpr bool isNull() const
Returns an indication whether both the element position and total element count is 0.
Definition: positioninset.h:94
TagParser::TagTextEncoding::Latin1
@ Latin1
TagParser::TagValue::assignData
void assignData(std::unique_ptr< char[]> &&data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
TagParser::TagDataType::Undefined
@ Undefined
TagParser::TagValue::toWString
std::u16string toWString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::wstring representation.
Definition: tagvalue.h:435
TagParser::MatroskaTagIds::language
constexpr TAG_PARSER_EXPORT const char * language()
Definition: matroskatagid.h:343
TagParser::TagDataType::Text
@ Text
TagParser::operator!=
constexpr bool operator!=(std::uint8_t lhs, FlacMetaDataBlockType type)
Definition: flacmetadata.h:23
TagParser::TagDataType::Picture
@ Picture
TagParser::TagValue::isNull
bool isNull() const
Returns whether no value is assigned at all.
Definition: tagvalue.h:450
TagParser::TagValue::assignStandardGenreIndex
void assignStandardGenreIndex(int index)
Assigns the given standard genre index to be assigned.
Definition: tagvalue.h:396
TagParser::TagValue::operator==
bool operator==(const TagValue &other) const
Returns whether both instances are equal.
Definition: tagvalue.h:325
TagParser::TagValue::dataPointer
char * dataPointer()
Returns a pointer to the raw data assigned to the current instance.
Definition: tagvalue.h:507
TagParser::TagValue::clearMetadata
void clearMetadata()
Wipes assigned meta data.
Definition: tagvalue.cpp:307
TagParser::TagValue::dataSize
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
Definition: tagvalue.h:496
TagParser::TagDataType::Binary
@ Binary
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::TagValue::setDescription
void setDescription(const std::string &value, TagTextEncoding encoding=TagTextEncoding::Latin1)
Sets the description.
Definition: tagvalue.h:541
TagParser::TagTextEncoding::Utf16LittleEndian
@ Utf16LittleEndian
TagParser::TagDataType::DateTime
@ DateTime
TagParser::TagValueComparisionFlags::CaseInsensitive
@ CaseInsensitive
TagParser::MatroskaIds::Tag
@ Tag
Definition: matroskaid.h:204
TagParser::TagValue::toString
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
Definition: tagvalue.h:422
TagParser::TagValue::~TagValue
~TagValue()
Destroys the TagValue.
Definition: tagvalue.h:188
TAG_PARSER_EXPORT
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
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::TagValue::isLabeledAsReadonly
bool isLabeledAsReadonly() const
Returns an indication whether the value is labeled as read-only.
Definition: tagvalue.h:595
TagParser::TagValueComparisionFlags
TagValueComparisionFlags
The TagValueComparisionOption enum specifies options for TagValue::compareTo().
Definition: tagvalue.h:69
TagParser::TagValue::type
TagDataType type() const
Returns the type of the assigned value.
Definition: tagvalue.h:405
TagParser::TagValue::dataEncoding
TagTextEncoding dataEncoding() const
Returns the data encoding.
Definition: tagvalue.h:618
TagParser::TagValue::assignData
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
TagParser::TagValue::setLanguage
void setLanguage(const std::string &language)
Sets the language.
Definition: tagvalue.h:582
TagParser::TagValue::language
const std::string & language() const
Returns the language.
Definition: tagvalue.h:572
TagParser::TagDataType::Integer
@ Integer