Tag Parser 12.0.0
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
137enum class TagValueComparisionFlags : unsigned int {
138 None,
139 CaseInsensitive = 0x1,
140 IgnoreMetaData = 0x2,
141};
142
143struct TagValuePrivate;
144
146public:
147 // constructor, destructor
148 explicit TagValue();
149 explicit TagValue(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
150 TagTextEncoding convertTo = TagTextEncoding::Unspecified);
151 explicit TagValue(
152 const char *text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
153 explicit TagValue(
154 const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
155 explicit TagValue(
156 std::string_view text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
157 explicit TagValue(int value);
158 explicit TagValue(std::uint64_t value);
159 explicit TagValue(
160 const char *data, std::size_t length, TagDataType type = TagDataType::Undefined, TagTextEncoding encoding = TagTextEncoding::Latin1);
161 explicit TagValue(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
162 TagTextEncoding encoding = TagTextEncoding::Latin1);
163 explicit TagValue(PositionInSet value);
164 explicit TagValue(CppUtilities::DateTime value);
165 explicit TagValue(const CppUtilities::DateTimeExpression &value);
166 explicit TagValue(CppUtilities::TimeSpan value);
167 explicit TagValue(const Popularity &value);
168 TagValue(const TagValue &other);
170 ~TagValue();
171
172 // operators
173 TagValue &operator=(const TagValue &other);
175 bool operator==(const TagValue &other) const;
176 bool operator!=(const TagValue &other) const;
177 operator bool() const;
178
179 // methods
180 bool isNull() const;
181 bool isEmpty() const;
182 void clearData();
183 void clearMetadata();
184 void clearDataAndMetadata();
185 TagDataType type() const;
186 std::string toString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
187 std::string toDisplayString() const;
188 void toString(std::string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
189 std::u16string toWString(TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
190 void toWString(std::u16string &result, TagTextEncoding encoding = TagTextEncoding::Unspecified) const;
191 std::int32_t toInteger() const;
192 std::uint64_t toUnsignedInteger() const;
193 int toStandardGenreIndex() const;
194 PositionInSet toPositionInSet() const;
195 CppUtilities::TimeSpan toTimeSpan() const;
196 CppUtilities::DateTime toDateTime() const;
197 CppUtilities::DateTimeExpression toDateTimeExpression() const;
198 Popularity toPopularity() const;
199 Popularity toScaledPopularity(TagType scale = TagType::Unspecified) const;
200 std::size_t dataSize() const;
201 char *dataPointer();
202 const char *dataPointer() const;
203 std::string_view data() const;
204 const std::string &description() const;
205 void setDescription(std::string_view value, TagTextEncoding encoding = TagTextEncoding::Latin1);
206 const std::string &mimeType() const;
207 void setMimeType(std::string_view mimeType);
208 const Locale &locale() const;
209 Locale &locale();
210 void setLocale(const Locale &locale);
211 TagValueFlags flags() const;
212 void setFlags(TagValueFlags flags);
213 bool isLabeledAsReadonly() const;
214 void setReadonly(bool readOnly);
215 const std::unordered_map<std::string, std::string> &nativeData() const;
216 std::unordered_map<std::string, std::string> &nativeData();
217 TagTextEncoding dataEncoding() const;
218 void convertDataEncoding(TagTextEncoding encoding);
219 void convertDataEncodingForTag(const Tag *tag);
220 TagTextEncoding descriptionEncoding() const;
221 void convertDescriptionEncoding(TagTextEncoding encoding);
222 static const TagValue &empty();
223
224 void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding = TagTextEncoding::Latin1,
225 TagTextEncoding convertTo = TagTextEncoding::Unspecified);
226 void assignText(
227 const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
228 void assignText(
229 std::string_view text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified);
230 void assignInteger(int value);
231 void assignUnsignedInteger(std::uint64_t value);
232 void assignStandardGenreIndex(int index);
233 void assignData(const char *data, std::size_t length, TagDataType type = TagDataType::Binary, TagTextEncoding encoding = TagTextEncoding::Latin1);
234 void assignData(std::unique_ptr<char[]> &&data, std::size_t length, TagDataType type = TagDataType::Binary,
235 TagTextEncoding encoding = TagTextEncoding::Latin1);
236 void assignPosition(PositionInSet value);
237 void assignTimeSpan(CppUtilities::TimeSpan value);
238 void assignDateTime(CppUtilities::DateTime value);
239 void assignDateTimeExpression(const CppUtilities::DateTimeExpression &value);
240 void assignPopularity(const Popularity &value);
241
242 static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding);
243 static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding);
244 template <typename ContainerType,
245 CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsIteratable<ContainerType>,
246 std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>>
247 * = nullptr>
248 static std::vector<std::string> toStrings(const ContainerType &values, TagTextEncoding encoding = TagTextEncoding::Utf8);
249 bool compareTo(const TagValue &other, TagValueComparisionFlags options = TagValueComparisionFlags::None) const;
250 bool compareData(const TagValue &other, bool ignoreCase = false) const;
251 static bool compareData(const std::string &data1, const std::string &data2, bool ignoreCase = false);
252 static bool compareData(const char *data1, std::size_t size1, const char *data2, std::size_t size2, bool ignoreCase = false);
253
254private:
255 std::unique_ptr<char[]> m_ptr;
256 std::size_t m_size;
257 std::string m_desc;
258 std::string m_mimeType;
259 Locale m_locale;
260 std::unordered_map<std::string, std::string> m_nativeData;
261 TagDataType m_type;
262 TagTextEncoding m_encoding;
263 TagTextEncoding m_descEncoding;
264 TagValueFlags m_flags;
265 std::unique_ptr<TagValuePrivate> m_p;
266};
267
271inline TagValue::TagValue(int value)
272 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::Integer)
273{
274}
275
279inline TagParser::TagValue::TagValue(std::uint64_t value)
280 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::UnsignedInteger)
281{
282}
283
288 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet)
289{
290}
291
295inline TagValue::TagValue(CppUtilities::DateTime value)
296 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTime)
297{
298}
299
303inline TagValue::TagValue(const CppUtilities::DateTimeExpression &value)
304 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTimeExpression)
305{
306}
307
311inline TagValue::TagValue(CppUtilities::TimeSpan value)
312 : TagValue(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::TimeSpan)
313{
314}
315
319inline TagValue::TagValue(const Popularity &value)
320 : TagValue()
321{
322 assignPopularity(value);
323}
324
329inline bool TagValue::operator==(const TagValue &other) const
330{
332}
333
338inline bool TagValue::operator!=(const TagValue &other) const
339{
341}
342
347inline TagParser::TagValue::operator bool() const
348{
349 return !isEmpty();
350}
351
361inline void TagValue::assignText(const std::string &text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
362{
363 assignText(text.data(), text.size(), textEncoding, convertTo);
364}
365
375inline void TagValue::assignText(std::string_view text, TagTextEncoding textEncoding, TagTextEncoding convertTo)
376{
377 assignText(text.data(), text.size(), textEncoding, convertTo);
378}
379
384{
385 if (value.isNull()) {
387 clearData();
388 } else {
389 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::PositionInSet);
390 }
391}
392
396inline void TagValue::assignTimeSpan(CppUtilities::TimeSpan value)
397{
398 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::TimeSpan);
399}
400
404inline void TagValue::assignDateTime(CppUtilities::DateTime value)
405{
406 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTime);
407}
408
412inline void TagParser::TagValue::assignDateTimeExpression(const CppUtilities::DateTimeExpression &value)
413{
414 assignData(reinterpret_cast<const char *>(&value), sizeof(value), TagDataType::DateTimeExpression);
415}
416
423{
424 assignInteger(index);
426}
427
432{
433 return m_type;
434}
435
448inline std::string TagValue::toString(TagTextEncoding encoding) const
449{
450 std::string res;
451 toString(res, encoding);
452 return res;
453}
454
461inline std::u16string TagValue::toWString(TagTextEncoding encoding) const
462{
463 std::u16string res;
464 toWString(res, encoding);
465 return res;
466}
467
475inline bool TagValue::isNull() const
476{
477 return m_ptr == nullptr;
478}
479
488inline bool TagValue::isEmpty() const
489{
490 return m_ptr == nullptr || m_size == 0;
491}
492
500{
501 m_size = 0;
502 m_ptr.reset();
503}
504
511{
512 clearData();
514}
515
520inline std::size_t TagValue::dataSize() const
521{
522 return m_size;
523}
524
532{
533 return m_ptr.get();
534}
535
536inline const char *TagValue::dataPointer() const
537{
538 return m_ptr.get();
539}
540
544inline std::string_view TagValue::data() const
545{
546 return std::string_view(m_ptr.get(), m_size);
547}
548
559inline const std::string &TagValue::description() const
560{
561 return m_desc;
562}
563
575inline void TagValue::setDescription(std::string_view value, TagTextEncoding encoding)
576{
577 m_desc = value;
578 m_descEncoding = encoding;
579}
580
588inline const std::string &TagValue::mimeType() const
589{
590 return m_mimeType;
591}
592
600inline void TagValue::setMimeType(std::string_view mimeType)
601{
602 m_mimeType = mimeType;
603}
604
614inline const Locale &TagValue::locale() const
615{
616 return m_locale;
617}
618
629{
630 return m_locale;
631}
632
642inline void TagValue::setLocale(const Locale &locale)
643{
644 m_locale = locale;
645}
646
652{
653 return m_flags;
654}
655
661{
662 m_flags = flags;
663}
664
675{
676 return m_flags & TagValueFlags::ReadOnly;
677}
678
688inline void TagValue::setReadonly(bool readOnly)
689{
690 CppUtilities::modFlagEnum(m_flags, TagValueFlags::ReadOnly, readOnly);
691}
692
697inline const std::unordered_map<std::string, std::string> &TagValue::nativeData() const
698{
699 return m_nativeData;
700}
701
706inline std::unordered_map<std::string, std::string> &TagValue::nativeData()
707{
708 return m_nativeData;
709}
710
717{
718 return m_encoding;
719}
720
727{
728 return m_descEncoding;
729}
730
736template <typename ContainerType,
737 CppUtilities::Traits::EnableIf<CppUtilities::Traits::IsIteratable<ContainerType>,
738 std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>> *>
739std::vector<std::string> TagValue::toStrings(const ContainerType &values, TagTextEncoding encoding)
740{
741 std::vector<std::string> res;
742 res.reserve(values.size());
743 for (const auto &value : values) {
744 res.emplace_back(CppUtilities::Traits::dereferenceMaybe(value).toString(encoding));
745 }
746 return res;
747}
748
752inline bool TagValue::compareData(const TagValue &other, bool ignoreCase) const
753{
754 return compareData(m_ptr.get(), m_size, other.m_ptr.get(), other.m_size, ignoreCase);
755}
756
760inline bool TagValue::compareData(const std::string &data1, const std::string &data2, bool ignoreCase)
761{
762 return compareData(data1.data(), data1.size(), data2.data(), data2.size(), ignoreCase);
763}
764
765} // namespace TagParser
766
768
769#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.
Definition tagvalue.h:145
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:752
void setMimeType(std::string_view mimeType)
Sets the MIME type.
Definition tagvalue.h:600
void setFlags(TagValueFlags flags)
Sets the flags.
Definition tagvalue.h:660
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:697
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:588
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
TagTextEncoding dataEncoding() const
Returns the data encoding.
Definition tagvalue.h:716
void assignPosition(PositionInSet value)
Assigns the given PositionInSet value.
Definition tagvalue.h:383
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:329
void setDescription(std::string_view value, TagTextEncoding encoding=TagTextEncoding::Latin1)
Sets the description.
Definition tagvalue.h:575
TagValue(TagValue &&other)
TagDataType type() const
Returns the type of the assigned value.
Definition tagvalue.h:431
void assignPopularity(const Popularity &value)
Assigns the specified popularity value.
void assignTimeSpan(CppUtilities::TimeSpan value)
Assigns the given TimeSpan value.
Definition tagvalue.h:396
void assignDateTimeExpression(const CppUtilities::DateTimeExpression &value)
Assigns the given DateTimeExpression value.
Definition tagvalue.h:412
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:739
void clearDataAndMetadata()
Wipes assigned data including meta data.
Definition tagvalue.h:510
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:404
bool isLabeledAsReadonly() const
Returns an indication whether the value is labeled as read-only.
Definition tagvalue.h:674
TagValueFlags flags() const
Returns the flags.
Definition tagvalue.h:651
bool operator!=(const TagValue &other) const
Returns whether both instances are not equal.
Definition tagvalue.h:338
std::string_view data() const
Returns the currently assigned raw data.
Definition tagvalue.h:544
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
Definition tagvalue.h:520
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:461
TagTextEncoding descriptionEncoding() const
Returns the description encoding.
Definition tagvalue.h:726
void assignStandardGenreIndex(int index)
Assigns the given standard genre index to be assigned.
Definition tagvalue.h:422
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:448
bool isNull() const
Returns whether no value is assigned at all.
Definition tagvalue.h:475
void setLocale(const Locale &locale)
Sets the setLocale.
Definition tagvalue.h:642
void setReadonly(bool readOnly)
Sets whether the TagValue is labeled as read-only.
Definition tagvalue.h:688
void clearData()
Clears the assigned data.
Definition tagvalue.h:499
TagValue & operator=(TagValue &&other)
bool isEmpty() const
Returns whether no or an empty value is assigned.
Definition tagvalue.h:488
const std::string & description() const
Returns the description.
Definition tagvalue.h:559
const Locale & locale() const
Returns the locale.
Definition tagvalue.h:614
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:531
The Tag class is used to store, read and write tag information.
Definition tag.h:166
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
Definition global.h:13
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
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:137
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.
Definition tagvalue.h:72
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