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