From e1eb037eb6ecdd72d2b0724a6f74c1d2157228a5 Mon Sep 17 00:00:00 2001 From: Mike Sharkey Date: Sat, 13 Feb 2021 00:14:53 -0500 Subject: [PATCH] opaque real_t numbers --- cJSON.c | 45 ++++++++++++++++++++++++--------------------- cJSON.h | 12 +++++++----- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/cJSON.c b/cJSON.c index dc62ff4..b82a244 100644 --- a/cJSON.c +++ b/cJSON.c @@ -38,13 +38,16 @@ #endif #if defined(_CARIBOU_RTOS_) + #include + #include + #include + #include #include #include #include #include #include - #include - #include + #define DBL_EPSILON 2.2204460492503131e-16 #else #include #include @@ -116,11 +119,11 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) return item->valuestring; } -CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +CJSON_PUBLIC(real_t) cJSON_GetNumberValue(const cJSON * const item) { if (!cJSON_IsNumber(item)) { - return (double) NAN; + return (real_t) NAN; } return item->valuedouble; @@ -314,7 +317,7 @@ typedef struct /* Parse the input text to generate a number, and populate the result into item. */ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) { - double number = 0; + real_t number = 0; unsigned char *after_end = NULL; unsigned char number_c_string[64]; unsigned char decimal_point = get_decimal_point(); @@ -373,7 +376,7 @@ loop_end: { item->valueint = INT_MAX; } - else if (number <= (double)INT_MIN) + else if (number <= (real_t)INT_MIN) { item->valueint = INT_MIN; } @@ -388,14 +391,14 @@ loop_end: return true; } -/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or real_t */ +CJSON_PUBLIC(real_t) cJSON_SetNumberHelper(cJSON *object, real_t number) { if (number >= INT_MAX) { object->valueint = INT_MAX; } - else if (number <= (double)INT_MIN) + else if (number <= (real_t)INT_MIN) { object->valueint = INT_MIN; } @@ -545,9 +548,9 @@ static void update_offset(printbuffer * const buffer) } /* securely comparison of floating-point variables */ -static cJSON_bool compare_double(double a, double b) +static cJSON_bool compare_real_t(real_t a, real_t b) { - double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); + real_t maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); return (fabs(a - b) <= maxVal * DBL_EPSILON); } @@ -555,12 +558,12 @@ static cJSON_bool compare_double(double a, double b) static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) { unsigned char *output_pointer = NULL; - double d = item->valuedouble; + real_t d = item->valuedouble; int length = 0; size_t i = 0; unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ unsigned char decimal_point = get_decimal_point(); - double test = 0.0; + real_t test = 0.0; if (output_buffer == NULL) { @@ -577,8 +580,8 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ length = sprintf((char*)number_buffer, "%1.15g", d); - /* Check whether the original double can be recovered */ - if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + /* Check whether the original real_t can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_real_t((real_t)test, d)) { /* If not, print with 17 decimal places of precision */ length = sprintf((char*)number_buffer, "%1.17g", d); @@ -2130,7 +2133,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * co return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const real_t number) { cJSON *number_item = cJSON_CreateNumber(number); if (add_item_to_object(object, name, number_item, &global_hooks, false)) @@ -2427,7 +2430,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(real_t num) { cJSON *item = cJSON_New_Item(&global_hooks); if(item) @@ -2440,7 +2443,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) { item->valueint = INT_MAX; } - else if (num <= (double)INT_MIN) + else if (num <= (real_t)INT_MIN) { item->valueint = INT_MIN; } @@ -2599,7 +2602,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) for(i = 0; a && (i < (size_t)count); i++) { - n = cJSON_CreateNumber((double)numbers[i]); + n = cJSON_CreateNumber((real_t)numbers[i]); if(!n) { cJSON_Delete(a); @@ -2623,7 +2626,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) return a; } -CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +CJSON_PUBLIC(cJSON *) cJSON_Createreal_tArray(const real_t *numbers, int count) { size_t i = 0; cJSON *n = NULL; @@ -3023,7 +3026,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons return true; case cJSON_Number: - if (compare_double(a->valuedouble, b->valuedouble)) + if (compare_real_t(a->valuedouble, b->valuedouble)) { return true; } diff --git a/cJSON.h b/cJSON.h index 4bd1e2e..214d2a3 100644 --- a/cJSON.h +++ b/cJSON.h @@ -86,8 +86,10 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ #if defined(_CARIBOU_RTOS_) #include #include + typedef float real_t; #else #include + typedef double real_t; #endif /* cJSON Types: */ @@ -121,7 +123,7 @@ typedef struct cJSON /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ int valueint; /* The item's number, if type==cJSON_Number */ - double valuedouble; + real_t valuedouble; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ char *string; @@ -201,7 +203,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); -CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(real_t num); CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); /* raw json */ CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); @@ -220,7 +222,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const real_t *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); /* Append item to the specified array/object. */ @@ -270,7 +272,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * co CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const real_t number); CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); @@ -279,7 +281,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * c /* When assigning an integer value, it needs to be propagated to valuedouble too. */ #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) /* helper for the cJSON_SetNumberValue macro */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, real_t number); #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);