mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Github pullreq 556: long long ints
This commit is contained in:
83
cJSON.c
83
cJSON.c
@@ -69,6 +69,21 @@
|
|||||||
#endif
|
#endif
|
||||||
#define false ((cJSON_bool)0)
|
#define false ((cJSON_bool)0)
|
||||||
|
|
||||||
|
/* define our own int max and min */
|
||||||
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||||
|
#define CJSON_INT_MAX LLONG_MAX
|
||||||
|
#define CJSON_INT_MIN LLONG_MIN
|
||||||
|
#define strtoint(s) strtoll((const char*)(s), NULL, 0)
|
||||||
|
#define intfmt "%lld"
|
||||||
|
#else
|
||||||
|
#define CJSON_INT_MAX INT_MAX
|
||||||
|
#define CJSON_INT_MIN INT_MIN
|
||||||
|
#define strtoint(s) atoi((const char*)(s))
|
||||||
|
#define intfmt "%d"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define isint(d) (d == floor(d))
|
||||||
|
|
||||||
/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */
|
/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */
|
||||||
#ifndef isinf
|
#ifndef isinf
|
||||||
#define isinf(d) (isnan((d - d)) && !isnan(d))
|
#define isinf(d) (isnan((d - d)) && !isnan(d))
|
||||||
@@ -305,6 +320,7 @@ typedef struct
|
|||||||
static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
|
static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
|
||||||
{
|
{
|
||||||
double number = 0;
|
double number = 0;
|
||||||
|
cJSON_bool integer = cJSON_True;
|
||||||
unsigned char *after_end = NULL;
|
unsigned char *after_end = NULL;
|
||||||
unsigned char number_c_string[64];
|
unsigned char number_c_string[64];
|
||||||
unsigned char decimal_point = get_decimal_point();
|
unsigned char decimal_point = get_decimal_point();
|
||||||
@@ -334,12 +350,17 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu
|
|||||||
case '9':
|
case '9':
|
||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
|
number_c_string[i] = buffer_at_offset(input_buffer)[i];
|
||||||
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E':
|
case 'E':
|
||||||
|
integer = cJSON_False;
|
||||||
number_c_string[i] = buffer_at_offset(input_buffer)[i];
|
number_c_string[i] = buffer_at_offset(input_buffer)[i];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
|
integer = cJSON_False;
|
||||||
number_c_string[i] = decimal_point;
|
number_c_string[i] = decimal_point;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -359,17 +380,22 @@ loop_end:
|
|||||||
item->valuedouble = number;
|
item->valuedouble = number;
|
||||||
|
|
||||||
/* use saturation in case of overflow */
|
/* use saturation in case of overflow */
|
||||||
if (number >= INT_MAX)
|
if (number >= CJSON_INT_MAX)
|
||||||
{
|
{
|
||||||
item->valueint = INT_MAX;
|
item->valueint = CJSON_INT_MAX;
|
||||||
}
|
}
|
||||||
else if (number <= (double)INT_MIN)
|
else if (number <= (double)CJSON_INT_MIN)
|
||||||
{
|
{
|
||||||
item->valueint = INT_MIN;
|
item->valueint = CJSON_INT_MIN;
|
||||||
|
}
|
||||||
|
else if (integer == cJSON_True)
|
||||||
|
{
|
||||||
|
/* parse again to handle the very big integer */
|
||||||
|
item->valueint = strtoint(number_c_string);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->valueint = (int)number;
|
item->valueint = (cJSON_int)number;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->type = cJSON_Number;
|
item->type = cJSON_Number;
|
||||||
@@ -381,13 +407,13 @@ loop_end:
|
|||||||
/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
|
/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
|
||||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
||||||
{
|
{
|
||||||
if (number >= INT_MAX)
|
if (number >= CJSON_INT_MAX)
|
||||||
{
|
{
|
||||||
object->valueint = INT_MAX;
|
object->valueint = CJSON_INT_MAX;
|
||||||
}
|
}
|
||||||
else if (number <= (double)INT_MIN)
|
else if (number <= (double)CJSON_INT_MIN)
|
||||||
{
|
{
|
||||||
object->valueint = INT_MIN;
|
object->valueint = CJSON_INT_MIN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -562,10 +588,11 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
|||||||
{
|
{
|
||||||
length = sprintf((char*)number_buffer, "null");
|
length = sprintf((char*)number_buffer, "null");
|
||||||
}
|
}
|
||||||
else if(d == (double)item->valueint)
|
else if (isint(d) && ((item->valueint != CJSON_INT_MAX &&
|
||||||
{
|
item->valueint != CJSON_INT_MIN) || d == (double)item->valueint))
|
||||||
length = sprintf((char*)number_buffer, "%d", item->valueint);
|
{
|
||||||
}
|
length = sprintf((char*)number_buffer, intfmt, item->valueint);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
||||||
@@ -2426,27 +2453,25 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateInt(cJSON_int num)
|
||||||
|
{
|
||||||
|
cJSON *item = cJSON_New_Item(&global_hooks);
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
item->type = cJSON_Number;
|
||||||
|
cJSON_SetIntValue(item, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
|
||||||
{
|
{
|
||||||
cJSON *item = cJSON_New_Item(&global_hooks);
|
cJSON *item = cJSON_New_Item(&global_hooks);
|
||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
item->type = cJSON_Number;
|
item->type = cJSON_Number;
|
||||||
item->valuedouble = num;
|
cJSON_SetNumberValue(item, num);
|
||||||
|
|
||||||
/* use saturation in case of overflow */
|
|
||||||
if (num >= INT_MAX)
|
|
||||||
{
|
|
||||||
item->valueint = INT_MAX;
|
|
||||||
}
|
|
||||||
else if (num <= (double)INT_MIN)
|
|
||||||
{
|
|
||||||
item->valueint = INT_MIN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->valueint = (int)num;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
@@ -3022,7 +3047,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case cJSON_Number:
|
case cJSON_Number:
|
||||||
if (compare_double(a->valuedouble, b->valuedouble))
|
if ((a->valueint == b->valueint) && compare_double(a->valuedouble, b->valuedouble))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
11
cJSON.h
11
cJSON.h
@@ -99,6 +99,12 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
|
|||||||
#define cJSON_IsReference 256
|
#define cJSON_IsReference 256
|
||||||
#define cJSON_StringIsConst 512
|
#define cJSON_StringIsConst 512
|
||||||
|
|
||||||
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||||
|
typedef long long cJSON_int;
|
||||||
|
#else
|
||||||
|
typedef int cJSON_int;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The cJSON structure: */
|
/* The cJSON structure: */
|
||||||
typedef struct cJSON
|
typedef struct cJSON
|
||||||
{
|
{
|
||||||
@@ -114,7 +120,7 @@ typedef struct cJSON
|
|||||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||||
char *valuestring;
|
char *valuestring;
|
||||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||||
int valueint;
|
cJSON_int valueint;
|
||||||
/* The item's number, if type==cJSON_Number */
|
/* The item's number, if type==cJSON_Number */
|
||||||
double valuedouble;
|
double valuedouble;
|
||||||
|
|
||||||
@@ -196,6 +202,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
|||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateInt(cJSON_int num);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||||
/* raw json */
|
/* raw json */
|
||||||
@@ -272,7 +279,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char *
|
|||||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||||
|
|
||||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
/* 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))
|
#define cJSON_SetIntValue(object, number) ((object) ? ((object)->valuedouble = (number), (object)->valueint = (number)) : (number))
|
||||||
/* helper for the cJSON_SetNumberValue macro */
|
/* helper for the cJSON_SetNumberValue macro */
|
||||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||||
|
|||||||
Reference in New Issue
Block a user