Tag Parser 12.3.1
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
Loading...
Searching...
No Matches
tagvalue.h
Go to the documentation of this file.
1#ifndef TAG_PARSER_TAGVALUE_H
2#define TAG_PARSER_TAGVALUE_H
3
4#include "./localehelper.h"
5#include "./positioninset.h"
6#include "./tagtype.h"
7
8#include <c++utilities/chrono/datetime.h>
9#include <c++utilities/chrono/timespan.h>
10#include <c++utilities/conversion/binaryconversion.h>
11#include <c++utilities/misc/flagenumclass.h>
12#include <c++utilities/misc/traits.h>
13
14#include <cstdint>
15#include <cstring>
16#include <iosfwd>
17#include <memory>
18#include <string>
19#include <unordered_map>
20
21namespace TagParser {
22
23class Tag;
24class Id3v2Frame;
25
29enum class TagTextEncoding : unsigned int {
30 Latin1,
31 Utf8,
35};
36
43enum class TagValueFlags : std::uint64_t {
44 None,
45 ReadOnly,
46};
47
48} // namespace TagParser
49
51
52namespace TagParser {
53
58constexpr int characterSize(TagTextEncoding encoding)
59{
60 switch (encoding) {
63 return 1;
66 return 2;
67 default:
68 return 0;
69 }
70}
71
74 std::string user;
76 double rating = 0.0;
78 std::uint64_t playCounter = 0;
82 TagType scale = TagType::Unspecified;
83
84 bool scaleTo(TagType targetScale);
85 Popularity scaled(TagType targetScale) const;
86 std::string toString() const;
87 static Popularity fromString(std::string_view str);
88 static Popularity fromString(std::string_view str, TagType scale);
89
91 bool isEmpty() const
92 {
93 return user.empty() && rating == 0.0 && !playCounter;
94 }
95
100 bool operator==(const Popularity &other) const
101 {
102 return playCounter == other.playCounter && rating == other.rating && user == other.user && scale == other.scale;
103 }
104};
105
109inline Popularity Popularity::scaled(TagType targetScale) const
110{
111 auto copy = *this;
112 copy.scaleTo(targetScale);
113 return copy;
114}
115
119enum class TagDataType : unsigned int {
120 Text,
121 Integer,
124 TimeSpan,
125 DateTime,
126 Picture,
127 Binary,
128 Undefined,
129 Popularity,
132};
133
134TAG_PARSER_EXPORT std::string_view tagDataTypeString(TagDataType dataType);
135
139enum class TagValueComparisionFlags : unsigned int {
140 None,
141 CaseInsensitive = 0x1,
142 IgnoreMetaData = 0x2,
143};
144
145struct TagValuePrivate;
146
147class TAG_PARSER_EXPORT TagValue {
148public:
149 // constructor, destructor
150 explicit TagValue();
151 explicit TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
152 TagTextEncoding convertTo = TagTextEncoding::Unspecified);
153 explicit TagValue(
154 const char *text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
155 explicit TagValue(
156 const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
157 explicit TagValue(
158 std::string_view text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
159 explicit TagValue(int value);
160 explicit TagValue(std::uint64_t value);
161 explicit TagValue(
162 const char *data, std::size_t length, TagDataType type = TagDataType::Undefined, TagTextEncoding encoding = TagTextEncoding::Latin1);
163 explicit TagValue(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
164 TagTextEncoding encoding = TagTextEncoding::Latin1);
165 explicit TagValue(PositionInSet value);
166 explicit TagValue(CppUtilities::DateTime value);
167 explicit TagValue(const CppUtilities::DateTimeExpression &value);
168 explicit TagValue(CppUtilities::TimeSpan value);
169 explicit TagValue(const Popularity &value);
170 TagValue(const TagValue &other);
172 ~TagValue();
173
174 // operators
175 TagValue &operator=(const TagValue &other);
177 bool operator==(const TagValue &other) const;
178 bool operator!=(const TagValue &other) const;
179 operator bool() const;
180
181 // methods
182 bool isNull() const;
183 bool isEmpty() const;
184 void clearData();
185 void clearMetadata();
186 void clearDataAndMetadata();
187 TagDataType type() const;
188 std::string toString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
189 std::string toDisplayString() const;
190 void toString(std::string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
191 std::u16string toWString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
192 void toWString(std::u16string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
193 std::int32_t toInteger() const;
194 std::uint64_t toUnsignedInteger() const;
195 int toStandardGenreIndex() const;
196 PositionInSet toPositionInSet() const;
197 CppUtilities::TimeSpan toTimeSpan() const;
198 CppUtilities::DateTime toDateTime() const;
199 CppUtilities::DateTimeExpression toDateTimeExpression() const;
200 Popularity toPopularity() const;
201 Popularity toScaledPopularity(TagType scale = TagType::Unspecified) const;
202 std::size_t dataSize() const;
203 char *dataPointer();
204 const char *dataPointer() const;
205 std::string_view data() const;
206 const std::string &description() const;
207 void setDescription(std::string_view value, TagTextEncoding encoding = TagTextEncoding::Latin1);
208 const std::string &mimeType() const;
209 void setMimeType(std::string_view mimeType);
210 const Locale &locale() const;
211 Locale &locale();
212 void setLocale(const Locale &locale);
213 TagValueFlags flags() const;
214 void setFlags(TagValueFlags flags);
215 bool isLabeledAsReadonly() const;
216 void setReadonly(bool readOnly);
217 const std::unordered_map<std::string, std::string> &nativeData() const;
218 std::unordered_map<std::string, std::string> &nativeData();
219 TagTextEncoding dataEncoding() const;
220 void convertDataEncoding(TagTextEncoding encoding);
221 void convertDataEncodingForTag(const Tag *tag);
222 TagTextEncoding descriptionEncoding() const;
223 void convertDescriptionEncoding(TagTextEncoding encoding);
224 static const TagValue &empty();
225
226 void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
227 TagTextEncoding convertTo = TagTextEncoding::Unspecified);
228 void assignText(
229 const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
230 void assignText(
231 std::string_view text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
232 void assignInteger(int value);
233 void assignUnsignedInteger(std::uint64_t value);
234 void assignStandardGenreIndex(int index);
235 void assignData(const char *data, std::size_t length, TagDataType type = TagDataType::Binary, TagTextEncoding encoding = TagTextEncoding::Latin1);
236 void assignData(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
237 TagTextEncoding encoding = TagTextEncoding::Latin1);
238 void assignPosition(PositionInSet value);
239 void assignTimeSpan(CppUtilities::TimeSpan value);
240 void assignDateTime(CppUtilities::DateTime value);
241 void assignDateTimeExpression(const CppUtilities::DateTimeExpression &value);
242 void assignPopularity(const Popularity &value);
243
244 static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding);
245 static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding);
246 template <typename ContainerType,
247 CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsIteratable<ContainerType>,
248 std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>>
249 * = nullptr>
250 static std::vector<std::string> toStrings(const ContainerType &values, TagTextEncoding encoding = TagTextEncoding::Utf8);
251 bool compareTo(const TagValue &other, TagValueComparisionFlags options = TagValueComparisionFlags::None) const;
252 bool compareData(const TagValue &other, bool ignoreCase = false) const;
253 static bool compareData(const std::string &data1, const std::string &data2, bool ignoreCase = false);
254 static bool compareData(const char *data1, std::size_t size1, const char *data2, std::size_t size2, bool ignoreCase = false);
255
256private:
257 std::unique_ptr<char[]> m_ptr;
258 std::size_t m_size;
259 std::string m_desc;
260 std::string m_mimeType;
261 Locale m_locale;
262 std::unordered_map<std::string, std::string> m_nativeData;
263 TagDataType m_type;
264 TagTextEncoding m_encoding;
265 TagTextEncoding m_descEncoding;
266 TagValueFlags m_flags;
267 std::unique_ptr<TagValuePrivate> m_p;
268};
269
273inline TagValue::TagValue(int value)
274 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::Integer)
275{
276}
277
281inline TagParser::TagValue::TagValue(std::uint64_t value)
282 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::UnsignedInteger)
283{
284}
285
290 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet)
291{
292}
293
297inline TagValue::TagValue(CppUtilities::DateTime value)
298 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTime)
299{
300}
301
305inline TagValue::TagValue(const CppUtilities::DateTimeExpression &value)
306 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTimeExpression)
307{
308}
309
313inline TagValue::TagValue(CppUtilities::TimeSpan value)
314 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::TimeSpan)
315{
316}
317
321inline TagValue::TagValue(const Popularity &value)
322 : TagValue()
323{
324 assignPopularity(value);
325}
326
331inline bool TagValue::operator==(const TagValue &other) const
332{
334}
335
340inline bool TagValue::operator!=(const TagValue &other) const
341{
343}
344
349inline TagParser::TagValue::operator bool() const
350{
351 return !isEmpty();
352}
353
363inline void TagValue::assignText(const std::string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
364{
365 assignText(text.data(), text.size(), textEncoding, convertTo);
366}
367
377inline void TagValue::assignText(std::string_view text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
378{
379 assignText(text.data(), text.size(), textEncoding, convertTo);
380}
381
386{
387 if (value.isNull()) {
389 clearData();
390 } else {
391 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet);
392 }
393}
394
398inline void TagValue::assignTimeSpan(CppUtilities::TimeSpan value)
399{
400 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::TimeSpan);
401}
402
406inline void TagValue::assignDateTime(CppUtilities::DateTime value)
407{
408 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTime);
409}
410
414inline void TagParser::TagValue::assignDateTimeExpression(const CppUtilities::DateTimeExpression &value)
415{
416 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTimeExpression);
417}
418
425{
426 assignInteger(index);
428}
429
434{
435 return m_type;
436}
437
450inline std::string TagValue::toString(TagTextEncoding encoding) const
451{
452 std::string res;
453 toString(res, encoding);
454 return res;
455}
456
463inline std::u16string TagValue::toWString(TagTextEncoding encoding) const
464{
465 std::u16string res;
466 toWString(res, encoding);
467 return res;
468}
469
477inline bool TagValue::isNull() const
478{
479 return m_ptr == nullptr;
480}
481
490inline bool TagValue::isEmpty() const
491{
492 return m_ptr == nullptr || m_size == 0;
493}
494
502{
503 m_size = 0;
504 m_ptr.reset();
505}
506
513{
514 clearData();
516}
517
522inline std::size_t TagValue::dataSize() const
523{
524 return m_size;
525}
526
534{
535 return m_ptr.get();
536}
537
538inline const char *TagValue::dataPointer() const
539{
540 return m_ptr.get();
541}
542
546inline std::string_view TagValue::data() const
547{
548 return std::string_view(m_ptr.get(), m_size);
549}
550
561inline const std::string &TagValue::description() const
562{
563 return m_desc;
564}
565
577inline void TagValue::setDescription(std::string_view value, TagTextEncoding encoding)
578{
579 m_desc = value;
580 m_descEncoding = encoding;
581}
582
590inline const std::string &TagValue::mimeType() const
591{
592 return m_mimeType;
593}
594
602inline void TagValue::setMimeType(std::string_view mimeType)
603{
604 m_mimeType = mimeType;
605}
606
616inline const Locale &TagValue::locale() const
617{
618 return m_locale;
619}
620
631{
632 return m_locale;
633}
634
644inline void TagValue::setLocale(const Locale &locale)
645{
646 m_locale = locale;
647}
648
654{
655 return m_flags;
656}
657
663{
664 m_flags = flags;
665}
666
677{
678 return m_flags & TagValueFlags::ReadOnly;
679}
680
690inline void TagValue::setReadonly(bool readOnly)
691{
692 CppUtilities::modFlagEnum(m_flags, TagValueFlags::ReadOnly, readOnly);
693}
694
699inline const std::unordered_map<std::string, std::string> &TagValue::nativeData() const
700{
701 return m_nativeData;
702}
703
708inline std::unordered_map<std::string, std::string> &TagValue::nativeData()
709{
710 return m_nativeData;
711}
712
719{
720 return m_encoding;
721}
722
729{
730 return m_descEncoding;
731}
732
738template <typename ContainerType,
739 CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsIteratable<ContainerType>,
740 std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>> *>
741std::vector<std::string> TagValue::toStrings(const ContainerType &values, TagTextEncoding encoding)
742{
743 std::vector<std::string> res;
744 res.reserve(values.size());
745 for (const auto &value : values) {
746 res.emplace_back(CppUtilities::Traits::dereferenceMaybe(value).toString(encoding));
747 }
748 return res;
749}
750
754inline bool TagValue::compareData(const TagValue &other, bool ignoreCase) const
755{
756 return compareData(m_ptr.get(), m_size, other.m_ptr.get(), other.m_size, ignoreCase);
757}
758
762inline bool TagValue::compareData(const std::string &data1, const std::string &data2, bool ignoreCase)
763{
764 return compareData(data1.data(), data1.size(), data2.data(), data2.size(), ignoreCase);
765}
766
767} // namespace TagParser
768
770
771#endif // TAG_PARSER_TAGVALUE_H
The PositionInSet class describes the position of an element in a set which consists of a certain num...
constexpr bool isNull() const
Returns an indication whether both the element position and total element count is 0.
The TagValue class wraps values of different types.
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:754
void setMimeType(std::string_view mimeType)
Sets the MIME type.
Definition tagvalue.h:602
void setFlags(TagValueFlags flags)
Sets the flags.
Definition tagvalue.h:662
const std::unordered_map< std::string, std::string > & nativeData() const
Holds tag format specific meta-data for that field which does not fit into any of the other meta-data...
Definition tagvalue.h:699
void clearMetadata()
Wipes assigned meta data.
Definition tagvalue.cpp:500
void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding=TagTextEncoding::Latin1, TagTextEncoding convertTo=TagTextEncoding::Unspecified)
Assigns a copy of the given text.
const std::string & mimeType() const
Returns the MIME type.
Definition tagvalue.h:590
void assignInteger(int value)
Assigns the given integer value.
bool compareTo(const TagValue &other, TagValueComparisionFlags options=TagValueComparisionFlags::None) const
Returns whether both instances are equal.
Definition tagvalue.cpp:354
std::string toDisplayString() const
CppUtilities::DateTimeExpression toDateTimeExpression() const
TagTextEncoding dataEncoding() const
Returns the data encoding.
Definition tagvalue.h:718
void assignPosition(PositionInSet value)
Assigns the given PositionInSet value.
Definition tagvalue.h:385
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
bool operator==(const TagValue &other) const
Returns whether both instances are equal.
Definition tagvalue.h:331
void setDescription(std::string_view value, TagTextEncoding encoding=TagTextEncoding::Latin1)
Sets the description.
Definition tagvalue.h:577
TagValue(TagValue &&other)
TagDataType type() const
Returns the type of the assigned value.
Definition tagvalue.h:433
void assignPopularity(const Popularity &value)
Assigns the specified popularity value.
void assignTimeSpan(CppUtilities::TimeSpan value)
Assigns the given TimeSpan value.
Definition tagvalue.h:398
void assignDateTimeExpression(const CppUtilities::DateTimeExpression &value)
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:741
void clearDataAndMetadata()
Wipes assigned data including meta data.
Definition tagvalue.h:512
void assignData(std::unique_ptr< char[]> &&data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
void assignDateTime(CppUtilities::DateTime value)
Assigns the given DateTime value.
Definition tagvalue.h:406
bool isLabeledAsReadonly() const
Returns an indication whether the value is labeled as read-only.
Definition tagvalue.h:676
TagValueFlags flags() const
Returns the flags.
Definition tagvalue.h:653
bool operator!=(const TagValue &other) const
Returns whether both instances are not equal.
Definition tagvalue.h:340
std::string_view data() const
Returns the currently assigned raw data.
Definition tagvalue.h:546
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
Definition tagvalue.h:522
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:463
TagTextEncoding descriptionEncoding() const
Returns the description encoding.
Definition tagvalue.h:728
TagValue(std::uint64_t value)
void assignStandardGenreIndex(int index)
Assigns the given standard genre index to be assigned.
Definition tagvalue.h:424
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:450
bool isNull() const
Returns whether no value is assigned at all.
Definition tagvalue.h:477
void setLocale(const Locale &locale)
Sets the setLocale.
Definition tagvalue.h:644
void setReadonly(bool readOnly)
Sets whether the TagValue is labeled as read-only.
Definition tagvalue.h:690
void clearData()
Clears the assigned data.
Definition tagvalue.h:501
TagValue & operator=(TagValue &&other)
bool isEmpty() const
Returns whether no or an empty value is assigned.
Definition tagvalue.h:490
const std::string & description() const
Returns the description.
Definition tagvalue.h:561
const Locale & locale() const
Returns the locale.
Definition tagvalue.h:616
TagValue()
Constructs an empty TagValue.
Definition tagvalue.cpp:156
char * dataPointer()
Returns a pointer to the raw data assigned to the current instance.
Definition tagvalue.h:533
The Tag class is used to store, read and write tag information.
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
Definition global.h:14
Contains all classes and functions of the TagInfo library.
Definition aaccodebook.h:10
constexpr int characterSize(TagTextEncoding encoding)
Returns the size of one character for the specified encoding in bytes.
Definition tagvalue.h:58
TAG_PARSER_EXPORT std::string_view tagDataTypeString(TagDataType dataType)
Returns the string representation of the specified dataType.
Definition tagvalue.cpp:31
TagTextEncoding
Specifies the text encoding.
Definition tagvalue.h:29
constexpr bool operator!=(std::uint8_t lhs, FlacMetaDataBlockType type)
constexpr bool operator==(std::uint8_t lhs, FlacMetaDataBlockType type)
TagType
Specifies the tag type.
Definition tagtype.h:11
TagValueComparisionFlags
The TagValueComparisionOption enum specifies options for TagValue::compareTo().
Definition tagvalue.h:139
TagValueFlags
Specifies additional flags about the tag value.
Definition tagvalue.h:43
TagDataType
Specifies the data type.
Definition tagvalue.h:119
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(TagParser, TagParser::TagCreationFlags)
The Locale struct specifies a language and/or a country using one or more LocaleDetail objects.
The Popularity class contains a value for ID3v2's "Popularimeter" field.
std::string user
The user who gave the rating / played the file, e.g. identified by e-mail address.
Definition tagvalue.h:74
bool isEmpty() const
Returns whether the Popularity is empty. The scale and zero-values don't count.
Definition tagvalue.h:91
bool operator==(const Popularity &other) const
Returns whether two instances are equal.
Definition tagvalue.h:100
std::uint64_t playCounter
Play counter specific to the user.
Definition tagvalue.h:78
bool scaleTo(TagType targetScale)
Scales the rating from the current scale to targetScale.
Popularity scaled(TagType targetScale) const
Same as Popularity::scaleTo() but returns a new object.
Definition tagvalue.h:109
TagType scale
Specifies the scale used for rating by the tag defining that scale.
Definition tagvalue.h:82
double rating
The rating on a tag type specific scale.
Definition tagvalue.h:76
static Popularity fromString(std::string_view str, TagType scale)