mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-15 15:16:49 +02:00
integer to string conversion
replaced sprintf-based int-to-string functionality with built-in intToString
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include "Poco/FPEnvironment.h"
|
||||
#ifdef min
|
||||
#undef min
|
||||
@@ -51,9 +52,11 @@
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
#if !defined(POCO_NO_LOCALE)
|
||||
#include <locale>
|
||||
#include <locale>
|
||||
#endif
|
||||
|
||||
#define POCO_MAX_NUM_STRING_LEN 65
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
@@ -82,6 +85,10 @@ inline char thousandSeparator()
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// String to Number Conversions
|
||||
//
|
||||
|
||||
template <typename I>
|
||||
bool strToInt(const char* pStr, I& result, short base, char thSep = ',')
|
||||
/// Converts zero-terminated character array to integer number;
|
||||
@@ -357,6 +364,174 @@ bool strToFloat (const std::string& s, F& result, char& eu = Impl::DUMMY_EXP_UND
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Number to String Conversions
|
||||
//
|
||||
|
||||
namespace Impl {
|
||||
|
||||
class Ptr
|
||||
/// Utility char pointer wrapper class.
|
||||
/// Class ensures increment/decrement remain within boundaries.
|
||||
{
|
||||
public:
|
||||
Ptr(char* ptr, unsigned offset): _beg(ptr), _cur(ptr), _end(ptr + offset)
|
||||
{
|
||||
}
|
||||
|
||||
char*& operator ++ () // prefix
|
||||
{
|
||||
check(_cur + 1);
|
||||
return ++_cur;
|
||||
}
|
||||
|
||||
char* operator ++ (int) // postfix
|
||||
{
|
||||
check(_cur + 1);
|
||||
char* tmp = _cur++;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char*& operator -- () // prefix
|
||||
{
|
||||
check(_cur - 1);
|
||||
return --_cur;
|
||||
}
|
||||
|
||||
char* operator -- (int) // postfix
|
||||
{
|
||||
check(_cur - 1);
|
||||
char* tmp = _cur--;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char*& operator += (int incr)
|
||||
{
|
||||
check(_cur + incr);
|
||||
return _cur += incr;
|
||||
}
|
||||
|
||||
char*& operator -= (int decr)
|
||||
{
|
||||
check(_cur - decr);
|
||||
return _cur -= decr;
|
||||
}
|
||||
|
||||
operator char* () const
|
||||
{
|
||||
return _cur;
|
||||
}
|
||||
|
||||
unsigned span() const
|
||||
{
|
||||
return _end - _beg;
|
||||
}
|
||||
|
||||
private:
|
||||
void check(char* ptr)
|
||||
{
|
||||
if (ptr > _end) throw RangeException();
|
||||
}
|
||||
|
||||
const char* _beg;
|
||||
char* _cur;
|
||||
const char* _end;
|
||||
};
|
||||
|
||||
} // namespace Impl
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool intToStr(T value,
|
||||
unsigned short base,
|
||||
char* result,
|
||||
unsigned& size,
|
||||
bool prefix = false,
|
||||
int width = -1,
|
||||
char fill = ' ',
|
||||
char thSep = 0)
|
||||
/// Converts integer to string. Numeric bases from binary to hexadecimal are supported.
|
||||
/// If width is non-zero, it pads the return value with fill character to the specified width.
|
||||
/// When padding is zero character ('0'), it is prepended to the number itself; all other
|
||||
/// paddings are prepended to the formatted result with minus sign or base prefix included
|
||||
/// If prefix is true and base is octal or hexadecimal, respective prefix ('0' for octal,
|
||||
/// "0x" for hexadecimal) is prepended. For all other bases, prefix argument is ignored.
|
||||
/// Formatted string has at least [width] total length.
|
||||
{
|
||||
if (base < 2 || base > 0x10)
|
||||
{
|
||||
*result = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
Impl::Ptr ptr(result, size);
|
||||
int thCount = 0;
|
||||
T tmpVal;
|
||||
do
|
||||
{
|
||||
tmpVal = value;
|
||||
value /= base;
|
||||
*ptr++ = "FEDCBA9876543210123456789ABCDEF"[15 + (tmpVal - value * base)];
|
||||
if (thSep && (base == 10) && (++thCount == 3))
|
||||
{
|
||||
*ptr++ = thSep;
|
||||
thCount = 0;
|
||||
}
|
||||
} while (value);
|
||||
|
||||
if ('0' == fill)
|
||||
{
|
||||
if (tmpVal < 0) --width;
|
||||
if (prefix && base == 010) --width;
|
||||
if (prefix && base == 0x10) width -= 2;
|
||||
while ((ptr - result) < width) *ptr++ = fill;
|
||||
}
|
||||
|
||||
if (prefix && base == 010) *ptr++ = '0';
|
||||
else if (prefix && base == 0x10)
|
||||
{
|
||||
*ptr++ = 'x';
|
||||
*ptr++ = '0';
|
||||
}
|
||||
|
||||
if (tmpVal < 0) *ptr++ = '-';
|
||||
|
||||
if ('0' != fill)
|
||||
{
|
||||
while ((ptr - result) < width) *ptr++ = fill;
|
||||
}
|
||||
|
||||
size = ptr - result;
|
||||
poco_assert_dbg (size <= ptr.span());
|
||||
poco_assert_dbg ((-1 == width) || (size >= width));
|
||||
*ptr-- = '\0';
|
||||
|
||||
char* ptrr = result;
|
||||
char tmp;
|
||||
while(ptrr < ptr)
|
||||
{
|
||||
tmp = *ptr;
|
||||
*ptr-- = *ptrr;
|
||||
*ptrr++ = tmp;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool intToStr (T number, unsigned short base, std::string& result, bool prefix = false, int width = -1, char fill = ' ', char thSep = 0)
|
||||
/// Converts integer to string; This is a wrapper function, for details see see the
|
||||
/// bool intToStr(T, unsigned short, char*, int, int, char, char) implementation.
|
||||
{
|
||||
char res[POCO_MAX_NUM_STRING_LEN] = {0};
|
||||
unsigned size = POCO_MAX_NUM_STRING_LEN;
|
||||
bool ret = intToStr(number, base, res, size, prefix, width, fill, thSep);
|
||||
result.assign(res, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user