Merge pull request #134 from TsudaKageyu/fix-byteswap

Bug fix for #132
This commit is contained in:
Tsuda Kageyu 2013-04-15 14:02:17 -07:00
commit cc3dbd84ce
5 changed files with 33 additions and 39 deletions

View File

@ -70,8 +70,17 @@
|| (defined(__clang__) && defined(__BIG_ENDIAN__))
# define TAGLIB_BIG_ENDIAN
#endif
#else
namespace {
bool isLittleEndian()
{
TagLib::ushort x = 1;
return (*reinterpret_cast<TagLib::uchar*>(&x) == 1);
}
}
#endif
namespace TagLib
{
@ -172,21 +181,17 @@ namespace TagLib
#endif
}
bool isLittleEndianSystem()
{
#if defined(TAGLIB_LITTLE_ENDIAN)
return true;
const bool isLittleEndianSystem = true;
#elif defined(TAGLIB_BIG_ENDIAN)
return false;
const bool isLittleEndianSystem = false;
#else
ushort x = 1;
return (*reinterpret_cast<uchar>(&x) == 1);
const bool isLittleEndianSystem = isLittleEndianSystem();
#endif
}
}

View File

@ -46,10 +46,10 @@ namespace TagLib
ulonglong byteSwap64(ulonglong x);
/*!
* Detects the system byte order.
* Returns \a true if little endian, \a false if big endian.
* Indicates the system byte order.
* \a true if little endian, \a false if big endian.
*/
bool isLittleEndianSystem();
extern const bool isLittleEndianSystem;
}
#endif

View File

@ -183,25 +183,25 @@ T byteSwap(T x)
}
template <>
unsigned short byteSwap<unsigned short>(unsigned short x)
ushort byteSwap<ushort>(ushort x)
{
return byteSwap16(x);
}
template <>
unsigned int byteSwap<unsigned int>(unsigned int x)
uint byteSwap<uint>(uint x)
{
return byteSwap32(x);
}
template <>
unsigned long long byteSwap<unsigned long long>(unsigned long long x)
ulonglong byteSwap<ulonglong>(ulonglong x)
{
return byteSwap64(x);
}
template <class T>
T toNumber(const ByteVector &v, bool swapBytes)
T toNumber(const ByteVector &v, bool mostSignificantByteFirst)
{
if(v.isEmpty()) {
debug("toNumber<T>() -- data is empty, returning 0");
@ -212,26 +212,26 @@ T toNumber(const ByteVector &v, bool swapBytes)
if(v.size() >= size)
{
if(swapBytes)
if(isLittleEndianSystem == mostSignificantByteFirst)
return byteSwap<T>(*reinterpret_cast<const T*>(v.data()));
else
return *reinterpret_cast<const T*>(v.data());
}
const uint last = v.size() > size ? size - 1 : v.size() - 1;
const uint last = std::min<uint>(v.size() - 1, size);
T sum = 0;
for(uint i = 0; i <= last; i++)
sum |= (T) uchar(v[i]) << ((swapBytes ? last - i : i) * 8);
sum |= (T) uchar(v[i]) << ((mostSignificantByteFirst ? last - i : i) * 8);
return sum;
}
template <class T>
ByteVector fromNumber(T value, bool swapBytes)
ByteVector fromNumber(T value, bool mostSignificantByteFirst)
{
const size_t size = sizeof(T);
if(swapBytes)
if(isLittleEndianSystem == mostSignificantByteFirst)
value = byteSwap<T>(value);
return ByteVector(reinterpret_cast<const char *>(&value), size);
@ -353,17 +353,17 @@ ByteVector ByteVector::fromCString(const char *s, uint length)
ByteVector ByteVector::fromUInt(uint value, bool mostSignificantByteFirst)
{
return fromNumber<uint>(value, (isLittleEndian == mostSignificantByteFirst));
return fromNumber<uint>(value, mostSignificantByteFirst);
}
ByteVector ByteVector::fromShort(short value, bool mostSignificantByteFirst)
{
return fromNumber<ushort>(value, (isLittleEndian == mostSignificantByteFirst));
return fromNumber<ushort>(value, mostSignificantByteFirst);
}
ByteVector ByteVector::fromLongLong(long long value, bool mostSignificantByteFirst)
{
return fromNumber<unsigned long long>(value, (isLittleEndian == mostSignificantByteFirst));
return fromNumber<unsigned long long>(value, mostSignificantByteFirst);
}
////////////////////////////////////////////////////////////////////////////////
@ -684,22 +684,22 @@ TagLib::uint ByteVector::checksum() const
TagLib::uint ByteVector::toUInt(bool mostSignificantByteFirst) const
{
return toNumber<uint>(*this, (isLittleEndian == mostSignificantByteFirst));
return toNumber<uint>(*this, mostSignificantByteFirst);
}
short ByteVector::toShort(bool mostSignificantByteFirst) const
{
return toNumber<unsigned short>(*this, (isLittleEndian == mostSignificantByteFirst));
return toNumber<unsigned short>(*this, mostSignificantByteFirst);
}
unsigned short ByteVector::toUShort(bool mostSignificantByteFirst) const
{
return toNumber<unsigned short>(*this, (isLittleEndian == mostSignificantByteFirst));
return toNumber<unsigned short>(*this, mostSignificantByteFirst);
}
long long ByteVector::toLongLong(bool mostSignificantByteFirst) const
{
return toNumber<unsigned long long>(*this, (isLittleEndian == mostSignificantByteFirst));
return toNumber<unsigned long long>(*this, mostSignificantByteFirst);
}
const char &ByteVector::operator[](int index) const
@ -816,12 +816,6 @@ void ByteVector::detach()
d = new ByteVectorPrivate(d->data->data, d->offset, d->length);
}
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
const bool ByteVector::isLittleEndian = isLittleEndianSystem();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -445,11 +445,6 @@ 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;
};

View File

@ -821,7 +821,7 @@ void String::copyFromUTF16(const char *s, size_t length, Type t)
internalCopyFromUTF16<sizeof(wchar_t)>(s, length, t);
}
const String::Type String::WCharByteOrder = isLittleEndianSystem() ? String::UTF16LE : String::UTF16BE;
const String::Type String::WCharByteOrder = isLittleEndianSystem ? String::UTF16LE : String::UTF16BE;
}
////////////////////////////////////////////////////////////////////////////////