1 #ifndef NUMBERTOSTRING_H
2 #define NUMBERTOSTRING_H
6 #ifdef JSON_LESS_MEMORY
7 #include "JSONMemory.h"
9 #include "JSONSharedString.h"
14 template <
unsigned int GETLENSIZE>
16 char tmp[GETLENSIZE == 16];
40 static inline bool _floatsAreEqual(
const json_number & one,
const json_number & two) json_pure;
41 static inline bool _floatsAreEqual(
const json_number & one,
const json_number & two) json_nothrow {
42 return (one > two) ? (one - two) < JSON_FLOAT_THRESHHOLD : (one - two) > -JSON_FLOAT_THRESHHOLD;
45 #ifdef JSON_LESS_MEMORY
46 #define num_str_result s.ptr
53 #ifdef JSON_LESS_MEMORY
63 long value = (long)val;
74 *runner-- = (json_char)(value % 10) + JSON_TEXT(
'0');
80 *runner = JSON_TEXT(
'-');
89 #ifdef JSON_LESS_MEMORY
99 unsigned long value = (
unsigned long)val;
101 *runner-- = (json_char)(value % 10) + JSON_TEXT(
'0');
102 }
while(value /= 10);
109 #ifdef JSON_ISO_STRICT
111 #define FLOAT_STRING "%f"
112 #define LFLOAT_STRING L"%f"
114 #define EXTRA_LONG long
115 #define FLOAT_STRING "%Lf"
116 #define LFLOAT_STRING L"%Lf"
119 static json_string _ftoa(json_number value) json_nothrow {
122 if (json_unlikely(value >= 0.0 && _floatsAreEqual(value, (json_number)((
unsigned EXTRA_LONG
long)value)))){
123 return _uitoa<unsigned EXTRA_LONG long>((
unsigned EXTRA_LONG long)value);
128 if (json_unlikely(_floatsAreEqual(value, (json_number)((
long EXTRA_LONG)value)))){
129 return _itoa<long EXTRA_LONG>((
long EXTRA_LONG)value);
132 #ifdef JSON_LESS_MEMORY
135 json_char num_str_result[64];
136 char temp_str_result[64];
142 snprintf(temp_str_result, 63, FLOAT_STRING, (EXTRA_LONG
double)value);
143 while( temp_str_result[i] !=
'\0' && i < 63)
145 num_str_result[i] = (wchar_t)temp_str_result[i];
148 num_str_result[i] =
'\0';
152 _snprintf_s(num_str_result, 63, 63, FLOAT_STRING, (EXTRA_LONG
double)value);
154 snprintf(num_str_result, 63, FLOAT_STRING, (EXTRA_LONG
double)value);
158 for(json_char * pos = &num_str_result[0]; *pos; ++pos){
159 if (json_unlikely(*pos ==
'.')){
160 for(json_char * runner = pos + 1; *runner; ++runner){
161 if (json_likely(*runner != JSON_TEXT(
'0'))){
165 *pos = JSON_TEXT(
'\0');
172 #if defined(JSON_SAFE) || defined(JSON_DEBUG)
173 static bool isNumeric(
const json_string & str) json_nothrow {
174 const json_char * p = str.c_str();
175 bool decimal =
false;
176 bool scientific =
false;
179 bool leadingzero =
false;
184 case JSON_TEXT(
'\0'):
197 case JSON_TEXT(
'\0'):
207 case JSON_TEXT(
'\0'):
247 case JSON_TEXT(
'\0'):
270 return (str.find_first_not_of(JSON_TEXT(
"0123456789ABCDEFabcdef"), 2) == json_string::npos);
278 return (str.find_first_not_of(JSON_TEXT(
"01234567"), 1) == json_string::npos);
280 case JSON_TEXT(
'\0'):
295 if (json_unlikely(decimal)){
299 if (json_unlikely(scientific)){
306 if (json_unlikely(scientific)){
312 case JSON_TEXT(
'\0'):
316 if (!isdigit(*(p + 1))){
321 if (*(p + 1) == JSON_TEXT(
'0')){
360 if (leadingzero && !decimal){
370 static json_number _atof (
const json_char * num){
371 json_number sign = (json_number)1.0;
374 if (*num==JSON_TEXT(
'-')){
381 #if defined(JSON_SAFE) || defined(JSON_DEBUG)
382 bool _leadingzeros = *num == JSON_TEXT(
'0');
383 bool _leadingdigits =
false;
385 if (*num == JSON_TEXT(
'0')){
389 else if (json_likely(*num < JSON_TEXT(
'1') || *num > JSON_TEXT(
'9'))){
390 return std::numeric_limits<json_number>::signaling_NaN();
394 JSON_ASSERT_SAFE(*num != JSON_TEXT(
'0'), JSON_TEXT(
"multiple leading zeros"),
return std::numeric_limits<json_number>::signaling_NaN(); );
397 json_number n = (json_number)0.0;
398 if (json_likely(*num >= JSON_TEXT(
'1') && *num <= JSON_TEXT(
'9'))){
399 #if defined(JSON_SAFE) || defined(JSON_DEBUG)
400 _leadingdigits =
true;
403 n = (n * 10.0) + (*num++ - JSON_TEXT(
'0'));
404 }
while (*num >= JSON_TEXT(
'0') && *num <= JSON_TEXT(
'9'));
407 (*num) == JSON_TEXT(
'.') ||
408 (*num) == JSON_TEXT(
'e') ||
409 (*num) == JSON_TEXT(
'E') ||
410 (*num) == JSON_TEXT(
'\0')
411 , JSON_TEXT(
"first digit not a number, e, period, or terminator"),
return std::numeric_limits<json_number>::signaling_NaN(); );
415 json_number scale = (json_number)0.0;
416 if (*num == JSON_TEXT(
'.')) {
417 JSON_ASSERT_SAFE(_leadingzeros || _leadingdigits, JSON_TEXT(
"period without leading anything"),
return std::numeric_limits<json_number>::signaling_NaN(); );
419 for(; *num >= JSON_TEXT(
'0') && *num <= JSON_TEXT(
'9');){
420 n = (n * 10.0) + (*num++ - JSON_TEXT(
'0'));
424 JSON_ASSERT_SAFE(!_leadingzeros || n == 0, JSON_TEXT(
"leading zero on an int"),
return std::numeric_limits<json_number>::signaling_NaN(); );
426 (*num) == JSON_TEXT(
'e') ||
427 (*num) == JSON_TEXT(
'E') ||
428 (*num) == JSON_TEXT(
'\0')
429 , JSON_TEXT(
"next char not an e or terminator"),
return std::numeric_limits<json_number>::signaling_NaN(); );
433 int subscale = 0, signsubscale = 1;
434 if (json_unlikely(*num == JSON_TEXT(
'e') || *num == JSON_TEXT(
'E'))){
443 JSON_ASSERT_SAFE(*num != JSON_TEXT(
'0'), JSON_TEXT(
"negative cant be followed by leading zero even after E"),
return std::numeric_limits<json_number>::signaling_NaN(); );
448 JSON_ASSERT_SAFE(*num != JSON_TEXT(
'\0'), JSON_TEXT(
"no exponent for scientific notation"),
return std::numeric_limits<json_number>::signaling_NaN(); );
449 while (*num >= JSON_TEXT(
'0') && *num <= JSON_TEXT(
'9')){
450 subscale=(subscale * 10) + (*num++ - JSON_TEXT(
'0'));
454 JSON_ASSERT_SAFE(*num == JSON_TEXT(
'\0'), JSON_TEXT(
"done with number, not at terminator"),
return std::numeric_limits<json_number>::signaling_NaN(); );
455 return sign * n * pow((json_number)10.0, scale + subscale * signsubscale);
Definition: NumberToString.h:49
Definition: NumberToString.h:15
Definition: JSONMemory.h:140
Definition: StringTest.h:22