Mind encoding when converting TagValue to pos
This commit is contained in:
parent
b76d35acfd
commit
6b705d5652
|
@ -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.
|
* \returns Returns the genre index or -1 if the specified string does not denote a genre index.
|
||||||
*/
|
*/
|
||||||
template<class stringtype>
|
template<class stringtype>
|
||||||
int parseGenreIndex(const stringtype &denotation, bool isBigEndian = false)
|
int parseGenreIndex(const stringtype &denotation)
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for(auto c : denotation) {
|
for(auto c : denotation) {
|
||||||
if(sizeof(typename stringtype::value_type) == 2 && isBigEndian != CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN) {
|
|
||||||
c = swapOrder(static_cast<uint16>(c));
|
|
||||||
}
|
|
||||||
if(index == -1) {
|
if(index == -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case ' ':
|
case ' ':
|
||||||
|
@ -272,7 +269,7 @@ void Id3v2Frame::parse(BinaryReader &reader, const uint32 version, const uint32
|
||||||
int genreIndex;
|
int genreIndex;
|
||||||
if(characterSize(dataEncoding) > 1) {
|
if(characterSize(dataEncoding) > 1) {
|
||||||
auto genreDenotation = parseWideString(buffer.get() + 1, m_dataSize - 1, dataEncoding);
|
auto genreDenotation = parseWideString(buffer.get() + 1, m_dataSize - 1, dataEncoding);
|
||||||
genreIndex = parseGenreIndex(genreDenotation, dataEncoding == TagTextEncoding::Utf16BigEndian);
|
genreIndex = parseGenreIndex(genreDenotation);
|
||||||
} else {
|
} else {
|
||||||
auto genreDenotation = parseString(buffer.get() + 1, m_dataSize - 1, dataEncoding);
|
auto genreDenotation = parseString(buffer.get() + 1, m_dataSize - 1, dataEncoding);
|
||||||
genreIndex = parseGenreIndex(genreDenotation);
|
genreIndex = parseGenreIndex(genreDenotation);
|
||||||
|
@ -675,20 +672,7 @@ u16string Id3v2Frame::parseWideString(const char *buffer, size_t dataSize, TagTe
|
||||||
{
|
{
|
||||||
auto substr = parseSubstring(buffer, dataSize, encoding, addWarnings);
|
auto substr = parseSubstring(buffer, dataSize, encoding, addWarnings);
|
||||||
u16string res(reinterpret_cast<u16string::const_pointer>(get<0>(substr)), get<1>(substr) / 2);
|
u16string res(reinterpret_cast<u16string::const_pointer>(get<0>(substr)), get<1>(substr) / 2);
|
||||||
if(encoding !=
|
TagValue::ensureHostByteOrder(res, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
tagvalue.cpp
26
tagvalue.cpp
|
@ -249,8 +249,9 @@ PositionInSet TagValue::toPositionInSet() const
|
||||||
return PositionInSet(string(m_ptr.get(), m_size));
|
return PositionInSet(string(m_ptr.get(), m_size));
|
||||||
case TagTextEncoding::Utf16LittleEndian:
|
case TagTextEncoding::Utf16LittleEndian:
|
||||||
case TagTextEncoding::Utf16BigEndian:
|
case TagTextEncoding::Utf16BigEndian:
|
||||||
// FIXME: Ensure endianness is correctly
|
u16string u16str(reinterpret_cast<char16_t *>(m_ptr.get()), m_size / 2);
|
||||||
return PositionInSet(u16string(reinterpret_cast<char16_t *>(m_ptr.get()), m_size / 2));
|
ensureHostByteOrder(u16str, m_encoding);
|
||||||
|
return PositionInSet(u16str);
|
||||||
}
|
}
|
||||||
case TagDataType::Integer:
|
case TagDataType::Integer:
|
||||||
case TagDataType::PositionInSet:
|
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<uint16>(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns an empty TagValue.
|
* \brief Returns an empty TagValue.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
|
||||||
class Tag;
|
class Tag;
|
||||||
|
class Id3v2Frame;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Specifies the text encoding.
|
* \brief Specifies the text encoding.
|
||||||
|
@ -62,6 +63,8 @@ enum class TagDataType : unsigned int
|
||||||
|
|
||||||
class TAG_PARSER_EXPORT TagValue
|
class TAG_PARSER_EXPORT TagValue
|
||||||
{
|
{
|
||||||
|
friend class Id3v2Frame; // FIXME: make ensureHostByteOrder() public in next minor release
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor, destructor
|
// constructor, destructor
|
||||||
TagValue();
|
TagValue();
|
||||||
|
@ -124,7 +127,8 @@ public:
|
||||||
|
|
||||||
|
|
||||||
private:
|
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<char[]> m_ptr;
|
std::unique_ptr<char[]> m_ptr;
|
||||||
std::string::size_type m_size;
|
std::string::size_type m_size;
|
||||||
|
|
Loading…
Reference in New Issue