feat(cjson): Add function to encode json number when "sprintf" not support float

Newlib use nano mode as default. When enable nano mode, cjson use internal function to encode for float data.
Otherwise using "sprintf" to encode float data.
This commit is contained in:
Dong Heng
2018-10-11 20:17:52 +08:00
parent c4f2a58351
commit e5df03c277
3 changed files with 51 additions and 2 deletions

View File

@ -56,6 +56,10 @@
#pragma GCC visibility pop
#endif
#ifndef CJSON_SPRINTF_FLOAT
#define CJSON_SPRINTF_FLOAT 0
#endif
#include "cJSON.h"
/* define our own boolean type */
@ -480,7 +484,6 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
size_t i = 0;
unsigned char number_buffer[26]; /* temporary buffer to print the number into */
unsigned char decimal_point = get_decimal_point();
double test;
if (output_buffer == NULL)
{
@ -494,6 +497,9 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
}
else
{
#if CJSON_SPRINTF_FLOAT
double test;
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
length = sprintf((char*)number_buffer, "%1.15g", d);
@ -503,6 +509,45 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
/* If not, print with 17 decimal places of precision */
length = sprintf((char*)number_buffer, "%1.17g", d);
}
#else
long d32 = (long)d;
length = sprintf((char*)number_buffer, "%ld", d32);
if ((double)d32 != d) {
size_t precision = 14;
unsigned char *pbuf = number_buffer;
if (d < 0.0) {
d = (double)d32 - d + 0.00000000000001;
} else {
d = d - (double)d32;
}
pbuf = &number_buffer[length];
*pbuf++ = '.';
length++;
while (d > 0.0 && precision--) {
d *= 10.0;
unsigned char tmp = (unsigned char)d;
*pbuf++ = tmp + '0';
length++;
d -= (double)tmp;
}
pbuf = &number_buffer[length - 1];
while (*pbuf == '0') {
pbuf--;
length--;
}
*++pbuf = 0;
}
#endif
}
/* sprintf failed or buffer overrun occured */

View File

@ -4,3 +4,7 @@
COMPONENT_ADD_INCLUDEDIRS += cJSON
COMPONENT_SRCDIRS := cJSON
ifdef CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL
CFLAGS += -DCJSON_SPRINTF_FLOAT=1
endif

View File

@ -11,7 +11,7 @@ config NEWLIB_ENABLE
choice NEWLIB_LIBRARY_LEVEL
prompt "newlib level"
default NEWLIB_LIBRARY_LEVEL_NORMAL
default NEWLIB_LIBRARY_LEVEL_NANO
depends on NEWLIB_ENABLE
help
Choose newlib library level.