mirror of
https://github.com/taglib/taglib.git
synced 2025-06-03 09:08:09 -04:00
Merge pull request #132 from TsudaKageyu/byteswap
Add cross-platform byte order conversions
This commit is contained in:
commit
f0edca2f8c
@ -50,6 +50,7 @@ set(tag_HDRS
|
||||
toolkit/tmap.h
|
||||
toolkit/tmap.tcc
|
||||
toolkit/tpropertymap.h
|
||||
toolkit/tbyteswap.h
|
||||
mpeg/mpegfile.h
|
||||
mpeg/mpegproperties.h
|
||||
mpeg/mpegheader.h
|
||||
@ -289,6 +290,7 @@ set(toolkit_SRCS
|
||||
toolkit/tfilestream.cpp
|
||||
toolkit/tdebug.cpp
|
||||
toolkit/tpropertymap.cpp
|
||||
toolkit/tbyteswap.cpp
|
||||
toolkit/unicode.cpp
|
||||
)
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <climits>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <libkern/OSAtomic.h>
|
||||
@ -75,6 +76,30 @@
|
||||
*/
|
||||
#endif
|
||||
|
||||
// Check the widths of integral types.
|
||||
|
||||
#if UCHAR_MAX != 255U
|
||||
# error TagLib assumes that char is 8-bit wide.
|
||||
#endif
|
||||
|
||||
#if USHRT_MAX != 65535U
|
||||
# error TagLib assumes that short is 16-bit wide.
|
||||
#endif
|
||||
|
||||
#if UINT_MAX != 4294967295U
|
||||
# error TagLib assumes that int is 32-bit wide.
|
||||
#endif
|
||||
|
||||
#if !defined(ULLONG_MAX) && !defined(ULONGLONG_MAX) && !defined(ULONG_LONG_MAX)
|
||||
# error TagLib assumes that long long is 64-bit wide.
|
||||
#elif defined(ULLONG_MAX) && ULLONG_MAX != 18446744073709551615ULL
|
||||
# error TagLib assumes that long long is 64-bit wide.
|
||||
#elif defined(ULONGLONG_MAX) && ULONGLONG_MAX != 18446744073709551615ULL
|
||||
# error TagLib assumes that long long is 64-bit wide.
|
||||
#elif defined(ULONG_LONG_MAX) && ULONG_LONG_MAX != 18446744073709551615ULL
|
||||
# error TagLib assumes that long long is 64-bit wide.
|
||||
#endif
|
||||
|
||||
//! A namespace for all TagLib related classes and functions
|
||||
|
||||
/*!
|
||||
@ -89,10 +114,13 @@ namespace TagLib {
|
||||
|
||||
class String;
|
||||
|
||||
typedef wchar_t wchar;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef wchar_t wchar; // Assumed to be sufficient to store a UTF-16 char.
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long long ulonglong;
|
||||
|
||||
// long/ulong can be either 32-bit or 64-bit wide.
|
||||
typedef unsigned long ulong;
|
||||
|
||||
/*!
|
||||
|
160
taglib/toolkit/tbyteswap.cpp
Normal file
160
taglib/toolkit/tbyteswap.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "taglib.h"
|
||||
#include "tbyteswap.h"
|
||||
|
||||
// Determines if compiler intrinsic functions are available.
|
||||
|
||||
// MSVC: Intrinsic _byteswap_* functions.
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
# include <stdlib.h>
|
||||
# define TAGLIB_BYTESWAP_MSC
|
||||
|
||||
// GCC 4.8 or above: __builtin_bswap16(), 32 and 64.
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
|
||||
# define TAGLIB_BYTESWAP_GCC 2
|
||||
|
||||
// GCC 4.3 or above: __builtin_bswap16 is missing.
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
# define TAGLIB_BYTESWAP_GCC 1
|
||||
|
||||
#endif
|
||||
|
||||
// Determines if platform or library specific functions are available.
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define TAGLIB_BYTESWAP_MAC
|
||||
|
||||
#elif defined(__OpenBSD__)
|
||||
# include <sys/endian.h>
|
||||
# define TAGLIB_BYTESWAP_OPENBSD
|
||||
|
||||
#elif defined(__GLIBC__)
|
||||
# include <byteswap.h>
|
||||
# define TAGLIB_BYTESWAP_GLIBC
|
||||
|
||||
#endif
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
ushort byteSwap16(ushort x)
|
||||
{
|
||||
#if defined(TAGLIB_BYTESWAP_MSC)
|
||||
|
||||
return _byteswap_ushort(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_GCC) && TAGLIB_BYTESWAP_GCC == 2
|
||||
|
||||
return __builtin_bswap16(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_MAC)
|
||||
|
||||
return OSSwapInt16(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_OPENBSD)
|
||||
|
||||
return swap16(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_GLIBC)
|
||||
|
||||
return __bswap_16(x);
|
||||
|
||||
#else
|
||||
|
||||
return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
uint byteSwap32(uint x)
|
||||
{
|
||||
#if defined(TAGLIB_BYTESWAP_MSC)
|
||||
|
||||
return _byteswap_ulong(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_GCC)
|
||||
|
||||
return __builtin_bswap32(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_MAC)
|
||||
|
||||
return OSSwapInt32(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_OPENBSD)
|
||||
|
||||
return swap32(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_GLIBC)
|
||||
|
||||
return __bswap_32(x);
|
||||
|
||||
#else
|
||||
|
||||
return ((x & 0xff000000) >> 24)
|
||||
| ((x & 0x00ff0000) >> 8)
|
||||
| ((x & 0x0000ff00) << 8)
|
||||
| ((x & 0x000000ff) << 24);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
ulonglong byteSwap64(ulonglong x)
|
||||
{
|
||||
#if defined(TAGLIB_BYTESWAP_MSC)
|
||||
|
||||
return _byteswap_uint64(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_GCC)
|
||||
|
||||
return __builtin_bswap64(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_MAC)
|
||||
|
||||
return OSSwapInt64(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_OPENBSD)
|
||||
|
||||
return swap64(x);
|
||||
|
||||
#elif defined(TAGLIB_BYTESWAP_GLIBC)
|
||||
|
||||
return __bswap_64(x);
|
||||
|
||||
#else
|
||||
|
||||
return ((x & 0xff00000000000000ull) >> 56)
|
||||
| ((x & 0x00ff000000000000ull) >> 40)
|
||||
| ((x & 0x0000ff0000000000ull) >> 24)
|
||||
| ((x & 0x000000ff00000000ull) >> 8)
|
||||
| ((x & 0x00000000ff000000ull) << 8)
|
||||
| ((x & 0x0000000000ff0000ull) << 24)
|
||||
| ((x & 0x000000000000ff00ull) << 40)
|
||||
| ((x & 0x00000000000000ffull) << 56);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
49
taglib/toolkit/tbyteswap.h
Normal file
49
taglib/toolkit/tbyteswap.h
Normal file
@ -0,0 +1,49 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_BYTESWAP_H
|
||||
#define TAGLIB_BYTESWAP_H
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
// Cross-platform byte order conversion functions.
|
||||
|
||||
/*!
|
||||
* Converts the byte order of \a x as a 16-bit unsigned integer.
|
||||
*/
|
||||
ushort byteSwap16(ushort x);
|
||||
|
||||
/*!
|
||||
* Converts the byte order of \a x as a 32-bit unsigned integer.
|
||||
*/
|
||||
uint byteSwap32(uint x);
|
||||
|
||||
/*!
|
||||
* Converts the byte order of \a x as a 64-bit unsigned integer.
|
||||
*/
|
||||
ulonglong byteSwap64(ulonglong x);
|
||||
}
|
||||
|
||||
#endif
|
@ -24,23 +24,12 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(_M_IX86) || defined(_M_X64))
|
||||
# define TAGLIB_MSC_BYTESWAP
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
# define TAGLIB_GCC_BYTESWAP
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_GCC_BYTESWAP
|
||||
# include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#include "tbytevector.h"
|
||||
#include "tbyteswap.h"
|
||||
|
||||
// This is a bit ugly to keep writing over and over again.
|
||||
|
||||
@ -184,8 +173,6 @@ namespace TagLib {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(TAGLIB_MSC_BYTESWAP) || defined(TAGLIB_GCC_BYTESWAP)
|
||||
|
||||
template <class T>
|
||||
T byteSwap(T x)
|
||||
{
|
||||
@ -194,52 +181,24 @@ namespace TagLib {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_MSC_BYTESWAP
|
||||
|
||||
template <>
|
||||
unsigned short byteSwap<unsigned short>(unsigned short x)
|
||||
{
|
||||
return _byteswap_ushort(x);
|
||||
return byteSwap16(x);
|
||||
}
|
||||
|
||||
template <>
|
||||
unsigned int byteSwap<unsigned int>(unsigned int x)
|
||||
{
|
||||
return _byteswap_ulong(x);
|
||||
return byteSwap32(x);
|
||||
}
|
||||
|
||||
template <>
|
||||
unsigned long long byteSwap<unsigned long long>(unsigned long long x)
|
||||
{
|
||||
return _byteswap_uint64(x);
|
||||
return byteSwap64(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_GCC_BYTESWAP
|
||||
|
||||
template <>
|
||||
unsigned short byteSwap<unsigned short>(unsigned short x)
|
||||
{
|
||||
return __bswap_16(x);
|
||||
}
|
||||
|
||||
template <>
|
||||
unsigned int byteSwap<unsigned int>(unsigned int x)
|
||||
{
|
||||
return __bswap_32(x);
|
||||
}
|
||||
|
||||
template <>
|
||||
unsigned long long byteSwap<unsigned long long>(unsigned long long x)
|
||||
{
|
||||
return __bswap_64(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
T toNumber(const ByteVector &v, bool mostSignificantByteFirst)
|
||||
{
|
||||
|
@ -29,9 +29,9 @@
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
#include "tstringlist.h"
|
||||
#include "tbyteswap.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Determine if the compiler supports codecvt.
|
||||
@ -49,19 +49,6 @@ typedef std::codecvt_utf8_utf16<wchar_t> utf8_utf16_t;
|
||||
|
||||
namespace {
|
||||
|
||||
inline unsigned short byteSwap(unsigned short x)
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
|
||||
return _byteswap_ushort(x);
|
||||
|
||||
#else
|
||||
|
||||
return (((x) >> 8) & 0xff) | (((x) & 0xff) << 8);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned short combine(unsigned char c1, unsigned char c2)
|
||||
{
|
||||
return (c1 << 8) | c2;
|
||||
@ -806,7 +793,7 @@ void String::copyFromUTF16(const wchar_t *s, size_t length, Type t)
|
||||
|
||||
if(swap) {
|
||||
for(size_t i = 0; i < length; ++i)
|
||||
d->data[i] = byteSwap(static_cast<unsigned short>(s[i]));
|
||||
d->data[i] = byteSwap16(static_cast<ushort>(s[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user