| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- /*
- * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
- */
- #include <bx/bx.h>
- #include <bx/readerwriter.h>
- #include <bx/debug.h>
- namespace bx
- {
- void* memCopyRef(void* _dst, const void* _src, size_t _numBytes)
- {
- uint8_t* dst = (uint8_t*)_dst;
- const uint8_t* end = dst + _numBytes;
- const uint8_t* src = (const uint8_t*)_src;
- while (dst != end)
- {
- *dst++ = *src++;
- }
- return _dst;
- }
- void* memCopy(void* _dst, const void* _src, size_t _numBytes)
- {
- #if BX_CRT_NONE
- return memCopyRef(_dst, _src, _numBytes);
- #else
- return ::memcpy(_dst, _src, _numBytes);
- #endif // BX_CRT_NONE
- }
- void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch)
- {
- const uint8_t* src = (const uint8_t*)_src;
- uint8_t* dst = (uint8_t*)_dst;
- for (uint32_t ii = 0; ii < _num; ++ii)
- {
- memCopy(dst, src, _size);
- src += _srcPitch;
- dst += _dstPitch;
- }
- }
- ///
- void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch)
- {
- memCopy(_dst, _src, _size, _num, _srcPitch, _size);
- }
- ///
- void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch)
- {
- memCopy(_dst, _src, _size, _num, _size, _dstPitch);
- }
- void* memMoveRef(void* _dst, const void* _src, size_t _numBytes)
- {
- uint8_t* dst = (uint8_t*)_dst;
- const uint8_t* src = (const uint8_t*)_src;
- if (_numBytes == 0
- || dst == src)
- {
- return dst;
- }
- // if (src+_numBytes <= dst || end <= src)
- if (dst < src)
- {
- return memcpy(_dst, _src, _numBytes);
- }
- for (intptr_t ii = _numBytes-1; ii >= 0; --ii)
- {
- dst[ii] = src[ii];
- }
- return _dst;
- }
- void* memMove(void* _dst, const void* _src, size_t _numBytes)
- {
- #if BX_CRT_NONE
- return memMoveRef(_dst, _src, _numBytes);
- #else
- return ::memmove(_dst, _src, _numBytes);
- #endif // BX_CRT_NONE
- }
- void* memSetRef(void* _dst, uint8_t _ch, size_t _numBytes)
- {
- uint8_t* dst = (uint8_t*)_dst;
- const uint8_t* end = dst + _numBytes;
- while (dst != end)
- {
- *dst++ = char(_ch);
- }
- return _dst;
- }
- void* memSet(void* _dst, uint8_t _ch, size_t _numBytes)
- {
- #if BX_CRT_NONE
- return memSetRef(_dst, _ch, _numBytes);
- #else
- return ::memset(_dst, _ch, _numBytes);
- #endif // BX_CRT_NONE
- }
- namespace
- {
- struct Param
- {
- Param()
- : width(0)
- , base(10)
- , prec(6)
- , fill(' ')
- , left(false)
- , upper(false)
- {
- }
- int32_t width;
- uint32_t base;
- uint32_t prec;
- char fill;
- bool left;
- bool upper;
- };
- 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;
- if (!_param.left)
- {
- size += writeRep(_writer, _param.fill, padding, _err);
- }
- if (_param.upper)
- {
- for (int32_t ii = 0; ii < len; ++ii)
- {
- size += write(_writer, toUpper(_str[ii]), _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, uint32_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, double _d, const Param& _param, Error* _err)
- {
- char str[1024];
- int32_t len = toString(str, sizeof(str), _d);
- if (len == 0)
- {
- return 0;
- }
- const char* dot = strnchr(str, '.');
- const int32_t precLen = int32_t(dot + 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, strnlen(_format) );
- int32_t size = 0;
- while (_err->isOk() )
- {
- char ch = '\0';
- read(&reader, ch, _err);
- if (!_err->isOk() )
- {
- break;
- }
- else if ('%' == ch)
- {
- // %[ -0][<width>][.<precision>]
- read(&reader, ch);
- Param param;
- while (' ' == ch
- || '-' == ch
- || '0' == ch)
- {
- switch (ch)
- {
- case '-': param.left = true; break;
- case ' ': param.fill = ' '; break;
- case '0': param.fill = '0'; break;
- }
- if (param.left)
- {
- param.fill = ' ';
- }
- read(&reader, ch);
- }
- 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);
- }
- }
- 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);
- }
- }
- }
- 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 'i':
- case 'd':
- param.base = 10;
- size += write(_writer, va_arg(_argList, int32_t), param, _err);
- break;
- case 'f':
- 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);
- size += write(_writer, va_arg(_argList, uint32_t), param, _err);
- break;
- case 'u':
- param.base = 10;
- size += write(_writer, va_arg(_argList, uint32_t), param, _err);
- 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;
- }
- } // namespace bx
|