Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef TAGLIB_TUTILS_H
00027 #define TAGLIB_TUTILS_H
00028
00029
00030
00031 #ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header
00032
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036
00037 #if defined(HAVE_MSC_BYTESWAP)
00038 # include <stdlib.h>
00039 #elif defined(HAVE_GLIBC_BYTESWAP)
00040 # include <byteswap.h>
00041 #elif defined(HAVE_MAC_BYTESWAP)
00042 # include <libkern/OSByteOrder.h>
00043 #elif defined(HAVE_OPENBSD_BYTESWAP)
00044 # include <sys/endian.h>
00045 #endif
00046
00047 #include <tstring.h>
00048 #include <cstdio>
00049 #include <cstdarg>
00050 #include <cstring>
00051
00052 namespace TagLib
00053 {
00054 namespace Utils
00055 {
00056
00060 inline ushort byteSwap(ushort x)
00061 {
00062 #if defined(HAVE_GCC_BYTESWAP)
00063
00064 return __builtin_bswap16(x);
00065
00066 #elif defined(HAVE_MSC_BYTESWAP)
00067
00068 return _byteswap_ushort(x);
00069
00070 #elif defined(HAVE_GLIBC_BYTESWAP)
00071
00072 return __bswap_16(x);
00073
00074 #elif defined(HAVE_MAC_BYTESWAP)
00075
00076 return OSSwapInt16(x);
00077
00078 #elif defined(HAVE_OPENBSD_BYTESWAP)
00079
00080 return swap16(x);
00081
00082 #else
00083
00084 return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
00085
00086 #endif
00087 }
00088
00092 inline uint byteSwap(uint x)
00093 {
00094 #if defined(HAVE_GCC_BYTESWAP)
00095
00096 return __builtin_bswap32(x);
00097
00098 #elif defined(HAVE_MSC_BYTESWAP)
00099
00100 return _byteswap_ulong(x);
00101
00102 #elif defined(HAVE_GLIBC_BYTESWAP)
00103
00104 return __bswap_32(x);
00105
00106 #elif defined(HAVE_MAC_BYTESWAP)
00107
00108 return OSSwapInt32(x);
00109
00110 #elif defined(HAVE_OPENBSD_BYTESWAP)
00111
00112 return swap32(x);
00113
00114 #else
00115
00116 return ((x & 0xff000000u) >> 24)
00117 | ((x & 0x00ff0000u) >> 8)
00118 | ((x & 0x0000ff00u) << 8)
00119 | ((x & 0x000000ffu) << 24);
00120
00121 #endif
00122 }
00123
00127 inline ulonglong byteSwap(ulonglong x)
00128 {
00129 #if defined(HAVE_GCC_BYTESWAP)
00130
00131 return __builtin_bswap64(x);
00132
00133 #elif defined(HAVE_MSC_BYTESWAP)
00134
00135 return _byteswap_uint64(x);
00136
00137 #elif defined(HAVE_GLIBC_BYTESWAP)
00138
00139 return __bswap_64(x);
00140
00141 #elif defined(HAVE_MAC_BYTESWAP)
00142
00143 return OSSwapInt64(x);
00144
00145 #elif defined(HAVE_OPENBSD_BYTESWAP)
00146
00147 return swap64(x);
00148
00149 #else
00150
00151 return ((x & 0xff00000000000000ull) >> 56)
00152 | ((x & 0x00ff000000000000ull) >> 40)
00153 | ((x & 0x0000ff0000000000ull) >> 24)
00154 | ((x & 0x000000ff00000000ull) >> 8)
00155 | ((x & 0x00000000ff000000ull) << 8)
00156 | ((x & 0x0000000000ff0000ull) << 24)
00157 | ((x & 0x000000000000ff00ull) << 40)
00158 | ((x & 0x00000000000000ffull) << 56);
00159
00160 #endif
00161 }
00162
00167 inline String formatString(const char *format, ...)
00168 {
00169
00170
00171
00172 static const size_t BufferSize = 128;
00173
00174 va_list args;
00175 va_start(args, format);
00176
00177 char buf[BufferSize];
00178 int length;
00179
00180 #if defined(HAVE_VSNPRINTF)
00181
00182 length = vsnprintf(buf, BufferSize, format, args);
00183
00184 #elif defined(HAVE_VSPRINTF_S)
00185
00186 length = vsprintf_s(buf, format, args);
00187
00188 #else
00189
00190
00191
00192 length = vsprintf(buf, format, args);
00193 if(length >= BufferSize) {
00194 debug("Utils::formatString() - Buffer overflow! Returning an empty string.");
00195 length = -1;
00196 }
00197
00198 #endif
00199
00200 va_end(args);
00201
00202 if(length != -1)
00203 return String(buf);
00204 else
00205 return String::null;
00206 }
00207
00211 enum ByteOrder
00212 {
00214 LittleEndian,
00216 BigEndian
00217 };
00218
00222 inline ByteOrder systemByteOrder()
00223 {
00224 union {
00225 int i;
00226 char c;
00227 } u;
00228
00229 u.i = 1;
00230 if(u.c == 1)
00231 return LittleEndian;
00232 else
00233 return BigEndian;
00234 }
00235
00239 inline ByteOrder floatByteOrder()
00240 {
00241 union {
00242 double d;
00243 char c;
00244 } u;
00245
00246
00247
00248
00249 u.d = 1.0;
00250 if(u.c == 0)
00251 return LittleEndian;
00252 else
00253 return BigEndian;
00254 }
00255
00256 }
00257 }
00258
00259 #endif
00260
00261 #endif