Tag Parser  8.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/traits.h>
10 
11 #include <cstring>
12 #include <iosfwd>
13 #include <memory>
14 #include <string>
15 
16 namespace TagParser {
17 
18 class Tag;
19 class Id3v2Frame;
20 
24 enum class TagTextEncoding : unsigned int {
25  Latin1,
26  Utf8,
30 };
31 
36 constexpr int characterSize(TagTextEncoding encoding)
37 {
38  switch (encoding) {
41  return 1;
44  return 2;
45  default:
46  return 0;
47  }
48 }
49 
53 enum class TagDataType : unsigned int {
54  Text,
55  Integer,
58  TimeSpan,
59  DateTime,
60  Picture,
61  Binary,
62  Undefined
63 };
64 
66 public:
67  // constructor, destructor
68  TagValue();
69  TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
72  TagValue(
73  const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
74  TagValue(int value);
75  TagValue(const char *data, std::size_t length, TagDataType type = TagDataType::Undefined, TagTextEncoding encoding = TagTextEncoding::Latin1);
76  TagValue(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
78  TagValue(PositionInSet value);
79  TagValue(const TagValue &other);
80  TagValue(TagValue &&other) = default;
81  ~TagValue();
82 
83  // operators
84  TagValue &operator=(const TagValue &other);
85  TagValue &operator=(TagValue &&other) = default;
86  bool operator==(const TagValue &other) const;
87  bool operator!=(const TagValue &other) const;
88 
89  // methods
90  bool isEmpty() const;
91  void clearData();
92  void clearMetadata();
93  void clearDataAndMetadata();
94  TagDataType type() const;
95  std::string toString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
96  void toString(std::string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
97  std::u16string toWString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
98  void toWString(std::u16string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
99  int32 toInteger() const;
100  int toStandardGenreIndex() const;
101  PositionInSet toPositionInSet() const;
102  ChronoUtilities::TimeSpan toTimeSpan() const;
103  ChronoUtilities::DateTime toDateTime() const;
104  std::size_t dataSize() const;
105  char *dataPointer();
106  const char *dataPointer() const;
107  const std::string &description() const;
108  void setDescription(const std::string &value, TagTextEncoding encoding = TagTextEncoding::Latin1);
109  const std::string &mimeType() const;
110  void setMimeType(const std::string &mimeType);
111  const std::string &language() const;
112  void setLanguage(const std::string &language);
113  bool isLabeledAsReadonly() const;
114  void setReadonly(bool readOnly);
115  TagTextEncoding dataEncoding() const;
116  void convertDataEncoding(TagTextEncoding encoding);
117  void convertDataEncodingForTag(const Tag *tag);
118  TagTextEncoding descriptionEncoding() const;
119  static const TagValue &empty();
120 
121  void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
123  void assignText(
124  const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
125  void assignInteger(int value);
126  void assignStandardGenreIndex(int index);
127  void assignData(const char *data, std::size_t length, TagDataType type = TagDataType::Binary, TagTextEncoding encoding = TagTextEncoding::Latin1);
128  void assignData(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
130  void assignPosition(PositionInSet value);
131  void assignTimeSpan(ChronoUtilities::TimeSpan value);
132  void assignDateTime(ChronoUtilities::DateTime value);
133 
134  static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding);
135  static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding);
136  template <typename ContainerType,
137  Traits::EnableIf<Traits::IsIteratable<ContainerType>,
138  std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>>
139  * = nullptr>
140  static std::vector<std::string> toStrings(const ContainerType &values, TagTextEncoding encoding = TagTextEncoding::Utf8);
141 
142 private:
143  std::unique_ptr<char[]> m_ptr;
144  std::size_t m_size;
145  std::string m_desc;
146  std::string m_mimeType;
147  std::string m_language;
148  TagDataType m_type;
149  TagTextEncoding m_encoding;
150  TagTextEncoding m_descEncoding;
151  bool m_labeledAsReadonly;
152 };
153 
158  : m_size(0)
159  , m_type(TagDataType::Undefined)
160  , m_encoding(TagTextEncoding::Latin1)
161  , m_descEncoding(TagTextEncoding::Latin1)
162  , m_labeledAsReadonly(false)
163 {
164 }
165 
170 {
171 }
172 
183 inline TagValue::TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding, TagTextEncoding convertTo)
184  : m_descEncoding(TagTextEncoding::Latin1)
185  , m_labeledAsReadonly(false)
186 {
187  assignText(text, textSize, textEncoding, convertTo);
188 }
189 
199 inline TagValue::TagValue(const char *text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
200 {
201  assignText(text, std::strlen(text), textEncoding, convertTo);
202 }
203 
213 inline TagValue::TagValue(const std::string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
214  : m_descEncoding(TagTextEncoding::Latin1)
215  , m_labeledAsReadonly(false)
216 {
217  assignText(text, textEncoding, convertTo);
218 }
219 
223 inline TagValue::TagValue(int value)
224  : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::Integer)
225 {
226 }
227 
238 inline TagValue::TagValue(const char *data, std::size_t length, TagDataType type, TagTextEncoding encoding)
239  : m_size(length)
240  , m_type(type)
241  , m_encoding(encoding)
242  , m_descEncoding(TagTextEncoding::Latin1)
243  , m_labeledAsReadonly(false)
244 {
245  if (length) {
246  if (type == TagDataType::Text) {
247  stripBom(data, m_size, encoding);
248  }
249  m_ptr = std::make_unique<char[]>(m_size);
250  std::copy(data, data + m_size, m_ptr.get());
251  }
252 }
253 
266 inline TagValue::TagValue(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type, TagTextEncoding encoding)
267  : m_size(length)
268  , m_type(type)
269  , m_encoding(encoding)
270  , m_descEncoding(TagTextEncoding::Latin1)
271  , m_labeledAsReadonly(false)
272 {
273  if (length) {
274  m_ptr = move(data);
275  }
276 }
277 
283  : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet)
284 {
285 }
286 
291 inline bool TagValue::operator!=(const TagValue &other) const
292 {
293  return !(*this == other);
294 }
295 
305 inline void TagValue::assignText(const std::string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
306 {
307  assignText(text.data(), text.size(), textEncoding, convertTo);
308 }
309 
314 {
315  if (value.isNull()) {
317  clearData();
318  } else {
319  assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet);
320  }
321 }
322 
327 {
328  assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::TimeSpan);
329 }
330 
335 {
336  assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTime);
337 }
338 
345 {
346  assignInteger(index);
348 }
349 
354 {
355  return m_type;
356 }
357 
365 inline std::string TagValue::toString(TagTextEncoding encoding) const
366 {
367  std::string res;
368  toString(res, encoding);
369  return res;
370 }
371 
378 inline std::u16string TagValue::toWString(TagTextEncoding encoding) const
379 {
380  std::u16string res;
381  toWString(res, encoding);
382  return res;
383 }
384 
389 inline bool TagValue::isEmpty() const
390 {
391  return m_ptr == nullptr || m_size == 0;
392 }
393 
400 inline void TagValue::clearData()
401 {
402  m_size = 0;
403  m_ptr.reset();
404 }
405 
412 {
413  clearData();
414  clearMetadata();
415 }
416 
421 inline std::size_t TagValue::dataSize() const
422 {
423  return m_size;
424 }
425 
432 inline char *TagValue::dataPointer()
433 {
434  return m_ptr.get();
435 }
436 
437 inline const char *TagValue::dataPointer() const
438 {
439  return m_ptr.get();
440 }
441 
448 inline const std::string &TagValue::description() const
449 {
450  return m_desc;
451 }
452 
461 inline void TagValue::setDescription(const std::string &value, TagTextEncoding encoding)
462 {
463  m_desc = value;
464  m_descEncoding = encoding;
465 }
466 
472 inline const std::string &TagValue::mimeType() const
473 {
474  return m_mimeType;
475 }
476 
482 inline void TagValue::setMimeType(const std::string &mimeType)
483 {
484  m_mimeType = mimeType;
485 }
486 
492 inline const std::string &TagValue::language() const
493 {
494  return m_language;
495 }
496 
502 inline void TagValue::setLanguage(const std::string &language)
503 {
504  m_language = language;
505 }
506 
515 inline bool TagValue::isLabeledAsReadonly() const
516 {
517  return m_labeledAsReadonly;
518 }
519 
528 inline void TagValue::setReadonly(bool readOnly)
529 {
530  m_labeledAsReadonly = readOnly;
531 }
532 
539 {
540  return m_encoding;
541 }
542 
549 {
550  return m_descEncoding;
551 }
552 
558 template <typename ContainerType,
559  Traits::EnableIf<Traits::IsIteratable<ContainerType>,
560  std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>> *>
561 std::vector<std::string> TagValue::toStrings(const ContainerType &values, TagTextEncoding encoding)
562 {
563  std::vector<std::string> res;
564  res.reserve(values.size());
565  for (const auto &value : values) {
566  res.emplace_back(Traits::dereferenceMaybe(value).toString(encoding));
567  }
568  return res;
569 }
570 
571 } // namespace TagParser
572 
573 #endif // TAG_PARSER_TAGVALUE_H
TagTextEncoding dataEncoding() const
Returns the data encoding.
Definition: tagvalue.h:538
static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding)
Strips the byte order mask from the specified text.
Definition: tagvalue.cpp:697
The Tag class is used to store, read and write tag information.
Definition: tag.h:98
TagTextEncoding descriptionEncoding() const
Returns the description encoding.
Definition: tagvalue.h:548
const std::string & description() const
Returns the description.
Definition: tagvalue.h:448
void setMimeType(const std::string &mimeType)
Sets the MIME type.
Definition: tagvalue.h:482
void setReadonly(bool readOnly)
Sets whether the TagValue is labeled as read-only.
Definition: tagvalue.h:528
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:378
bool operator!=(const TagValue &other) const
Returns whether both instances are not equal.
Definition: tagvalue.h:291
The PositionInSet class describes the position of an element in a set which consists of a certain num...
Definition: positioninset.h:21
TagDataType
Specifies the data type.
Definition: tagvalue.h:53
void clearDataAndMetadata()
Wipes assigned data including meta data.
Definition: tagvalue.h:411
constexpr bool operator==(byte lhs, FlacMetaDataBlockType type)
Definition: flacmetadata.h:19
constexpr TAG_PARSER_EXPORT const char * language()
bool isEmpty() const
Returns an indication whether an value is assigned.
Definition: tagvalue.h:389
const std::string & mimeType() const
Returns the MIME type.
Definition: tagvalue.h:472
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
Definition: tagvalue.h:421
constexpr bool operator!=(byte lhs, FlacMetaDataBlockType type)
Definition: flacmetadata.h:24
void assignDateTime(ChronoUtilities::DateTime value)
Assigns the given DateTime value.
Definition: tagvalue.h:334
void clearMetadata()
Wipes assigned meta data.
Definition: tagvalue.cpp:161
const std::string & language() const
Returns the language.
Definition: tagvalue.h:492
void assignPosition(PositionInSet value)
Assigns the given PositionInSet value.
Definition: tagvalue.h:313
void assignStandardGenreIndex(int index)
Assigns the given standard genre index to be assigned.
Definition: tagvalue.h:344
~TagValue()
Destroys the TagValue.
Definition: tagvalue.h:169
TagValue()
Constructs an empty TagValue.
Definition: tagvalue.h:157
void setLanguage(const std::string &language)
Sets the language.
Definition: tagvalue.h:502
char * dataPointer()
Returns a pointer to the raw data assigned to the current instance.
Definition: tagvalue.h:432
constexpr bool isNull() const
Returns an indication whether both the element position and total element count is 0.
Definition: positioninset.h:92
TagDataType type() const
Returns the type of the assigned value.
Definition: tagvalue.h:353
void assignInteger(int value)
Assigns the given integer value.
Definition: tagvalue.cpp:639
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:588
void clearData()
Clears the assigned data.
Definition: tagvalue.h:400
bool isLabeledAsReadonly() const
Returns an indication whether the value is labeled as read-only.
Definition: tagvalue.h:515
void setDescription(const std::string &value, TagTextEncoding encoding=TagTextEncoding::Latin1)
Sets the description.
Definition: tagvalue.h:461
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
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:561
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:365
void assignTimeSpan(ChronoUtilities::TimeSpan value)
Assigns the given TimeSpan value.
Definition: tagvalue.h:326
constexpr int characterSize(TagTextEncoding encoding)
Returns the size of one character for the specified encoding in bytes.
Definition: tagvalue.h:36
The TagValue class wraps values of different types.
Definition: tagvalue.h:65
constexpr TAG_PARSER_EXPORT const char * description()
TagTextEncoding
Specifies the text encoding.
Definition: tagvalue.h:24
Contains all classes and functions of the TagInfo library.
Definition: aaccodebook.h:9
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.