6 #include <c++utilities/conversion/binaryconversion.h> 7 #include <c++utilities/conversion/conversionexception.h> 8 #include <c++utilities/conversion/stringbuilder.h> 9 #include <c++utilities/conversion/stringconversion.h> 16 using namespace ConversionUtilities;
17 using namespace ChronoUtilities;
27 case TagDataType::Text:
29 case TagDataType::Integer:
31 case TagDataType::PositionInSet:
32 return "position in set";
33 case TagDataType::StandardGenreIndex:
35 case TagDataType::TimeSpan:
39 case TagDataType::Picture:
41 case TagDataType::Binary:
60 : m_size(other.m_size)
61 , m_desc(other.m_desc)
62 , m_mimeType(other.m_mimeType)
63 , m_language(other.m_language)
64 , m_type(other.m_type)
65 , m_encoding(other.m_encoding)
66 , m_descEncoding(other.m_descEncoding)
67 , m_labeledAsReadonly(other.m_labeledAsReadonly)
70 m_ptr = make_unique<char[]>(m_size);
71 std::copy(other.m_ptr.get(), other.m_ptr.get() + other.m_size, m_ptr.get());
83 m_size = other.m_size;
84 m_type = other.m_type;
85 m_desc = other.m_desc;
86 m_mimeType = other.m_mimeType;
87 m_language = other.m_language;
88 m_labeledAsReadonly = other.m_labeledAsReadonly;
89 m_encoding = other.m_encoding;
90 m_descEncoding = other.m_descEncoding;
94 m_ptr = make_unique<char[]>(m_size);
95 std::copy(other.m_ptr.get(), other.m_ptr.get() + other.m_size, m_ptr.get());
111 if (m_desc != other.m_desc || (!m_desc.empty() && m_descEncoding != other.m_descEncoding) || m_mimeType != other.m_mimeType
112 || m_language != other.m_language || m_labeledAsReadonly != other.m_labeledAsReadonly) {
117 if (m_type == other.m_type) {
120 if (m_size != other.m_size && m_encoding != other.m_encoding) {
124 return strncmp(m_ptr.get(), other.m_ptr.get(), m_size) == 0;
138 if (m_size != other.m_size) {
141 return strncmp(m_ptr.get(), other.m_ptr.get(), m_size) == 0;
149 }
catch (
const ConversionException &) {
166 m_labeledAsReadonly =
false;
184 switch (m_encoding) {
188 return ConversionUtilities::bufferToNumber<int32>(m_ptr.get(), m_size);
191 u16string u16str(reinterpret_cast<char16_t *>(m_ptr.get()), m_size / 2);
193 return ConversionUtilities::stringToNumber<int32>(u16str);
198 if (m_size ==
sizeof(int32)) {
199 return *reinterpret_cast<int32 *>(m_ptr.get());
201 throw ConversionException(
"Can not convert assigned data to integer because the data size is not appropriate.");
203 throw ConversionException(argsToString(
"Can not convert ",
tagDataTypeString(m_type),
" to integer."));
222 }
catch (
const ConversionException &) {
234 if (m_size !=
sizeof(int32)) {
235 throw ConversionException(
"The assigned index/integer is of unappropriate size.");
237 index = static_cast<int>(*reinterpret_cast<int32 *>(m_ptr.get()));
240 throw ConversionException(argsToString(
"Can not convert ",
tagDataTypeString(m_type),
" to genre index."));
243 throw ConversionException(
"The assigned number is not a valid standard genre index.");
260 switch (m_encoding) {
267 u16string u16str(reinterpret_cast<char16_t *>(m_ptr.get()), m_size / 2);
275 return PositionInSet(*(reinterpret_cast<int32 *>(m_ptr.get())));
276 case 2 *
sizeof(int32):
277 return PositionInSet(*(reinterpret_cast<int32 *>(m_ptr.get())), *(reinterpret_cast<int32 *>(m_ptr.get() +
sizeof(int32))));
279 throw ConversionException(
"The size of the assigned data is not appropriate.");
282 throw ConversionException(argsToString(
"Can not convert ",
tagDataTypeString(m_type),
" to position in set."));
303 return TimeSpan(*(reinterpret_cast<int32 *>(m_ptr.get())));
305 return TimeSpan(*(reinterpret_cast<int64 *>(m_ptr.get())));
307 throw ConversionException(
"The size of the assigned integer is not appropriate for conversion to time span.");
310 throw ConversionException(argsToString(
"Can not convert ",
tagDataTypeString(m_type),
" to time span."));
329 if (m_size ==
sizeof(int32)) {
330 return DateTime(*(reinterpret_cast<uint32 *>(m_ptr.get())));
331 }
else if (m_size ==
sizeof(int64)) {
332 return DateTime(*(reinterpret_cast<uint64 *>(m_ptr.get())));
334 throw ConversionException(
"The size of the assigned integer is not appropriate for conversion to date time.");
337 throw ConversionException(argsToString(
"Can not convert ",
tagDataTypeString(m_type),
" to date time."));
346 switch (tagTextEncoding) {
348 return make_pair(
"ISO-8859-1", 1.0f);
350 return make_pair(
"UTF-8", 1.0f);
352 return make_pair(
"UTF-16LE", 2.0f);
354 return make_pair(
"UTF-16BE", 2.0f);
356 return make_pair(
nullptr, 0.0f);
371 if (m_encoding == encoding) {
375 StringData encodedData;
381 encodedData = convertLatin1ToUtf8(m_ptr.get(), m_size);
384 encodedData = convertUtf16LEToUtf8(m_ptr.get(), m_size);
387 encodedData = convertUtf16BEToUtf8(m_ptr.get(), m_size);
397 = convertString(inputParameter.first, outputParameter.first, m_ptr.get(), m_size, outputParameter.second / inputParameter.second);
401 m_ptr = make_unique<char[]>(m_size = encodedData.second);
402 copy(encodedData.first.get(), encodedData.first.get() + encodedData.second, m_ptr.get());
404 m_encoding = encoding;
437 result.assign(m_ptr.get(), m_size);
439 StringData encodedData;
445 encodedData = convertLatin1ToUtf8(m_ptr.get(), m_size);
448 encodedData = convertUtf16LEToUtf8(m_ptr.get(), m_size);
451 encodedData = convertUtf16BEToUtf8(m_ptr.get(), m_size);
461 = convertString(inputParameter.first, outputParameter.first, m_ptr.get(), m_size, outputParameter.second / inputParameter.second);
464 result.assign(encodedData.first.get(), encodedData.second);
468 result = ConversionUtilities::numberToString(
toInteger());
478 result.assign(genreName);
480 throw ConversionException(
"No string representation for the assigned standard genre index available.");
491 throw ConversionException(argsToString(
"Can not convert ",
tagDataTypeString(m_type),
" to string."));
495 : convertUtf8ToUtf16BE(result.data(), result.size());
496 result.assign(encodedData.first.get(), encodedData.second);
514 string regularStrRes;
518 result.assign(reinterpret_cast<const char16_t *>(m_ptr.get()), m_size /
sizeof(char16_t));
520 StringData encodedData;
526 encodedData = convertLatin1ToUtf8(m_ptr.get(), m_size);
529 encodedData = convertUtf16LEToUtf8(m_ptr.get(), m_size);
532 encodedData = convertUtf16BEToUtf8(m_ptr.get(), m_size);
542 = convertString(inputParameter.first, outputParameter.first, m_ptr.get(), m_size, outputParameter.second / inputParameter.second);
545 result.assign(reinterpret_cast<const char16_t *>(encodedData.first.get()), encodedData.second /
sizeof(char16_t));
549 regularStrRes = ConversionUtilities::numberToString(
toInteger());
557 regularStrRes.clear();
559 regularStrRes.assign(genreName);
561 throw ConversionException(
"No string representation for the assigned standard genre index available.");
569 throw ConversionException(argsToString(
"Can not convert ",
tagDataTypeString(m_type),
" to string."));
573 : convertUtf8ToUtf16BE(regularStrRes.data(), result.size());
574 result.assign(reinterpret_cast<const char16_t *>(encodedData.first.get()), encodedData.second /
sizeof(
const char16_t));
593 stripBom(text, textSize, textEncoding);
601 m_ptr = make_unique<char[]>(m_size = textSize);
602 copy(text, text + textSize, m_ptr.get());
606 StringData encodedData;
607 switch (textEncoding) {
612 encodedData = convertUtf8ToLatin1(text, textSize);
615 encodedData = convertUtf8ToUtf16LE(text, textSize);
618 encodedData = convertUtf8ToUtf16BE(text, textSize);
627 encodedData = convertString(inputParameter.first, outputParameter.first, text, textSize, outputParameter.second / inputParameter.second);
631 m_ptr = make_unique<char[]>(m_size = encodedData.second);
632 copy(encodedData.first.get(), encodedData.first.get() + encodedData.second, m_ptr.get());
641 m_size =
sizeof(value);
642 m_ptr = make_unique<char[]>(m_size);
643 std::copy(reinterpret_cast<const char *>(&value), reinterpret_cast<const char *>(&value) + m_size, m_ptr.get());
661 if (length > m_size) {
662 m_ptr = make_unique<char[]>(length);
665 std::copy(data, data + length, m_ptr.get());
671 m_encoding = encoding;
690 m_encoding = encoding;
701 if ((length >= 3) && (ConversionUtilities::BE::toUInt24(text) == 0x00EFBBBF)) {
707 if ((length >= 2) && (ConversionUtilities::LE::toUInt16(text) == 0xFEFF)) {
713 if ((length >= 2) && (ConversionUtilities::BE::toUInt16(text) == 0xFEFF)) {
728 if (currentEncoding !=
729 #
if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
731 #elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
734 #error
"Host byte order not supported" 737 for (
auto &c : u16str) {
738 c = swapOrder(static_cast<uint16>(c));
749 return emptyTagValue;
TagTextEncoding dataEncoding() const
Returns the data encoding.
StringType toString() const
Returns the string representation of the current PositionInSet.
static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding)
Strips the byte order mask from the specified text.
The Tag class is used to store, read and write tag information.
pair< const char *, float > encodingParameter(TagTextEncoding tagTextEncoding)
Returns the encoding parameter (name of the character set and bytes per character) for the specified ...
virtual TagTextEncoding proposedTextEncoding() const
Returns the proposed text encoding.
std::u16string toWString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::wstring representation.
The PositionInSet class describes the position of an element in a set which consists of a certain num...
TagDataType
Specifies the data type.
static const char * stringFromIndex(int index)
Returns the genre name for the specified numerical denotation as C-style string.
int toStandardGenreIndex() const
Converts the value of the current TagValue object to its equivalent standard genre index.
static int indexFromString(const std::string &genre)
Returns the numerical denotation of the specified genre or -1 if genre is unknown.
bool isEmpty() const
Returns an indication whether an value is assigned.
static constexpr int emptyGenreIndex()
Returns the preferred genre index to indicate that no genre is set at all.
void clearMetadata()
Wipes assigned meta data.
ChronoUtilities::TimeSpan toTimeSpan() const
Converts the value of the current TagValue object to its equivalent TimeSpan representation.
static const TagValue & empty()
Returns an empty TagValue.
PositionInSet toPositionInSet() const
Converts the value of the current TagValue object to its equivalent PositionInSet representation.
bool operator==(const TagValue &other) const
Returns whether both instances are equal.
const char * tagDataTypeString(TagDataType dataType)
Returns the string representation of the specified dataType.
void convertDataEncoding(TagTextEncoding encoding)
Converts the currently assigned text value to the specified encoding.
TagDataType type() const
Returns the type of the assigned value.
ChronoUtilities::DateTime toDateTime() const
Converts the value of the current TagValue object to its equivalent DateTime representation.
int32 toInteger() const
Converts the value of the current TagValue object to its equivalent integer representation.
void assignInteger(int value)
Assigns the given integer value.
void assignText(const char *text, std::size_t textSize, TagTextEncoding textEncoding=TagTextEncoding::Latin1, TagTextEncoding convertTo=TagTextEncoding::Unspecified)
Assigns a copy of the given text.
static constexpr bool isEmptyGenre(int index)
Returns whether the genre index indicates the genre field is not set at all.
TagValue & operator=(const TagValue &other)
Assigns the value of another TagValue to the current instance.
void assignData(const char *data, std::size_t length, TagDataType type=TagDataType::Binary, TagTextEncoding encoding=TagTextEncoding::Latin1)
static constexpr bool isIndexSupported(int index)
Returns an indication whether the specified numerical denotation is supported by this class.
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
void convertDataEncodingForTag(const Tag *tag)
Ensures the encoding of the currently assigned text value is supported by the specified tag.
The TagValue class wraps values of different types.
TagTextEncoding
Specifies the text encoding.
Contains all classes and functions of the TagInfo library.
virtual bool canEncodingBeUsed(TagTextEncoding encoding) const
Returns an indication whether the specified encoding can be used to provide string values for the tag...
static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding)
Ensures the byte-order of the specified UTF-16 string matches the byte-order of the machine.