From 88a0871784542f05b820efa19be28e870acce44d Mon Sep 17 00:00:00 2001 From: Tsuda kageyu Date: Tue, 16 Apr 2013 04:06:29 +0900 Subject: [PATCH] Bug fix for #132 --- taglib/toolkit/taglib.h | 12 - taglib/toolkit/tbyteswap.cpp | 32 +++ taglib/toolkit/tbyteswap.h | 6 + taglib/toolkit/tbytevector.cpp | 389 ++++++++++++++++----------------- taglib/toolkit/tbytevector.h | 5 + taglib/toolkit/tstring.cpp | 32 +-- 6 files changed, 233 insertions(+), 243 deletions(-) diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h index 696174e9..dd4ee69d 100755 --- a/taglib/toolkit/taglib.h +++ b/taglib/toolkit/taglib.h @@ -64,18 +64,6 @@ # define TAGLIB_ATOMIC_GCC #endif -// Detect CPU endian at compile time rather than run time if possible. -// This is a poor list. Hope someone enrich it. -#if (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) \ - || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) \ - || (defined(__clang__) && (defined(__i386__) || defined(__x86_64__))) -# define TAGLIB_LITTLE_ENDIAN -/* -#elif .... -# define TAGLIB_BIG_ENDIAN -*/ -#endif - // Check the widths of integral types. #if UCHAR_MAX != 255U diff --git a/taglib/toolkit/tbyteswap.cpp b/taglib/toolkit/tbyteswap.cpp index cf0c9b9b..7aeea902 100644 --- a/taglib/toolkit/tbyteswap.cpp +++ b/taglib/toolkit/tbyteswap.cpp @@ -59,6 +59,20 @@ #endif +// Determines CPU byte order at compile time rather than run time if possible. + +#if (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) \ + || (defined(__GNUC__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) \ + || (defined(__clang__) && defined(__LITTLE_ENDIAN__)) +# define TAGLIB_LITTLE_ENDIAN + +#elif (defined(__GNUC__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) \ + || (defined(__clang__) && defined(__BIG_ENDIAN__)) +# define TAGLIB_BIG_ENDIAN + +#endif + + namespace TagLib { ushort byteSwap16(ushort x) @@ -155,6 +169,24 @@ namespace TagLib | ((x & 0x000000000000ff00ull) << 40) | ((x & 0x00000000000000ffull) << 56); +#endif + } + + bool isLittleEndianSystem() + { +#if defined(TAGLIB_LITTLE_ENDIAN) + + return true; + +#elif defined(TAGLIB_BIG_ENDIAN) + + return false; + +#else + + ushort x = 1; + return (*reinterpret_cast(&x) == 1); + #endif } } diff --git a/taglib/toolkit/tbyteswap.h b/taglib/toolkit/tbyteswap.h index ed20125c..6121414c 100644 --- a/taglib/toolkit/tbyteswap.h +++ b/taglib/toolkit/tbyteswap.h @@ -44,6 +44,12 @@ namespace TagLib * Converts the byte order of \a x as a 64-bit unsigned integer. */ ulonglong byteSwap64(ulonglong x); + + /*! + * Detects the system byte order. + * Returns \a true if little endian, \a false if big endian. + */ + bool isLittleEndianSystem(); } #endif diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index 63aad50f..510e6cf6 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -34,226 +34,208 @@ // This is a bit ugly to keep writing over and over again. // A rather obscure feature of the C++ spec that I hadn't thought of that makes -// working with C libs much more effecient. There's more here: +// working with C libs much more efficient. There's more here: // // http://www.informit.com/isapi/product_id~{9C84DAB4-FE6E-49C5-BB0A-FB50331233EA}/content/index.asp #define DATA(x) (&(x->data->data[0])) namespace TagLib { - static const char hexTable[17] = "0123456789abcdef"; - static const uint crcTable[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, - 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, - 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, - 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, - 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, - 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, - 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, - 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, - 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, - 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, - 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, - 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, - 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, - 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, - 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, - 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, - 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 - }; +static const char hexTable[17] = "0123456789abcdef"; - /*! - * A templatized straightforward find that works with the types - * std::vector::iterator and std::vector::reverse_iterator. - */ - template - int findChar( - const TIterator dataBegin, const TIterator dataEnd, - char c, uint offset, int byteAlign) - { - const size_t dataSize = dataEnd - dataBegin; - if(dataSize == 0 || offset > dataSize - 1) - return -1; - - // n % 0 is invalid - - if(byteAlign == 0) - return -1; - - for(TIterator it = dataBegin + offset; it < dataEnd; it += byteAlign) { - if(*it == c) - return (it - dataBegin); - } +static const uint crcTable[256] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 +}; +/*! + * A templatized straightforward find that works with the types + * std::vector::iterator and std::vector::reverse_iterator. + */ +template +int findChar( + const TIterator dataBegin, const TIterator dataEnd, + char c, uint offset, int byteAlign) +{ + const size_t dataSize = dataEnd - dataBegin; + if(dataSize == 0 || offset > dataSize - 1) return -1; + + // n % 0 is invalid + + if(byteAlign == 0) + return -1; + + for(TIterator it = dataBegin + offset; it < dataEnd; it += byteAlign) { + if(*it == c) + return (it - dataBegin); } - /*! - * A templatized KMP find that works with the types - * std::vector::iterator and std::vector::reverse_iterator. - */ - template - int findVector( - const TIterator dataBegin, const TIterator dataEnd, - const TIterator patternBegin, const TIterator patternEnd, - uint offset, int byteAlign) + return -1; +} + +/*! + * A templatized KMP find that works with the types + * std::vector::iterator and std::vector::reverse_iterator. + */ +template +int findVector( + const TIterator dataBegin, const TIterator dataEnd, + const TIterator patternBegin, const TIterator patternEnd, + uint offset, int byteAlign) +{ + const size_t dataSize = dataEnd - dataBegin; + const size_t patternSize = patternEnd - patternBegin; + if(patternSize > dataSize || offset > dataSize - 1) + return -1; + + // n % 0 is invalid + + if(byteAlign == 0) + return -1; + + // Special case that pattern contains just single char. + + if(patternSize == 1) + return findChar(dataBegin, dataEnd, *patternBegin, offset, byteAlign); + + size_t lastOccurrence[256]; + + for(size_t i = 0; i < 256; ++i) + lastOccurrence[i] = patternSize; + + for(size_t i = 0; i < patternSize - 1; ++i) + lastOccurrence[static_cast(*(patternBegin + i))] = patternSize - i - 1; + + for(TIterator it = dataBegin + patternSize - 1 + offset; + it < dataEnd; + it += lastOccurrence[static_cast(*it)]) { - const size_t dataSize = dataEnd - dataBegin; - const size_t patternSize = patternEnd - patternBegin; - if(patternSize > dataSize || offset > dataSize - 1) - return -1; + TIterator itBuffer = it; + TIterator itPattern = patternBegin + patternSize - 1; - // n % 0 is invalid - - if(byteAlign == 0) - return -1; - - // Special case that pattern contains just single char. - - if(patternSize == 1) - return findChar(dataBegin, dataEnd, *patternBegin, offset, byteAlign); - - size_t lastOccurrence[256]; - - for(size_t i = 0; i < 256; ++i) - lastOccurrence[i] = patternSize; - - for(size_t i = 0; i < patternSize - 1; ++i) - lastOccurrence[static_cast(*(patternBegin + i))] = patternSize - i - 1; - - for(TIterator it = dataBegin + patternSize - 1 + offset; - it < dataEnd; - it += lastOccurrence[static_cast(*it)]) + while(*itBuffer == *itPattern) { - TIterator itBuffer = it; - TIterator itPattern = patternBegin + patternSize - 1; - - while(*itBuffer == *itPattern) + if(itPattern == patternBegin) { - if(itPattern == patternBegin) - { - if((itBuffer - dataBegin - offset) % byteAlign == 0) - return (itBuffer - dataBegin); - else - break; - } - - --itBuffer; - --itPattern; + if((itBuffer - dataBegin - offset) % byteAlign == 0) + return (itBuffer - dataBegin); + else + break; } - } - return -1; + --itBuffer; + --itPattern; + } } - template - T byteSwap(T x) - { - // There should be all counterparts of to*() and from*() overloads for integral types. - debug("byteSwap() -- Non specialized version should not be called"); + return -1; +} + +template +T byteSwap(T x) +{ + // There should be all counterparts of to*() and from*() overloads for integral types. + debug("byteSwap() -- Non specialized version should not be called"); + return 0; +} + +template <> +unsigned short byteSwap(unsigned short x) +{ + return byteSwap16(x); +} + +template <> +unsigned int byteSwap(unsigned int x) +{ + return byteSwap32(x); +} + +template <> +unsigned long long byteSwap(unsigned long long x) +{ + return byteSwap64(x); +} + +template +T toNumber(const ByteVector &v, bool swapBytes) +{ + if(v.isEmpty()) { + debug("toNumber() -- data is empty, returning 0"); return 0; } - template <> - unsigned short byteSwap(unsigned short x) + const size_t size = sizeof(T); + + if(v.size() >= size) { - return byteSwap16(x); + if(swapBytes) + return byteSwap(*reinterpret_cast(v.data())); + else + return *reinterpret_cast(v.data()); } - template <> - unsigned int byteSwap(unsigned int x) - { - return byteSwap32(x); - } + const uint last = v.size() > size ? size - 1 : v.size() - 1; + T sum = 0; + for(uint i = 0; i <= last; i++) + sum |= (T) uchar(v[i]) << ((swapBytes ? last - i : i) * 8); - template <> - unsigned long long byteSwap(unsigned long long x) - { - return byteSwap64(x); - } - - template - T toNumber(const ByteVector &v, bool mostSignificantByteFirst) - { - if(v.isEmpty()) { - debug("toNumber() -- data is empty, returning 0"); - return 0; - } - - const size_t size = sizeof(T); - -#if defined(TAGLIB_MSC_BYTESWAP) || defined(TAGLIB_GCC_BYTESWAP) - - if(v.size() >= size) - { - if(mostSignificantByteFirst) - return byteSwap(*reinterpret_cast(v.data())); - else - return *reinterpret_cast(v.data()); - } - -#endif - - const uint last = v.size() > size ? size - 1 : v.size() - 1; - T sum = 0; - for(uint i = 0; i <= last; i++) - sum |= (T) uchar(v[i]) << ((mostSignificantByteFirst ? last - i : i) * 8); - - return sum; - } - - template - ByteVector fromNumber(T value, bool mostSignificantByteFirst) - { - const size_t size = sizeof(T); - -#if defined(TAGLIB_MSC_BYTESWAP) || defined(TAGLIB_GCC_BYTESWAP) - - if(mostSignificantByteFirst) - value = byteSwap(value); - - return ByteVector(reinterpret_cast(&value), size); - -#else - - ByteVector v(size, 0); - for(uint i = 0; i < size; i++) - v[i] = uchar(value >> ((mostSignificantByteFirst ? size - 1 - i : i) * 8) & 0xff); - - return v; - -#endif - } + return sum; } -using namespace TagLib; +template +ByteVector fromNumber(T value, bool swapBytes) +{ + const size_t size = sizeof(T); + + if(swapBytes) + value = byteSwap(value); + + return ByteVector(reinterpret_cast(&value), size); +} class DataPrivate : public RefCounter { @@ -266,7 +248,7 @@ public: : data(v.begin() + offset, v.begin() + offset + length) { } - + DataPrivate(uint len, char c) : data(len, c) { @@ -371,17 +353,17 @@ ByteVector ByteVector::fromCString(const char *s, uint length) ByteVector ByteVector::fromUInt(uint value, bool mostSignificantByteFirst) { - return fromNumber(value, mostSignificantByteFirst); + return fromNumber(value, (isLittleEndian == mostSignificantByteFirst)); } ByteVector ByteVector::fromShort(short value, bool mostSignificantByteFirst) { - return fromNumber(value, mostSignificantByteFirst); + return fromNumber(value, (isLittleEndian == mostSignificantByteFirst)); } ByteVector ByteVector::fromLongLong(long long value, bool mostSignificantByteFirst) { - return fromNumber(value, mostSignificantByteFirst); + return fromNumber(value, (isLittleEndian == mostSignificantByteFirst)); } //////////////////////////////////////////////////////////////////////////////// @@ -702,22 +684,22 @@ TagLib::uint ByteVector::checksum() const TagLib::uint ByteVector::toUInt(bool mostSignificantByteFirst) const { - return toNumber(*this, mostSignificantByteFirst); + return toNumber(*this, (isLittleEndian == mostSignificantByteFirst)); } short ByteVector::toShort(bool mostSignificantByteFirst) const { - return toNumber(*this, mostSignificantByteFirst); + return toNumber(*this, (isLittleEndian == mostSignificantByteFirst)); } unsigned short ByteVector::toUShort(bool mostSignificantByteFirst) const { - return toNumber(*this, mostSignificantByteFirst); + return toNumber(*this, (isLittleEndian == mostSignificantByteFirst)); } long long ByteVector::toLongLong(bool mostSignificantByteFirst) const { - return toNumber(*this, mostSignificantByteFirst); + return toNumber(*this, (isLittleEndian == mostSignificantByteFirst)); } const char &ByteVector::operator[](int index) const @@ -835,11 +817,18 @@ void ByteVector::detach() } } +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +const bool ByteVector::isLittleEndian = isLittleEndianSystem(); +} + //////////////////////////////////////////////////////////////////////////////// // related functions //////////////////////////////////////////////////////////////////////////////// -std::ostream &operator<<(std::ostream &s, const ByteVector &v) +std::ostream &operator<<(std::ostream &s, const TagLib::ByteVector &v) { for(TagLib::uint i = 0; i < v.size(); i++) s << v[i]; diff --git a/taglib/toolkit/tbytevector.h b/taglib/toolkit/tbytevector.h index ca810130..d43e3e78 100644 --- a/taglib/toolkit/tbytevector.h +++ b/taglib/toolkit/tbytevector.h @@ -445,6 +445,11 @@ namespace TagLib { void detach(); private: + /*! + * Indicates the system endian. \a true if little endian, \a false if big endian. + */ + static const bool isLittleEndian; + class ByteVectorPrivate; ByteVectorPrivate *d; }; diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index 2c80e80c..d6e102c3 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -53,24 +53,6 @@ namespace { { return (c1 << 8) | c2; } - -#if !defined(TAGLIB_LITTLE_ENDIAN) && !defined(TAGLIB_BIG_ENDIAN) - - TagLib::String::Type wcharByteOrder() - { - // Detect CPU endian at run time. - union { - TagLib::ushort w; - char c; - } x = { 0x1234 }; - - if(x.c == 0x34) - return String::UTF16LE; - else - return String::UTF16BE; - } - -#endif } namespace TagLib { @@ -839,19 +821,7 @@ void String::copyFromUTF16(const char *s, size_t length, Type t) internalCopyFromUTF16(s, length, t); } -#if defined(TAGLIB_LITTLE_ENDIAN) - -const String::Type String::WCharByteOrder = String::UTF16LE; - -#elif defined(TAGLIB_BIG_ENDIAN) - -const String::Type String::WCharByteOrder = String::UTF16BE; - -#else - -const String::Type String::WCharByteOrder = wcharByteOrder(); - -#endif +const String::Type String::WCharByteOrder = isLittleEndianSystem() ? String::UTF16LE : String::UTF16BE; } ////////////////////////////////////////////////////////////////////////////////