mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 20:52:37 +01:00
vsnprintf: Implemented length sub-specifier.
This commit is contained in:
@@ -223,9 +223,15 @@ namespace bx
|
||||
///
|
||||
int32_t toString(char* _out, size_t _max, int32_t _value, uint32_t _base = 10);
|
||||
|
||||
///
|
||||
int32_t toString(char* _out, size_t _max, int64_t _value, uint32_t _base = 10);
|
||||
|
||||
///
|
||||
int32_t toString(char* _out, size_t _max, uint32_t _value, uint32_t _base = 10);
|
||||
|
||||
///
|
||||
int32_t toString(char* _out, size_t _max, uint64_t _value, uint32_t _base = 10);
|
||||
|
||||
///
|
||||
uint32_t hashMurmur2A(const StringView& _data);
|
||||
|
||||
|
||||
99
src/crt.cpp
99
src/crt.cpp
@@ -153,6 +153,7 @@ namespace bx
|
||||
, base(10)
|
||||
, prec(6)
|
||||
, fill(' ')
|
||||
, bits(0)
|
||||
, left(false)
|
||||
, upper(false)
|
||||
, spec(false)
|
||||
@@ -164,6 +165,7 @@ namespace bx
|
||||
uint32_t base;
|
||||
uint32_t prec;
|
||||
char fill;
|
||||
uint8_t bits;
|
||||
bool left;
|
||||
bool upper;
|
||||
bool spec;
|
||||
@@ -235,7 +237,7 @@ namespace bx
|
||||
return write(_writer, str, len, _param, _err);
|
||||
}
|
||||
|
||||
static int32_t write(WriterI* _writer, uint32_t _i, const Param& _param, Error* _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);
|
||||
@@ -248,6 +250,32 @@ namespace bx
|
||||
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];
|
||||
@@ -323,9 +351,10 @@ namespace bx
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
default:
|
||||
case ' ': param.fill = ' '; break;
|
||||
case '-': param.left = true; break;
|
||||
case '+': param.sign = true; break;
|
||||
case ' ': param.fill = ' '; break;
|
||||
case '0': param.fill = '0'; break;
|
||||
case '#': param.spec = true; break;
|
||||
}
|
||||
@@ -379,6 +408,48 @@ namespace bx
|
||||
}
|
||||
}
|
||||
|
||||
// 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 '6':
|
||||
read(&reader, ch);
|
||||
if ('4' == ch) { param.bits = sizeof(int64_t)*8; }
|
||||
break;
|
||||
|
||||
default: seek(&reader, -1); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
read(&reader, ch);
|
||||
}
|
||||
|
||||
switch (toLower(ch) )
|
||||
{
|
||||
case 'c':
|
||||
@@ -391,13 +462,21 @@ namespace bx
|
||||
|
||||
case 'o':
|
||||
param.base = 8;
|
||||
size += write(_writer, va_arg(_argList, int32_t), param, _err);
|
||||
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;
|
||||
size += write(_writer, va_arg(_argList, int32_t), param, _err);
|
||||
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 'f':
|
||||
@@ -411,12 +490,20 @@ namespace bx
|
||||
case 'x':
|
||||
param.base = 16;
|
||||
param.upper = isUpper(ch);
|
||||
size += write(_writer, va_arg(_argList, uint32_t), param, _err);
|
||||
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;
|
||||
size += write(_writer, va_arg(_argList, uint32_t), param, _err);
|
||||
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:
|
||||
|
||||
61
src/dtoa.cpp
61
src/dtoa.cpp
@@ -487,6 +487,29 @@ namespace bx
|
||||
return toString(_dst, _max, uint32_t(_value), _base);
|
||||
}
|
||||
|
||||
int32_t toString(char* _dst, size_t _max, int64_t _value, uint32_t _base)
|
||||
{
|
||||
if (_base == 10
|
||||
&& _value < 0)
|
||||
{
|
||||
if (_max < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
_max = toString(_dst + 1, _max - 1, uint64_t(-_value), _base);
|
||||
if (_max == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*_dst = '-';
|
||||
return int32_t(_max + 1);
|
||||
}
|
||||
|
||||
return toString(_dst, _max, uint64_t(_value), _base);
|
||||
}
|
||||
|
||||
int32_t toString(char* _dst, size_t _max, uint32_t _value, uint32_t _base)
|
||||
{
|
||||
char data[32];
|
||||
@@ -525,4 +548,42 @@ namespace bx
|
||||
return int32_t(len);
|
||||
}
|
||||
|
||||
int32_t toString(char* _dst, size_t _max, uint64_t _value, uint32_t _base)
|
||||
{
|
||||
char data[32];
|
||||
size_t len = 0;
|
||||
|
||||
if (_base > 16
|
||||
|| _base < 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
const uint64_t rem = _value % _base;
|
||||
_value /= _base;
|
||||
if (rem < 10)
|
||||
{
|
||||
data[len++] = char('0' + rem);
|
||||
}
|
||||
else
|
||||
{
|
||||
data[len++] = char('a' + rem - 10);
|
||||
}
|
||||
|
||||
} while (_value != 0);
|
||||
|
||||
if (_max < len + 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
reverse(data, len);
|
||||
|
||||
memCopy(_dst, data, len);
|
||||
_dst[len] = '\0';
|
||||
return int32_t(len);
|
||||
}
|
||||
|
||||
} // namespace bx
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "test.h"
|
||||
#include <bx/string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
TEST_CASE("vsnprintf NULL buffer", "No output buffer provided.")
|
||||
{
|
||||
@@ -81,6 +82,18 @@ TEST_CASE("vsnprintf d/i/o/u/x", "")
|
||||
REQUIRE(test("0000000000001234ABCD", "%020X", 0x1234abcd) );
|
||||
REQUIRE(test("000000000000edcb5433", "%020x", -0x1234abcd) );
|
||||
REQUIRE(test("000000000000EDCB5433", "%020X", -0x1234abcd) );
|
||||
|
||||
if (BX_ENABLED(BX_ARCH_32BIT) )
|
||||
{
|
||||
REQUIRE(test("2147483647", "%jd", INTMAX_MAX) );
|
||||
}
|
||||
else
|
||||
{
|
||||
REQUIRE(test("9223372036854775807", "%jd", INTMAX_MAX) );
|
||||
}
|
||||
|
||||
REQUIRE(test("18446744073709551615", "%" PRIu64, UINT64_MAX) );
|
||||
REQUIRE(test("ffffffffffffffff", "%016" PRIx64, UINT64_MAX) );
|
||||
}
|
||||
|
||||
TEST_CASE("vsnprintf modifiers", "")
|
||||
|
||||
Reference in New Issue
Block a user