oculus1

view libovr/Src/Kernel/OVR_Std.h @ 29:9a973ef0e2a3

fixed the performance issue under MacOSX by replacing glutSolidTeapot (which uses glEvalMesh) with my own teapot generator.
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 27 Oct 2013 06:31:18 +0200
parents e2f9e4603129
children
line source
1 /************************************************************************************
3 PublicHeader: OVR.h
4 Filename : OVR_Std.h
5 Content : Standard C function interface
6 Created : September 19, 2012
7 Notes :
9 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
11 Use of this software is subject to the terms of the Oculus license
12 agreement provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
15 ************************************************************************************/
17 #ifndef OVR_Std_h
18 #define OVR_Std_h
20 #include "OVR_Types.h"
21 #include <stdarg.h> // for va_list args
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <ctype.h>
27 #if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
28 #define OVR_MSVC_SAFESTRING
29 #include <errno.h>
30 #endif
32 // Wide-char funcs
33 #include <wchar.h>
34 #include <wctype.h>
36 namespace OVR {
38 #if defined(OVR_OS_WIN32)
39 inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix)
40 {
41 #if defined(OVR_MSVC_SAFESTRING)
42 _itoa_s(val, dest, destsize, radix);
43 return dest;
44 #else
45 OVR_UNUSED(destsize);
46 return itoa(val, dest, radix);
47 #endif
48 }
49 #else // OVR_OS_WIN32
50 inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix)
51 {
52 if (val == 0)
53 {
54 if (len > 1)
55 {
56 dest[0] = '0';
57 dest[1] = '\0';
58 }
59 return dest;
60 }
62 int cur = val;
63 unsigned int i = 0;
64 unsigned int sign = 0;
66 if (val < 0)
67 {
68 val = -val;
69 sign = 1;
70 }
72 while ((val != 0) && (i < (len - 1 - sign)))
73 {
74 cur = val % radix;
75 val /= radix;
77 if (radix == 16)
78 {
79 switch(cur)
80 {
81 case 10:
82 dest[i] = 'a';
83 break;
84 case 11:
85 dest[i] = 'b';
86 break;
87 case 12:
88 dest[i] = 'c';
89 break;
90 case 13:
91 dest[i] = 'd';
92 break;
93 case 14:
94 dest[i] = 'e';
95 break;
96 case 15:
97 dest[i] = 'f';
98 break;
99 default:
100 dest[i] = (char)('0' + cur);
101 break;
102 }
103 }
104 else
105 {
106 dest[i] = (char)('0' + cur);
107 }
108 ++i;
109 }
111 if (sign)
112 {
113 dest[i++] = '-';
114 }
116 for (unsigned int j = 0; j < i / 2; ++j)
117 {
118 char tmp = dest[j];
119 dest[j] = dest[i - 1 - j];
120 dest[i - 1 - j] = tmp;
121 }
122 dest[i] = '\0';
124 return dest;
125 }
127 #endif
130 // String functions
132 inline UPInt OVR_CDECL OVR_strlen(const char* str)
133 {
134 return strlen(str);
135 }
137 inline char* OVR_CDECL OVR_strcpy(char* dest, UPInt destsize, const char* src)
138 {
139 #if defined(OVR_MSVC_SAFESTRING)
140 strcpy_s(dest, destsize, src);
141 return dest;
142 #else
143 OVR_UNUSED(destsize);
144 return strcpy(dest, src);
145 #endif
146 }
148 inline char* OVR_CDECL OVR_strncpy(char* dest, UPInt destsize, const char* src, UPInt count)
149 {
150 #if defined(OVR_MSVC_SAFESTRING)
151 strncpy_s(dest, destsize, src, count);
152 return dest;
153 #else
154 OVR_UNUSED(destsize);
155 return strncpy(dest, src, count);
156 #endif
157 }
159 inline char * OVR_CDECL OVR_strcat(char* dest, UPInt destsize, const char* src)
160 {
161 #if defined(OVR_MSVC_SAFESTRING)
162 strcat_s(dest, destsize, src);
163 return dest;
164 #else
165 OVR_UNUSED(destsize);
166 return strcat(dest, src);
167 #endif
168 }
170 inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src)
171 {
172 return strcmp(dest, src);
173 }
175 inline const char* OVR_CDECL OVR_strchr(const char* str, char c)
176 {
177 return strchr(str, c);
178 }
180 inline char* OVR_CDECL OVR_strchr(char* str, char c)
181 {
182 return strchr(str, c);
183 }
185 inline const char* OVR_strrchr(const char* str, char c)
186 {
187 UPInt len = OVR_strlen(str);
188 for (UPInt i=len; i>0; i--)
189 if (str[i]==c)
190 return str+i;
191 return 0;
192 }
194 inline const UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c)
195 {
196 for (SPInt i = (SPInt)size - 1; i >= 0; i--)
197 {
198 if (str[i] == c)
199 return str + i;
200 }
201 return 0;
202 }
204 inline char* OVR_CDECL OVR_strrchr(char* str, char c)
205 {
206 UPInt len = OVR_strlen(str);
207 for (UPInt i=len; i>0; i--)
208 if (str[i]==c)
209 return str+i;
210 return 0;
211 }
214 double OVR_CDECL OVR_strtod(const char* string, char** tailptr);
216 inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix)
217 {
218 return strtol(string, tailptr, radix);
219 }
221 inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
222 {
223 return strtoul(string, tailptr, radix);
224 }
226 inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, UPInt size)
227 {
228 return strncmp(ws1, ws2, size);
229 }
231 inline UInt64 OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base)
232 {
233 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
234 return _strtoui64(nptr, endptr, base);
235 #else
236 return strtoull(nptr, endptr, base);
237 #endif
238 }
240 inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base)
241 {
242 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
243 return _strtoi64(nptr, endptr, base);
244 #else
245 return strtoll(nptr, endptr, base);
246 #endif
247 }
250 inline SInt64 OVR_CDECL OVR_atoq(const char* string)
251 {
252 #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE)
253 return _atoi64(string);
254 #else
255 return atoll(string);
256 #endif
257 }
259 inline UInt64 OVR_CDECL OVR_atouq(const char* string)
260 {
261 return OVR_strtouq(string, NULL, 10);
262 }
265 // Implemented in GStd.cpp in platform-specific manner.
266 int OVR_CDECL OVR_stricmp(const char* dest, const char* src);
267 int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, UPInt count);
269 inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* format, ...)
270 {
271 va_list argList;
272 va_start(argList,format);
273 UPInt ret;
274 #if defined(OVR_CC_MSVC)
275 #if defined(OVR_MSVC_SAFESTRING)
276 ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
277 OVR_ASSERT(ret != -1);
278 #else
279 OVR_UNUSED(destsize);
280 ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character
281 OVR_ASSERT(ret != -1);
282 dest[destsize-1] = 0;
283 #endif
284 #else
285 OVR_UNUSED(destsize);
286 ret = vsprintf(dest, format, argList);
287 OVR_ASSERT(ret < destsize);
288 #endif
289 va_end(argList);
290 return ret;
291 }
293 inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList)
294 {
295 UPInt ret;
296 #if defined(OVR_CC_MSVC)
297 #if defined(OVR_MSVC_SAFESTRING)
298 dest[0] = '\0';
299 int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
300 if (rv == -1)
301 {
302 dest[destsize - 1] = '\0';
303 ret = destsize - 1;
304 }
305 else
306 ret = (UPInt)rv;
307 #else
308 OVR_UNUSED(destsize);
309 int rv = _vsnprintf(dest, destsize - 1, format, argList);
310 OVR_ASSERT(rv != -1);
311 ret = (UPInt)rv;
312 dest[destsize-1] = 0;
313 #endif
314 #else
315 OVR_UNUSED(destsize);
316 ret = (UPInt)vsprintf(dest, format, argList);
317 OVR_ASSERT(ret < destsize);
318 #endif
319 return ret;
320 }
322 // Returns the number of characters in the formatted string.
323 inline UPInt OVR_CDECL OVR_vscprintf(const char * format, va_list argList)
324 {
325 UPInt ret;
326 #if defined(OVR_CC_MSVC)
327 ret = (UPInt) _vscprintf(format, argList);
328 #else
329 ret = (UPInt) vsnprintf(NULL, 0, format, argList);
330 #endif
331 return ret;
332 }
335 wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src);
336 wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count);
337 wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src);
338 UPInt OVR_CDECL OVR_wcslen(const wchar_t* str);
339 int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b);
340 int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b);
342 inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b)
343 {
344 #if defined(OVR_OS_WIN32)
345 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
346 return ::_wcsicoll(a, b);
347 #else
348 return ::wcsicoll(a, b);
349 #endif
350 #else
351 // not supported, use regular wcsicmp
352 return OVR_wcsicmp(a, b);
353 #endif
354 }
356 inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b)
357 {
358 #if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX)
359 return wcscoll(a, b);
360 #else
361 // not supported, use regular wcscmp
362 return OVR_wcscmp(a, b);
363 #endif
364 }
366 #ifndef OVR_NO_WCTYPE
368 inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode)
369 {
370 unsigned offset = table[charCode >> 8];
371 if (offset == 0) return 0;
372 if (offset == 1) return 1;
373 return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0;
374 }
376 extern const UInt16 UnicodeAlnumBits[];
377 extern const UInt16 UnicodeAlphaBits[];
378 extern const UInt16 UnicodeDigitBits[];
379 extern const UInt16 UnicodeSpaceBits[];
380 extern const UInt16 UnicodeXDigitBits[];
382 // Uncomment if necessary
383 //extern const UInt16 UnicodeCntrlBits[];
384 //extern const UInt16 UnicodeGraphBits[];
385 //extern const UInt16 UnicodeLowerBits[];
386 //extern const UInt16 UnicodePrintBits[];
387 //extern const UInt16 UnicodePunctBits[];
388 //extern const UInt16 UnicodeUpperBits[];
390 inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits, charCode); }
391 inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits, charCode); }
392 inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits, charCode); }
393 inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits, charCode); }
394 inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); }
396 // Uncomment if necessary
397 //inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits, charCode); }
398 //inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits, charCode); }
399 //inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits, charCode); }
400 //inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits, charCode); }
401 //inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits, charCode); }
402 //inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits, charCode); }
404 int OVR_CDECL OVR_towupper(wchar_t charCode);
405 int OVR_CDECL OVR_towlower(wchar_t charCode);
407 #else // OVR_NO_WCTYPE
409 inline int OVR_CDECL OVR_iswspace(wchar_t c)
410 {
411 return iswspace(c);
412 }
414 inline int OVR_CDECL OVR_iswdigit(wchar_t c)
415 {
416 return iswdigit(c);
417 }
419 inline int OVR_CDECL OVR_iswxdigit(wchar_t c)
420 {
421 return iswxdigit(c);
422 }
424 inline int OVR_CDECL OVR_iswalpha(wchar_t c)
425 {
426 return iswalpha(c);
427 }
429 inline int OVR_CDECL OVR_iswalnum(wchar_t c)
430 {
431 return iswalnum(c);
432 }
434 inline wchar_t OVR_CDECL OVR_towlower(wchar_t c)
435 {
436 return (wchar_t)towlower(c);
437 }
439 inline wchar_t OVR_towupper(wchar_t c)
440 {
441 return (wchar_t)towupper(c);
442 }
444 #endif // OVR_NO_WCTYPE
446 // ASCII versions of tolower and toupper. Don't use "char"
447 inline int OVR_CDECL OVR_tolower(int c)
448 {
449 return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c;
450 }
452 inline int OVR_CDECL OVR_toupper(int c)
453 {
454 return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
455 }
459 inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr)
460 {
461 #if defined(OVR_OS_OTHER)
462 OVR_UNUSED(tailptr);
463 char buffer[64];
464 char* tp = NULL;
465 UPInt max = OVR_wcslen(string);
466 if (max > 63) max = 63;
467 unsigned char c = 0;
468 for (UPInt i=0; i < max; i++)
469 {
470 c = (unsigned char)string[i];
471 buffer[i] = ((c) < 128 ? (char)c : '!');
472 }
473 buffer[max] = 0;
474 return OVR_strtod(buffer, &tp);
475 #else
476 return wcstod(string, tailptr);
477 #endif
478 }
480 inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix)
481 {
482 #if defined(OVR_OS_OTHER)
483 OVR_UNUSED(tailptr);
484 char buffer[64];
485 char* tp = NULL;
486 UPInt max = OVR_wcslen(string);
487 if (max > 63) max = 63;
488 unsigned char c = 0;
489 for (UPInt i=0; i < max; i++)
490 {
491 c = (unsigned char)string[i];
492 buffer[i] = ((c) < 128 ? (char)c : '!');
493 }
494 buffer[max] = 0;
495 return strtol(buffer, &tp, radix);
496 #else
497 return wcstol(string, tailptr, radix);
498 #endif
499 }
501 } // OVR
503 #endif // OVR_Std_h