From 6b705d56525372cfaaca0b10d8208020660f435e Mon Sep 17 00:00:00 2001 From: Martchus Date: Wed, 31 May 2017 00:53:42 +0200 Subject: [PATCH] Mind encoding when converting TagValue to pos --- id3/id3v2frame.cpp | 22 +++------------------- tagvalue.cpp | 26 ++++++++++++++++++++++++-- tagvalue.h | 6 +++++- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/id3/id3v2frame.cpp b/id3/id3v2frame.cpp index 199e2c1..2b0af7f 100644 --- a/id3/id3v2frame.cpp +++ b/id3/id3v2frame.cpp @@ -65,13 +65,10 @@ Id3v2Frame::Id3v2Frame(const identifierType &id, const TagValue &value, const by * \returns Returns the genre index or -1 if the specified string does not denote a genre index. */ template -int parseGenreIndex(const stringtype &denotation, bool isBigEndian = false) +int parseGenreIndex(const stringtype &denotation) { int index = -1; for(auto c : denotation) { - if(sizeof(typename stringtype::value_type) == 2 && isBigEndian != CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN) { - c = swapOrder(static_cast(c)); - } if(index == -1) { switch(c) { case ' ': @@ -272,7 +269,7 @@ void Id3v2Frame::parse(BinaryReader &reader, const uint32 version, const uint32 int genreIndex; if(characterSize(dataEncoding) > 1) { auto genreDenotation = parseWideString(buffer.get() + 1, m_dataSize - 1, dataEncoding); - genreIndex = parseGenreIndex(genreDenotation, dataEncoding == TagTextEncoding::Utf16BigEndian); + genreIndex = parseGenreIndex(genreDenotation); } else { auto genreDenotation = parseString(buffer.get() + 1, m_dataSize - 1, dataEncoding); genreIndex = parseGenreIndex(genreDenotation); @@ -675,20 +672,7 @@ u16string Id3v2Frame::parseWideString(const char *buffer, size_t dataSize, TagTe { auto substr = parseSubstring(buffer, dataSize, encoding, addWarnings); u16string res(reinterpret_cast(get<0>(substr)), get<1>(substr) / 2); - if(encoding != - #if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN) - TagTextEncoding::Utf16LittleEndian - #elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN) - TagTextEncoding::Utf16BigEndian - #else - # error "Host byte order not supported" - #endif - ) { - // ensure byte order matches host byte order - for(auto &c : res) { - c = ((c >> 8) & 0x00FF) | ((c << 8) & 0xFF00); - } - } + TagValue::ensureHostByteOrder(res, encoding); return res; } diff --git a/tagvalue.cpp b/tagvalue.cpp index d09f5fa..fcbf5db 100644 --- a/tagvalue.cpp +++ b/tagvalue.cpp @@ -249,8 +249,9 @@ PositionInSet TagValue::toPositionInSet() const return PositionInSet(string(m_ptr.get(), m_size)); case TagTextEncoding::Utf16LittleEndian: case TagTextEncoding::Utf16BigEndian: - // FIXME: Ensure endianness is correctly - return PositionInSet(u16string(reinterpret_cast(m_ptr.get()), m_size / 2)); + u16string u16str(reinterpret_cast(m_ptr.get()), m_size / 2); + ensureHostByteOrder(u16str, m_encoding); + return PositionInSet(u16str); } case TagDataType::Integer: case TagDataType::PositionInSet: @@ -705,6 +706,27 @@ void TagValue::stripBom(const char *&text, size_t &length, TagTextEncoding encod } } +/*! + * \brief Ensures the byte-order of the specified UTF-16 string matches the byte-order of the machine. + * \remarks Does nothing if \a currentEncoding already matches the byte-order of the machine. + */ +void TagValue::ensureHostByteOrder(u16string &u16str, TagTextEncoding currentEncoding) +{ + if(currentEncoding != + #if defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN) + TagTextEncoding::Utf16LittleEndian + #elif defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN) + TagTextEncoding::Utf16BigEndian + #else + # error "Host byte order not supported" + #endif + ) { + for(auto &c : u16str) { + c = swapOrder(static_cast(c)); + } + } +} + /*! * \brief Returns an empty TagValue. */ diff --git a/tagvalue.h b/tagvalue.h index 12d8b58..7e2c539 100644 --- a/tagvalue.h +++ b/tagvalue.h @@ -14,6 +14,7 @@ namespace Media { class Tag; +class Id3v2Frame; /*! * \brief Specifies the text encoding. @@ -62,6 +63,8 @@ enum class TagDataType : unsigned int class TAG_PARSER_EXPORT TagValue { + friend class Id3v2Frame; // FIXME: make ensureHostByteOrder() public in next minor release + public: // constructor, destructor TagValue(); @@ -124,7 +127,8 @@ public: private: - void stripBom(const char *&text, size_t &length, TagTextEncoding encoding); + static void stripBom(const char *&text, size_t &length, TagTextEncoding encoding); + static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding); std::unique_ptr m_ptr; std::string::size_type m_size;