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 #pragma GCC visibility pop
#endif #endif
#ifndef CJSON_SPRINTF_FLOAT
#define CJSON_SPRINTF_FLOAT 0
#endif
#include "cJSON.h" #include "cJSON.h"
/* define our own boolean type */ /* 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; size_t i = 0;
unsigned char number_buffer[26]; /* temporary buffer to print the number into */ unsigned char number_buffer[26]; /* temporary buffer to print the number into */
unsigned char decimal_point = get_decimal_point(); unsigned char decimal_point = get_decimal_point();
double test;
if (output_buffer == NULL) if (output_buffer == NULL)
{ {
@ -494,6 +497,9 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
} }
else else
{ {
#if CJSON_SPRINTF_FLOAT
double test;
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
length = sprintf((char*)number_buffer, "%1.15g", d); 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 */ /* If not, print with 17 decimal places of precision */
length = sprintf((char*)number_buffer, "%1.17g", d); 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 */ /* sprintf failed or buffer overrun occured */

View File

@ -4,3 +4,7 @@
COMPONENT_ADD_INCLUDEDIRS += cJSON COMPONENT_ADD_INCLUDEDIRS += cJSON
COMPONENT_SRCDIRS := 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 choice NEWLIB_LIBRARY_LEVEL
prompt "newlib level" prompt "newlib level"
default NEWLIB_LIBRARY_LEVEL_NORMAL default NEWLIB_LIBRARY_LEVEL_NANO
depends on NEWLIB_ENABLE depends on NEWLIB_ENABLE
help help
Choose newlib library level. Choose newlib library level.