1 /*************************************************************************** 2 copyright : (C) 2013 by Tsuda Kageyu 3 email : tsuda.kageyu@gmail.com 4 ***************************************************************************/ 5 6 /*************************************************************************** 7 * This library is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU Lesser General Public License version * 9 * 2.1 as published by the Free Software Foundation. * 10 * * 11 * This library is distributed in the hope that it will be useful, but * 12 * WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the Free Software * 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 19 * 02110-1301 USA * 20 * * 21 * Alternatively, this file is available under the Mozilla Public * 22 * License Version 1.1. You may obtain a copy of the License at * 23 * http://www.mozilla.org/MPL/ * 24 ***************************************************************************/ 25 26 #ifndef TAGLIB_TUTILS_H 27 #define TAGLIB_TUTILS_H 28 29 // THIS FILE IS NOT A PART OF THE TAGLIB API 30 31 #ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header 32 33 #ifdef HAVE_CONFIG_H 34 # include <config.h> 35 #endif 36 37 #if defined(HAVE_MSC_BYTESWAP) 38 # include <stdlib.h> 39 #elif defined(HAVE_GLIBC_BYTESWAP) 40 # include <byteswap.h> 41 #elif defined(HAVE_MAC_BYTESWAP) 42 # include <libkern/OSByteOrder.h> 43 #elif defined(HAVE_OPENBSD_BYTESWAP) 44 # include <sys/endian.h> 45 #endif 46 47 #include <tstring.h> 48 #include <cstdio> 49 #include <cstdarg> 50 #include <cstring> 51 52 namespace TagLib 53 { 54 namespace Utils 55 { 56 namespace 57 { 58 59 /*! 60 * Reverses the order of bytes in an 16-bit integer. 61 */ byteSwap(unsigned short x)62 inline unsigned short byteSwap(unsigned short x) 63 { 64 #if defined(HAVE_GCC_BYTESWAP) 65 66 return __builtin_bswap16(x); 67 68 #elif defined(HAVE_MSC_BYTESWAP) 69 70 return _byteswap_ushort(x); 71 72 #elif defined(HAVE_GLIBC_BYTESWAP) 73 74 return __bswap_16(x); 75 76 #elif defined(HAVE_MAC_BYTESWAP) 77 78 return OSSwapInt16(x); 79 80 #elif defined(HAVE_OPENBSD_BYTESWAP) 81 82 return swap16(x); 83 84 #else 85 86 return ((x >> 8) & 0xff) | ((x & 0xff) << 8); 87 88 #endif 89 } 90 91 /*! 92 * Reverses the order of bytes in an 32-bit integer. 93 */ byteSwap(unsigned int x)94 inline unsigned int byteSwap(unsigned int x) 95 { 96 #if defined(HAVE_GCC_BYTESWAP) 97 98 return __builtin_bswap32(x); 99 100 #elif defined(HAVE_MSC_BYTESWAP) 101 102 return _byteswap_ulong(x); 103 104 #elif defined(HAVE_GLIBC_BYTESWAP) 105 106 return __bswap_32(x); 107 108 #elif defined(HAVE_MAC_BYTESWAP) 109 110 return OSSwapInt32(x); 111 112 #elif defined(HAVE_OPENBSD_BYTESWAP) 113 114 return swap32(x); 115 116 #else 117 118 return ((x & 0xff000000u) >> 24) 119 | ((x & 0x00ff0000u) >> 8) 120 | ((x & 0x0000ff00u) << 8) 121 | ((x & 0x000000ffu) << 24); 122 123 #endif 124 } 125 126 /*! 127 * Reverses the order of bytes in an 64-bit integer. 128 */ byteSwap(unsigned long long x)129 inline unsigned long long byteSwap(unsigned long long x) 130 { 131 #if defined(HAVE_GCC_BYTESWAP) 132 133 return __builtin_bswap64(x); 134 135 #elif defined(HAVE_MSC_BYTESWAP) 136 137 return _byteswap_uint64(x); 138 139 #elif defined(HAVE_GLIBC_BYTESWAP) 140 141 return __bswap_64(x); 142 143 #elif defined(HAVE_MAC_BYTESWAP) 144 145 return OSSwapInt64(x); 146 147 #elif defined(HAVE_OPENBSD_BYTESWAP) 148 149 return swap64(x); 150 151 #else 152 153 return ((x & 0xff00000000000000ull) >> 56) 154 | ((x & 0x00ff000000000000ull) >> 40) 155 | ((x & 0x0000ff0000000000ull) >> 24) 156 | ((x & 0x000000ff00000000ull) >> 8) 157 | ((x & 0x00000000ff000000ull) << 8) 158 | ((x & 0x0000000000ff0000ull) << 24) 159 | ((x & 0x000000000000ff00ull) << 40) 160 | ((x & 0x00000000000000ffull) << 56); 161 162 #endif 163 } 164 165 /*! 166 * Returns a formatted string just like standard sprintf(), but makes use of 167 * safer functions such as snprintf() if available. 168 */ formatString(const char * format,...)169 inline String formatString(const char *format, ...) 170 { 171 // Sufficient buffer size for the current internal uses. 172 // Consider changing this value when you use this function. 173 174 static const size_t BufferSize = 128; 175 176 va_list args; 177 va_start(args, format); 178 179 char buf[BufferSize]; 180 int length; 181 182 #if defined(HAVE_VSNPRINTF) 183 184 length = vsnprintf(buf, BufferSize, format, args); 185 186 #elif defined(HAVE_VSPRINTF_S) 187 188 length = vsprintf_s(buf, format, args); 189 190 #else 191 192 // The last resort. May cause a buffer overflow. 193 194 length = vsprintf(buf, format, args); 195 if(length >= BufferSize) { 196 debug("Utils::formatString() - Buffer overflow! Returning an empty string."); 197 length = -1; 198 } 199 200 #endif 201 202 va_end(args); 203 204 if(length > 0) 205 return String(buf); 206 else 207 return String(); 208 } 209 210 /*! 211 * The types of byte order of the running system. 212 */ 213 enum ByteOrder 214 { 215 //! Little endian systems. 216 LittleEndian, 217 //! Big endian systems. 218 BigEndian 219 }; 220 221 /*! 222 * Returns the byte order of the system. 223 */ systemByteOrder()224 inline ByteOrder systemByteOrder() 225 { 226 union { 227 int i; 228 char c; 229 } u; 230 231 u.i = 1; 232 if(u.c == 1) 233 return LittleEndian; 234 else 235 return BigEndian; 236 } 237 } 238 } 239 } 240 241 #endif 242 243 #endif 244