tutils.h
Go to the documentation of this file.
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_BOOST_BYTESWAP)
38# include <boost/endian/conversion.hpp>
39#elif defined(HAVE_MSC_BYTESWAP)
40# include <stdlib.h>
41#elif defined(HAVE_GLIBC_BYTESWAP)
42# include <byteswap.h>
43#elif defined(HAVE_MAC_BYTESWAP)
44# include <libkern/OSByteOrder.h>
45#elif defined(HAVE_OPENBSD_BYTESWAP)
46# include <sys/endian.h>
47#endif
48
49#include <tstring.h>
50#include <cstdio>
51#include <cstdarg>
52#include <cstring>
53
54namespace TagLib
55{
56 namespace Utils
57 {
58 namespace
59 {
60
64 inline unsigned short byteSwap(unsigned short x)
65 {
66#if defined(HAVE_BOOST_BYTESWAP)
67
68 return boost::endian::endian_reverse(static_cast<uint16_t>(x));
69
70#elif defined(HAVE_GCC_BYTESWAP)
71
72 return __builtin_bswap16(x);
73
74#elif defined(HAVE_MSC_BYTESWAP)
75
76 return _byteswap_ushort(x);
77
78#elif defined(HAVE_GLIBC_BYTESWAP)
79
80 return __bswap_16(x);
81
82#elif defined(HAVE_MAC_BYTESWAP)
83
84 return OSSwapInt16(x);
85
86#elif defined(HAVE_OPENBSD_BYTESWAP)
87
88 return swap16(x);
89
90#else
91
92 return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
93
94#endif
95 }
96
100 inline unsigned int byteSwap(unsigned int x)
101 {
102#if defined(HAVE_BOOST_BYTESWAP)
103
104 return boost::endian::endian_reverse(static_cast<uint32_t>(x));
105
106#elif defined(HAVE_GCC_BYTESWAP)
107
108 return __builtin_bswap32(x);
109
110#elif defined(HAVE_MSC_BYTESWAP)
111
112 return _byteswap_ulong(x);
113
114#elif defined(HAVE_GLIBC_BYTESWAP)
115
116 return __bswap_32(x);
117
118#elif defined(HAVE_MAC_BYTESWAP)
119
120 return OSSwapInt32(x);
121
122#elif defined(HAVE_OPENBSD_BYTESWAP)
123
124 return swap32(x);
125
126#else
127
128 return ((x & 0xff000000u) >> 24)
129 | ((x & 0x00ff0000u) >> 8)
130 | ((x & 0x0000ff00u) << 8)
131 | ((x & 0x000000ffu) << 24);
132
133#endif
134 }
135
139 inline unsigned long long byteSwap(unsigned long long x)
140 {
141#if defined(HAVE_BOOST_BYTESWAP)
142
143 return boost::endian::endian_reverse(static_cast<uint64_t>(x));
144
145#elif defined(HAVE_GCC_BYTESWAP)
146
147 return __builtin_bswap64(x);
148
149#elif defined(HAVE_MSC_BYTESWAP)
150
151 return _byteswap_uint64(x);
152
153#elif defined(HAVE_GLIBC_BYTESWAP)
154
155 return __bswap_64(x);
156
157#elif defined(HAVE_MAC_BYTESWAP)
158
159 return OSSwapInt64(x);
160
161#elif defined(HAVE_OPENBSD_BYTESWAP)
162
163 return swap64(x);
164
165#else
166
167 return ((x & 0xff00000000000000ull) >> 56)
168 | ((x & 0x00ff000000000000ull) >> 40)
169 | ((x & 0x0000ff0000000000ull) >> 24)
170 | ((x & 0x000000ff00000000ull) >> 8)
171 | ((x & 0x00000000ff000000ull) << 8)
172 | ((x & 0x0000000000ff0000ull) << 24)
173 | ((x & 0x000000000000ff00ull) << 40)
174 | ((x & 0x00000000000000ffull) << 56);
175
176#endif
177 }
178
183 inline String formatString(const char *format, ...)
184 {
185 // Sufficient buffer size for the current internal uses.
186 // Consider changing this value when you use this function.
187
188 static const size_t BufferSize = 128;
189
190 va_list args;
191 va_start(args, format);
192
193 char buf[BufferSize];
194 int length;
195
196#if defined(HAVE_VSNPRINTF)
197
198 length = vsnprintf(buf, BufferSize, format, args);
199
200#elif defined(HAVE_VSPRINTF_S)
201
202 length = vsprintf_s(buf, format, args);
203
204#else
205
206 // The last resort. May cause a buffer overflow.
207
208 length = vsprintf(buf, format, args);
209 if(length >= BufferSize) {
210 debug("Utils::formatString() - Buffer overflow! Returning an empty string.");
211 length = -1;
212 }
213
214#endif
215
216 va_end(args);
217
218 if(length > 0)
219 return String(buf);
220 else
221 return String();
222 }
223
231 inline bool equalsIgnoreCase(const char *s1, const char *s2)
232 {
233 while(*s1 != '\0' && *s2 != '\0' && ::tolower(*s1) == ::tolower(*s2)) {
234 s1++;
235 s2++;
236 }
237
238 return (*s1 == '\0' && *s2 == '\0');
239 }
240
244 enum ByteOrder
245 {
247 LittleEndian,
249 BigEndian
250 };
251
255 inline ByteOrder systemByteOrder()
256 {
257 union {
258 int i;
259 char c;
260 } u;
261
262 u.i = 1;
263 if(u.c == 1)
264 return LittleEndian;
265 else
266 return BigEndian;
267 }
268
272 inline ByteOrder floatByteOrder()
273 {
274 union {
275 double d;
276 char c;
277 } u;
278
279 // 1.0 is stored in memory like 0x3FF0000000000000 in canonical form.
280 // So the first byte is zero if little endian.
281
282 u.d = 1.0;
283 if(u.c == 0)
284 return LittleEndian;
285 else
286 return BigEndian;
287 }
288 }
289 }
290}
291
292#endif
293
294#endif
A namespace for all TagLib related classes and functions.
Definition: apefile.h:41