nuclear@3: /************************************************************************************ nuclear@3: nuclear@3: PublicHeader: OVR.h nuclear@3: Filename : OVR_Std.h nuclear@3: Content : Standard C function interface nuclear@3: Created : September 19, 2012 nuclear@3: Notes : nuclear@3: nuclear@3: Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. nuclear@3: nuclear@3: Use of this software is subject to the terms of the Oculus license nuclear@3: agreement provided at the time of installation or download, or which nuclear@3: otherwise accompanies this software in either electronic or hard copy form. nuclear@3: nuclear@3: ************************************************************************************/ nuclear@3: nuclear@3: #ifndef OVR_Std_h nuclear@3: #define OVR_Std_h nuclear@3: nuclear@3: #include "OVR_Types.h" nuclear@3: #include // for va_list args nuclear@3: #include nuclear@3: #include nuclear@3: #include nuclear@3: #include nuclear@3: nuclear@3: #if !defined(OVR_OS_WINCE) && defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) nuclear@3: #define OVR_MSVC_SAFESTRING nuclear@3: #include nuclear@3: #endif nuclear@3: nuclear@3: // Wide-char funcs nuclear@3: #include nuclear@3: #include nuclear@3: nuclear@3: namespace OVR { nuclear@3: nuclear@3: #if defined(OVR_OS_WIN32) nuclear@3: inline char* OVR_CDECL OVR_itoa(int val, char *dest, UPInt destsize, int radix) nuclear@3: { nuclear@3: #if defined(OVR_MSVC_SAFESTRING) nuclear@3: _itoa_s(val, dest, destsize, radix); nuclear@3: return dest; nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: return itoa(val, dest, radix); nuclear@3: #endif nuclear@3: } nuclear@3: #else // OVR_OS_WIN32 nuclear@3: inline char* OVR_itoa(int val, char* dest, unsigned int len, int radix) nuclear@3: { nuclear@3: if (val == 0) nuclear@3: { nuclear@3: if (len > 1) nuclear@3: { nuclear@3: dest[0] = '0'; nuclear@3: dest[1] = '\0'; nuclear@3: } nuclear@3: return dest; nuclear@3: } nuclear@3: nuclear@3: int cur = val; nuclear@3: unsigned int i = 0; nuclear@3: unsigned int sign = 0; nuclear@3: nuclear@3: if (val < 0) nuclear@3: { nuclear@3: val = -val; nuclear@3: sign = 1; nuclear@3: } nuclear@3: nuclear@3: while ((val != 0) && (i < (len - 1 - sign))) nuclear@3: { nuclear@3: cur = val % radix; nuclear@3: val /= radix; nuclear@3: nuclear@3: if (radix == 16) nuclear@3: { nuclear@3: switch(cur) nuclear@3: { nuclear@3: case 10: nuclear@3: dest[i] = 'a'; nuclear@3: break; nuclear@3: case 11: nuclear@3: dest[i] = 'b'; nuclear@3: break; nuclear@3: case 12: nuclear@3: dest[i] = 'c'; nuclear@3: break; nuclear@3: case 13: nuclear@3: dest[i] = 'd'; nuclear@3: break; nuclear@3: case 14: nuclear@3: dest[i] = 'e'; nuclear@3: break; nuclear@3: case 15: nuclear@3: dest[i] = 'f'; nuclear@3: break; nuclear@3: default: nuclear@3: dest[i] = (char)('0' + cur); nuclear@3: break; nuclear@3: } nuclear@3: } nuclear@3: else nuclear@3: { nuclear@3: dest[i] = (char)('0' + cur); nuclear@3: } nuclear@3: ++i; nuclear@3: } nuclear@3: nuclear@3: if (sign) nuclear@3: { nuclear@3: dest[i++] = '-'; nuclear@3: } nuclear@3: nuclear@3: for (unsigned int j = 0; j < i / 2; ++j) nuclear@3: { nuclear@3: char tmp = dest[j]; nuclear@3: dest[j] = dest[i - 1 - j]; nuclear@3: dest[i - 1 - j] = tmp; nuclear@3: } nuclear@3: dest[i] = '\0'; nuclear@3: nuclear@3: return dest; nuclear@3: } nuclear@3: nuclear@3: #endif nuclear@3: nuclear@3: nuclear@3: // String functions nuclear@3: nuclear@3: inline UPInt OVR_CDECL OVR_strlen(const char* str) nuclear@3: { nuclear@3: return strlen(str); nuclear@3: } nuclear@3: nuclear@3: inline char* OVR_CDECL OVR_strcpy(char* dest, UPInt destsize, const char* src) nuclear@3: { nuclear@3: #if defined(OVR_MSVC_SAFESTRING) nuclear@3: strcpy_s(dest, destsize, src); nuclear@3: return dest; nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: return strcpy(dest, src); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: inline char* OVR_CDECL OVR_strncpy(char* dest, UPInt destsize, const char* src, UPInt count) nuclear@3: { nuclear@3: #if defined(OVR_MSVC_SAFESTRING) nuclear@3: strncpy_s(dest, destsize, src, count); nuclear@3: return dest; nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: return strncpy(dest, src, count); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: inline char * OVR_CDECL OVR_strcat(char* dest, UPInt destsize, const char* src) nuclear@3: { nuclear@3: #if defined(OVR_MSVC_SAFESTRING) nuclear@3: strcat_s(dest, destsize, src); nuclear@3: return dest; nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: return strcat(dest, src); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src) nuclear@3: { nuclear@3: return strcmp(dest, src); nuclear@3: } nuclear@3: nuclear@3: inline const char* OVR_CDECL OVR_strchr(const char* str, char c) nuclear@3: { nuclear@3: return strchr(str, c); nuclear@3: } nuclear@3: nuclear@3: inline char* OVR_CDECL OVR_strchr(char* str, char c) nuclear@3: { nuclear@3: return strchr(str, c); nuclear@3: } nuclear@3: nuclear@3: inline const char* OVR_strrchr(const char* str, char c) nuclear@3: { nuclear@3: UPInt len = OVR_strlen(str); nuclear@3: for (UPInt i=len; i>0; i--) nuclear@3: if (str[i]==c) nuclear@3: return str+i; nuclear@3: return 0; nuclear@3: } nuclear@3: nuclear@3: inline const UByte* OVR_CDECL OVR_memrchr(const UByte* str, UPInt size, UByte c) nuclear@3: { nuclear@3: for (SPInt i = (SPInt)size - 1; i >= 0; i--) nuclear@3: { nuclear@3: if (str[i] == c) nuclear@3: return str + i; nuclear@3: } nuclear@3: return 0; nuclear@3: } nuclear@3: nuclear@3: inline char* OVR_CDECL OVR_strrchr(char* str, char c) nuclear@3: { nuclear@3: UPInt len = OVR_strlen(str); nuclear@3: for (UPInt i=len; i>0; i--) nuclear@3: if (str[i]==c) nuclear@3: return str+i; nuclear@3: return 0; nuclear@3: } nuclear@3: nuclear@3: nuclear@3: double OVR_CDECL OVR_strtod(const char* string, char** tailptr); nuclear@3: nuclear@3: inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix) nuclear@3: { nuclear@3: return strtol(string, tailptr, radix); nuclear@3: } nuclear@3: nuclear@3: inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix) nuclear@3: { nuclear@3: return strtoul(string, tailptr, radix); nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, UPInt size) nuclear@3: { nuclear@3: return strncmp(ws1, ws2, size); nuclear@3: } nuclear@3: nuclear@3: inline UInt64 OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) nuclear@3: { nuclear@3: #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) nuclear@3: return _strtoui64(nptr, endptr, base); nuclear@3: #else nuclear@3: return strtoull(nptr, endptr, base); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: inline SInt64 OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) nuclear@3: { nuclear@3: #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) nuclear@3: return _strtoi64(nptr, endptr, base); nuclear@3: #else nuclear@3: return strtoll(nptr, endptr, base); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: nuclear@3: inline SInt64 OVR_CDECL OVR_atoq(const char* string) nuclear@3: { nuclear@3: #if defined(OVR_CC_MSVC) && !defined(OVR_OS_WINCE) nuclear@3: return _atoi64(string); nuclear@3: #else nuclear@3: return atoll(string); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: inline UInt64 OVR_CDECL OVR_atouq(const char* string) nuclear@3: { nuclear@3: return OVR_strtouq(string, NULL, 10); nuclear@3: } nuclear@3: nuclear@3: nuclear@3: // Implemented in GStd.cpp in platform-specific manner. nuclear@3: int OVR_CDECL OVR_stricmp(const char* dest, const char* src); nuclear@3: int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, UPInt count); nuclear@3: nuclear@3: inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* format, ...) nuclear@3: { nuclear@3: va_list argList; nuclear@3: va_start(argList,format); nuclear@3: UPInt ret; nuclear@3: #if defined(OVR_CC_MSVC) nuclear@3: #if defined(OVR_MSVC_SAFESTRING) nuclear@3: ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); nuclear@3: OVR_ASSERT(ret != -1); nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character nuclear@3: OVR_ASSERT(ret != -1); nuclear@3: dest[destsize-1] = 0; nuclear@3: #endif nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: ret = vsprintf(dest, format, argList); nuclear@3: OVR_ASSERT(ret < destsize); nuclear@3: #endif nuclear@3: va_end(argList); nuclear@3: return ret; nuclear@3: } nuclear@3: nuclear@3: inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList) nuclear@3: { nuclear@3: UPInt ret; nuclear@3: #if defined(OVR_CC_MSVC) nuclear@3: #if defined(OVR_MSVC_SAFESTRING) nuclear@3: dest[0] = '\0'; nuclear@3: int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); nuclear@3: if (rv == -1) nuclear@3: { nuclear@3: dest[destsize - 1] = '\0'; nuclear@3: ret = destsize - 1; nuclear@3: } nuclear@3: else nuclear@3: ret = (UPInt)rv; nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: int rv = _vsnprintf(dest, destsize - 1, format, argList); nuclear@3: OVR_ASSERT(rv != -1); nuclear@3: ret = (UPInt)rv; nuclear@3: dest[destsize-1] = 0; nuclear@3: #endif nuclear@3: #else nuclear@3: OVR_UNUSED(destsize); nuclear@3: ret = (UPInt)vsprintf(dest, format, argList); nuclear@3: OVR_ASSERT(ret < destsize); nuclear@3: #endif nuclear@3: return ret; nuclear@3: } nuclear@3: nuclear@3: // Returns the number of characters in the formatted string. nuclear@3: inline UPInt OVR_CDECL OVR_vscprintf(const char * format, va_list argList) nuclear@3: { nuclear@3: UPInt ret; nuclear@3: #if defined(OVR_CC_MSVC) nuclear@3: ret = (UPInt) _vscprintf(format, argList); nuclear@3: #else nuclear@3: ret = (UPInt) vsnprintf(NULL, 0, format, argList); nuclear@3: #endif nuclear@3: return ret; nuclear@3: } nuclear@3: nuclear@3: nuclear@3: wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, UPInt destsize, const wchar_t* src); nuclear@3: wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, UPInt destsize, const wchar_t* src, UPInt count); nuclear@3: wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, UPInt destsize, const wchar_t* src); nuclear@3: UPInt OVR_CDECL OVR_wcslen(const wchar_t* str); nuclear@3: int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b); nuclear@3: int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b); nuclear@3: nuclear@3: inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) nuclear@3: { nuclear@3: #if defined(OVR_OS_WIN32) nuclear@3: #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) nuclear@3: return ::_wcsicoll(a, b); nuclear@3: #else nuclear@3: return ::wcsicoll(a, b); nuclear@3: #endif nuclear@3: #else nuclear@3: // not supported, use regular wcsicmp nuclear@3: return OVR_wcsicmp(a, b); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) nuclear@3: { nuclear@3: #if defined(OVR_OS_WIN32) || defined(OVR_OS_LINUX) nuclear@3: return wcscoll(a, b); nuclear@3: #else nuclear@3: // not supported, use regular wcscmp nuclear@3: return OVR_wcscmp(a, b); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: #ifndef OVR_NO_WCTYPE nuclear@3: nuclear@3: inline int OVR_CDECL UnicodeCharIs(const UInt16* table, wchar_t charCode) nuclear@3: { nuclear@3: unsigned offset = table[charCode >> 8]; nuclear@3: if (offset == 0) return 0; nuclear@3: if (offset == 1) return 1; nuclear@3: return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0; nuclear@3: } nuclear@3: nuclear@3: extern const UInt16 UnicodeAlnumBits[]; nuclear@3: extern const UInt16 UnicodeAlphaBits[]; nuclear@3: extern const UInt16 UnicodeDigitBits[]; nuclear@3: extern const UInt16 UnicodeSpaceBits[]; nuclear@3: extern const UInt16 UnicodeXDigitBits[]; nuclear@3: nuclear@3: // Uncomment if necessary nuclear@3: //extern const UInt16 UnicodeCntrlBits[]; nuclear@3: //extern const UInt16 UnicodeGraphBits[]; nuclear@3: //extern const UInt16 UnicodeLowerBits[]; nuclear@3: //extern const UInt16 UnicodePrintBits[]; nuclear@3: //extern const UInt16 UnicodePunctBits[]; nuclear@3: //extern const UInt16 UnicodeUpperBits[]; nuclear@3: nuclear@3: inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits, charCode); } nuclear@3: inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits, charCode); } nuclear@3: inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits, charCode); } nuclear@3: inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits, charCode); } nuclear@3: inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); } nuclear@3: nuclear@3: // Uncomment if necessary nuclear@3: //inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits, charCode); } nuclear@3: //inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits, charCode); } nuclear@3: //inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits, charCode); } nuclear@3: //inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits, charCode); } nuclear@3: //inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits, charCode); } nuclear@3: //inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits, charCode); } nuclear@3: nuclear@3: int OVR_CDECL OVR_towupper(wchar_t charCode); nuclear@3: int OVR_CDECL OVR_towlower(wchar_t charCode); nuclear@3: nuclear@3: #else // OVR_NO_WCTYPE nuclear@3: nuclear@3: inline int OVR_CDECL OVR_iswspace(wchar_t c) nuclear@3: { nuclear@3: return iswspace(c); nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_iswdigit(wchar_t c) nuclear@3: { nuclear@3: return iswdigit(c); nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_iswxdigit(wchar_t c) nuclear@3: { nuclear@3: return iswxdigit(c); nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_iswalpha(wchar_t c) nuclear@3: { nuclear@3: return iswalpha(c); nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_iswalnum(wchar_t c) nuclear@3: { nuclear@3: return iswalnum(c); nuclear@3: } nuclear@3: nuclear@3: inline wchar_t OVR_CDECL OVR_towlower(wchar_t c) nuclear@3: { nuclear@3: return (wchar_t)towlower(c); nuclear@3: } nuclear@3: nuclear@3: inline wchar_t OVR_towupper(wchar_t c) nuclear@3: { nuclear@3: return (wchar_t)towupper(c); nuclear@3: } nuclear@3: nuclear@3: #endif // OVR_NO_WCTYPE nuclear@3: nuclear@3: // ASCII versions of tolower and toupper. Don't use "char" nuclear@3: inline int OVR_CDECL OVR_tolower(int c) nuclear@3: { nuclear@3: return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; nuclear@3: } nuclear@3: nuclear@3: inline int OVR_CDECL OVR_toupper(int c) nuclear@3: { nuclear@3: return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; nuclear@3: } nuclear@3: nuclear@3: nuclear@3: nuclear@3: inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr) nuclear@3: { nuclear@3: #if defined(OVR_OS_OTHER) nuclear@3: OVR_UNUSED(tailptr); nuclear@3: char buffer[64]; nuclear@3: char* tp = NULL; nuclear@3: UPInt max = OVR_wcslen(string); nuclear@3: if (max > 63) max = 63; nuclear@3: unsigned char c = 0; nuclear@3: for (UPInt i=0; i < max; i++) nuclear@3: { nuclear@3: c = (unsigned char)string[i]; nuclear@3: buffer[i] = ((c) < 128 ? (char)c : '!'); nuclear@3: } nuclear@3: buffer[max] = 0; nuclear@3: return OVR_strtod(buffer, &tp); nuclear@3: #else nuclear@3: return wcstod(string, tailptr); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix) nuclear@3: { nuclear@3: #if defined(OVR_OS_OTHER) nuclear@3: OVR_UNUSED(tailptr); nuclear@3: char buffer[64]; nuclear@3: char* tp = NULL; nuclear@3: UPInt max = OVR_wcslen(string); nuclear@3: if (max > 63) max = 63; nuclear@3: unsigned char c = 0; nuclear@3: for (UPInt i=0; i < max; i++) nuclear@3: { nuclear@3: c = (unsigned char)string[i]; nuclear@3: buffer[i] = ((c) < 128 ? (char)c : '!'); nuclear@3: } nuclear@3: buffer[max] = 0; nuclear@3: return strtol(buffer, &tp, radix); nuclear@3: #else nuclear@3: return wcstol(string, tailptr, radix); nuclear@3: #endif nuclear@3: } nuclear@3: nuclear@3: } // OVR nuclear@3: nuclear@3: #endif // OVR_Std_h