summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx/src/string.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bx/src/string.cpp')
-rw-r--r--3rdparty/bx/src/string.cpp584
1 files changed, 499 insertions, 85 deletions
diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp
index c53a9de1155..dbb59e5090a 100644
--- a/3rdparty/bx/src/string.cpp
+++ b/3rdparty/bx/src/string.cpp
@@ -60,21 +60,57 @@ namespace bx
return _ch + (isUpper(_ch) ? 0x20 : 0);
}
+ void toLowerUnsafe(char* _inOutStr, int32_t _len)
+ {
+ for (int32_t ii = 0; ii < _len; ++ii)
+ {
+ *_inOutStr = toLower(*_inOutStr);
+ }
+ }
+
+ void toLower(char* _inOutStr, int32_t _max)
+ {
+ const int32_t len = strnlen(_inOutStr, _max);
+ toLowerUnsafe(_inOutStr, len);
+ }
+
char toUpper(char _ch)
{
return _ch - (isLower(_ch) ? 0x20 : 0);
}
+ void toUpperUnsafe(char* _inOutStr, int32_t _len)
+ {
+ for (int32_t ii = 0; ii < _len; ++ii)
+ {
+ *_inOutStr = toUpper(*_inOutStr);
+ }
+ }
+
+ void toUpper(char* _inOutStr, int32_t _max)
+ {
+ const int32_t len = strnlen(_inOutStr, _max);
+ toUpperUnsafe(_inOutStr, len);
+ }
+
bool toBool(const char* _str)
{
char ch = toLower(_str[0]);
return ch == 't' || ch == '1';
}
- int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max)
+ typedef char (*CharFn)(char _ch);
+
+ inline char toNoop(char _ch)
+ {
+ return _ch;
+ }
+
+ template<CharFn fn>
+ int32_t strCmp(const char* _lhs, const char* _rhs, int32_t _max)
{
for (
- ; 0 < _max && *_lhs == *_rhs
+ ; 0 < _max && fn(*_lhs) == fn(*_rhs)
; ++_lhs, ++_rhs, --_max
)
{
@@ -85,62 +121,60 @@ namespace bx
}
}
- return 0 == _max ? 0 : *_lhs - *_rhs;
+ return 0 == _max ? 0 : fn(*_lhs) - fn(*_rhs);
}
- int32_t strincmp(const char* _lhs, const char* _rhs, size_t _max)
+ int32_t strncmp(const char* _lhs, const char* _rhs, int32_t _max)
{
- for (
- ; 0 < _max && toLower(*_lhs) == toLower(*_rhs)
- ; ++_lhs, ++_rhs, --_max
- )
- {
- if (*_lhs == '\0'
- || *_rhs == '\0')
- {
- break;
- }
- }
+ return strCmp<toNoop>(_lhs, _rhs, _max);
+ }
- return 0 == _max ? 0 : *_lhs - *_rhs;
+ int32_t strincmp(const char* _lhs, const char* _rhs, int32_t _max)
+ {
+ return strCmp<toLower>(_lhs, _rhs, _max);
}
- size_t strnlen(const char* _str, size_t _max)
+ int32_t strnlen(const char* _str, int32_t _max)
{
- const char* ptr;
- for (ptr = _str; 0 < _max && *ptr != '\0'; ++ptr, --_max) {};
- return ptr - _str;
+ if (NULL == _str)
+ {
+ return 0;
+ }
+
+ const char* ptr = _str;
+ for (; 0 < _max && *ptr != '\0'; ++ptr, --_max) {};
+ return int32_t(ptr - _str);
}
- size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_t _num)
+ int32_t strlncpy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num)
{
BX_CHECK(NULL != _dst, "_dst can't be NULL!");
BX_CHECK(NULL != _src, "_src can't be NULL!");
BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
- const size_t len = strnlen(_src, _num);
- const size_t max = _dstSize-1;
- const size_t num = (len < max ? len : max);
- memcpy(_dst, _src, num);
+ const int32_t len = strnlen(_src, _num);
+ const int32_t max = _dstSize-1;
+ const int32_t num = (len < max ? len : max);
+ memCopy(_dst, _src, num);
_dst[num] = '\0';
return num;
}
- size_t strlncat(char* _dst, size_t _dstSize, const char* _src, size_t _num)
+ int32_t strlncat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num)
{
BX_CHECK(NULL != _dst, "_dst can't be NULL!");
BX_CHECK(NULL != _src, "_src can't be NULL!");
BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
- const size_t max = _dstSize;
- const size_t len = strnlen(_dst, max);
+ const int32_t max = _dstSize;
+ const int32_t len = strnlen(_dst, max);
return strlncpy(&_dst[len], max-len, _src, _num);
}
- const char* strnchr(const char* _str, char _ch, size_t _max)
+ const char* strnchr(const char* _str, char _ch, int32_t _max)
{
- for (size_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii)
+ for (int32_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii)
{
if (_str[ii] == _ch)
{
@@ -151,9 +185,9 @@ namespace bx
return NULL;
}
- const char* strnrchr(const char* _str, char _ch, size_t _max)
+ const char* strnrchr(const char* _str, char _ch, int32_t _max)
{
- for (size_t ii = strnlen(_str, _max); 0 < ii; --ii)
+ for (int32_t ii = strnlen(_str, _max); 0 < ii; --ii)
{
if (_str[ii] == _ch)
{
@@ -164,17 +198,18 @@ namespace bx
return NULL;
}
- const char* strnstr(const char* _str, const char* _find, size_t _max)
+ template<CharFn fn>
+ static const char* strStr(const char* _str, int32_t _strMax, const char* _find, int32_t _findMax)
{
const char* ptr = _str;
- size_t stringLen = strnlen(_str, _max);
- const size_t findLen = strnlen(_find);
+ int32_t stringLen = strnlen(_str, _strMax);
+ const int32_t findLen = strnlen(_find, _findMax);
for (; stringLen >= findLen; ++ptr, --stringLen)
{
// Find start of the string.
- while (*ptr != *_find)
+ while (fn(*ptr) != fn(*_find) )
{
++ptr;
--stringLen;
@@ -191,7 +226,7 @@ namespace bx
const char* search = _find;
// Start comparing.
- while (*string++ == *search++)
+ while (fn(*string++) == fn(*search++) )
{
// If end of the 'search' string is reached, all characters match.
if ('\0' == *search)
@@ -204,44 +239,14 @@ namespace bx
return NULL;
}
- const char* stristr(const char* _str, const char* _find, size_t _max)
+ const char* strnstr(const char* _str, const char* _find, int32_t _max)
{
- const char* ptr = _str;
-
- size_t stringLen = strnlen(_str, _max);
- const size_t findLen = strnlen(_find);
-
- for (; stringLen >= findLen; ++ptr, --stringLen)
- {
- // Find start of the string.
- while (toLower(*ptr) != toLower(*_find) )
- {
- ++ptr;
- --stringLen;
-
- // Search pattern lenght can't be longer than the string.
- if (findLen > stringLen)
- {
- return NULL;
- }
- }
-
- // Set pointers.
- const char* string = ptr;
- const char* search = _find;
-
- // Start comparing.
- while (toLower(*string++) == toLower(*search++) )
- {
- // If end of the 'search' string is reached, all characters match.
- if ('\0' == *search)
- {
- return ptr;
- }
- }
- }
+ return strStr<toNoop>(_str, _max, _find, INT32_MAX);
+ }
- return NULL;
+ const char* stristr(const char* _str, const char* _find, int32_t _max)
+ {
+ return strStr<toLower>(_str, _max, _find, INT32_MAX);
}
const char* strnl(const char* _str)
@@ -324,7 +329,7 @@ namespace bx
return NULL;
}
- void eolLF(char* _out, size_t _size, const char* _str)
+ void eolLF(char* _out, int32_t _size, const char* _str)
{
if (0 < _size)
{
@@ -343,7 +348,7 @@ namespace bx
const char* findIdentifierMatch(const char* _str, const char* _word)
{
- size_t len = strnlen(_word);
+ int32_t len = strnlen(_word);
const char* ptr = strnstr(_str, _word);
for (; NULL != ptr; ptr = strnstr(ptr + len, _word) )
{
@@ -382,13 +387,422 @@ namespace bx
return NULL;
}
- int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err);
+ namespace
+ {
+ struct Param
+ {
+ Param()
+ : width(0)
+ , base(10)
+ , prec(6)
+ , fill(' ')
+ , bits(0)
+ , left(false)
+ , upper(false)
+ , spec(false)
+ , sign(false)
+ {
+ }
+
+ int32_t width;
+ uint32_t base;
+ uint32_t prec;
+ char fill;
+ uint8_t bits;
+ bool left;
+ bool upper;
+ bool spec;
+ bool sign;
+ };
+
+ static int32_t write(WriterI* _writer, const char* _str, int32_t _len, const Param& _param, Error* _err)
+ {
+ int32_t size = 0;
+ int32_t len = (int32_t)strnlen(_str, _len);
+ int32_t padding = _param.width > len ? _param.width - len : 0;
+ bool sign = _param.sign && len > 1 && _str[0] != '-';
+ padding = padding > 0 ? padding - sign : 0;
+
+ if (!_param.left)
+ {
+ size += writeRep(_writer, _param.fill, padding, _err);
+ }
+
+ if (NULL == _str)
+ {
+ size += write(_writer, "(null)", 6, _err);
+ }
+ else if (_param.upper)
+ {
+ for (int32_t ii = 0; ii < len; ++ii)
+ {
+ size += write(_writer, toUpper(_str[ii]), _err);
+ }
+ }
+ else if (sign)
+ {
+ size += write(_writer, '+', _err);
+ size += write(_writer, _str, len, _err);
+ }
+ else
+ {
+ size += write(_writer, _str, len, _err);
+ }
+
+ if (_param.left)
+ {
+ size += writeRep(_writer, _param.fill, padding, _err);
+ }
+
+ return size;
+ }
+
+ static int32_t write(WriterI* _writer, char _ch, const Param& _param, Error* _err)
+ {
+ return write(_writer, &_ch, 1, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, const char* _str, const Param& _param, Error* _err)
+ {
+ return write(_writer, _str, INT32_MAX, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, int32_t _i, const Param& _param, Error* _err)
+ {
+ char str[33];
+ int32_t len = toString(str, sizeof(str), _i, _param.base);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, int64_t _i, const Param& _param, Error* _err)
+ {
+ char str[33];
+ int32_t len = toString(str, sizeof(str), _i, _param.base);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, uint32_t _u, const Param& _param, Error* _err)
+ {
+ char str[33];
+ int32_t len = toString(str, sizeof(str), _u, _param.base);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, uint64_t _u, const Param& _param, Error* _err)
+ {
+ char str[33];
+ int32_t len = toString(str, sizeof(str), _u, _param.base);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, double _d, const Param& _param, Error* _err)
+ {
+ char str[1024];
+ int32_t len = toString(str, sizeof(str), _d);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ if (_param.upper)
+ {
+ toUpperUnsafe(str, len);
+ }
+
+ const char* dot = strnchr(str, '.');
+ if (NULL != dot)
+ {
+ const int32_t precLen = int32_t(
+ dot
+ + uint32_min(_param.prec + _param.spec, 1)
+ + _param.prec
+ - str
+ );
+ if (precLen > len)
+ {
+ for (int32_t ii = len; ii < precLen; ++ii)
+ {
+ str[ii] = '0';
+ }
+ str[precLen] = '\0';
+ }
+ len = precLen;
+ }
+
+ return write(_writer, str, len, _param, _err);
+ }
+
+ static int32_t write(WriterI* _writer, const void* _ptr, const Param& _param, Error* _err)
+ {
+ char str[35] = "0x";
+ int32_t len = toString(str + 2, sizeof(str) - 2, uint32_t(uintptr_t(_ptr) ), 16);
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ len += 2;
+ return write(_writer, str, len, _param, _err);
+ }
+ } // anonymous namespace
+
+ int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err)
+ {
+ MemoryReader reader(_format, uint32_t(strnlen(_format) ) );
+
+ int32_t size = 0;
+
+ while (_err->isOk() )
+ {
+ char ch = '\0';
+
+ Error err;
+ read(&reader, ch, &err);
+
+ if (!_err->isOk()
+ || !err.isOk() )
+ {
+ break;
+ }
+ else if ('%' == ch)
+ {
+ // %[flags][width][.precision][length sub-specifier]specifier
+ read(&reader, ch);
+
+ Param param;
+
+ // flags
+ while (' ' == ch
+ || '-' == ch
+ || '+' == ch
+ || '0' == ch
+ || '#' == ch)
+ {
+ switch (ch)
+ {
+ default:
+ case ' ': param.fill = ' '; break;
+ case '-': param.left = true; break;
+ case '+': param.sign = true; break;
+ case '0': param.fill = '0'; break;
+ case '#': param.spec = true; break;
+ }
+
+ read(&reader, ch);
+ }
+
+ if (param.left)
+ {
+ param.fill = ' ';
+ }
+
+ // width
+ if ('*' == ch)
+ {
+ read(&reader, ch);
+ param.width = va_arg(_argList, int32_t);
+
+ if (0 > param.width)
+ {
+ param.left = true;
+ param.width = -param.width;
+ }
+
+ }
+ else
+ {
+ while (isNumeric(ch) )
+ {
+ param.width = param.width * 10 + ch - '0';
+ read(&reader, ch);
+ }
+ }
+
+ // .precision
+ if ('.' == ch)
+ {
+ read(&reader, ch);
+
+ if ('*' == ch)
+ {
+ read(&reader, ch);
+ param.prec = va_arg(_argList, int32_t);
+ }
+ else
+ {
+ param.prec = 0;
+ while (isNumeric(ch) )
+ {
+ param.prec = param.prec * 10 + ch - '0';
+ read(&reader, ch);
+ }
+ }
+ }
+
+ // length sub-specifier
+ while ('h' == ch
+ || 'I' == ch
+ || 'l' == ch
+ || 'j' == ch
+ || 't' == ch
+ || 'z' == ch)
+ {
+ switch (ch)
+ {
+ default: break;
+
+ case 'j': param.bits = sizeof(intmax_t )*8; break;
+ case 't': param.bits = sizeof(size_t )*8; break;
+ case 'z': param.bits = sizeof(ptrdiff_t)*8; break;
+
+ case 'h': case 'I': case 'l':
+ switch (ch)
+ {
+ case 'h': param.bits = sizeof(short int)*8; break;
+ case 'l': param.bits = sizeof(long int )*8; break;
+ default: break;
+ }
+
+ read(&reader, ch);
+ switch (ch)
+ {
+ case 'h': param.bits = sizeof(signed char )*8; break;
+ case 'l': param.bits = sizeof(long long int)*8; break;
+ case '3':
+ case '6':
+ read(&reader, ch);
+ switch (ch)
+ {
+ case '2': param.bits = sizeof(int32_t)*8; break;
+ case '4': param.bits = sizeof(int64_t)*8; break;
+ default: break;
+ }
+ break;
+
+ default: seek(&reader, -1); break;
+ }
+ break;
+ }
+
+ read(&reader, ch);
+ }
+
+ // specifier
+ switch (toLower(ch) )
+ {
+ case 'c':
+ size += write(_writer, char(va_arg(_argList, int32_t) ), param, _err);
+ break;
+
+ case 's':
+ size += write(_writer, va_arg(_argList, const char*), param, _err);
+ break;
+
+ case 'o':
+ param.base = 8;
+ switch (param.bits)
+ {
+ default: size += write(_writer, va_arg(_argList, int32_t), param, _err); break;
+ case 64: size += write(_writer, va_arg(_argList, int64_t), param, _err); break;
+ }
+ break;
+
+ case 'i':
+ case 'd':
+ param.base = 10;
+ switch (param.bits)
+ {
+ default: size += write(_writer, va_arg(_argList, int32_t), param, _err); break;
+ case 64: size += write(_writer, va_arg(_argList, int64_t), param, _err); break;
+ };
+ break;
+
+ case 'e':
+ case 'f':
+ case 'g':
+ param.upper = isUpper(ch);
+ size += write(_writer, va_arg(_argList, double), param, _err);
+ break;
+
+ case 'p':
+ size += write(_writer, va_arg(_argList, void*), param, _err);
+ break;
+
+ case 'x':
+ param.base = 16;
+ param.upper = isUpper(ch);
+ switch (param.bits)
+ {
+ default: size += write(_writer, va_arg(_argList, uint32_t), param, _err); break;
+ case 64: size += write(_writer, va_arg(_argList, uint64_t), param, _err); break;
+ }
+ break;
+
+ case 'u':
+ param.base = 10;
+ switch (param.bits)
+ {
+ default: size += write(_writer, va_arg(_argList, uint32_t), param, _err); break;
+ case 64: size += write(_writer, va_arg(_argList, uint64_t), param, _err); break;
+ }
+ break;
+
+ default:
+ size += write(_writer, ch, _err);
+ break;
+ }
+ }
+ else
+ {
+ size += write(_writer, ch, _err);
+ }
+ }
+
+ size += write(_writer, '\0', _err);
+
+ return size;
+ }
+
+ int32_t write(WriterI* _writer, Error* _err, const char* _format, ...)
+ {
+ va_list argList;
+ va_start(argList, _format);
+ int32_t size = write(_writer, _format, argList, _err);
+ va_end(argList);
+ return size;
+ }
- int32_t vsnprintfRef(char* _out, size_t _max, const char* _format, va_list _argList)
+ int32_t vsnprintfRef(char* _out, int32_t _max, const char* _format, va_list _argList)
{
if (1 < _max)
{
- StaticMemoryBlockWriter writer(_out, _max-1);
+ StaticMemoryBlockWriter writer(_out, uint32_t(_max-1) );
_out[_max-1] = '\0';
Error err;
@@ -413,7 +827,7 @@ namespace bx
return size - 1 /* size without '\0' terminator */;
}
- int32_t vsnprintf(char* _out, size_t _max, const char* _format, va_list _argList)
+ int32_t vsnprintf(char* _out, int32_t _max, const char* _format, va_list _argList)
{
#if BX_CRT_NONE
return vsnprintfRef(_out, _max, _format, _argList);
@@ -432,7 +846,7 @@ namespace bx
#endif // BX_COMPILER_MSVC
}
- int32_t snprintf(char* _out, size_t _max, const char* _format, ...)
+ int32_t snprintf(char* _out, int32_t _max, const char* _format, ...)
{
va_list argList;
va_start(argList, _format);
@@ -441,7 +855,7 @@ namespace bx
return len;
}
- int32_t vsnwprintf(wchar_t* _out, size_t _max, const wchar_t* _format, va_list _argList)
+ int32_t vsnwprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, va_list _argList)
{
#if BX_CRT_NONE
BX_UNUSED(_out, _max, _format, _argList);
@@ -463,7 +877,7 @@ namespace bx
#endif // BX_COMPILER_MSVC
}
- int32_t swnprintf(wchar_t* _out, size_t _max, const wchar_t* _format, ...)
+ int32_t swnprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, ...)
{
va_list argList;
va_start(argList, _format);
@@ -487,7 +901,7 @@ namespace bx
return _filePath;
}
- void prettify(char* _out, size_t _count, uint64_t _size)
+ void prettify(char* _out, int32_t _count, uint64_t _size)
{
uint8_t idx = 0;
double size = double(_size);
@@ -502,12 +916,12 @@ namespace bx
snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0');
}
- size_t strlcpy(char* _dst, const char* _src, size_t _max)
+ int32_t strlcpy(char* _dst, const char* _src, int32_t _max)
{
return strlncpy(_dst, _max, _src);
}
- size_t strlcat(char* _dst, const char* _src, size_t _max)
+ int32_t strlcat(char* _dst, const char* _src, int32_t _max)
{
return strlncat(_dst, _max, _src);
}