mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
feat: add int64 support
This commit adds int64 support for cjson. To enable int64, you need to define the macro ENABLE_INT64. To make it more clear, you need to build cjson like this: mkdir build cd build cmake -DENABLE_INT64=ON .. make This implementation changed the type of valueint in struct cJSON: from int to long long(int64), and added a new flag cJSON_IsInt64. For a int64 cJSON item, the value of item->type would be cJSON_Number | cJSON_IsInt64. The existing functions parse_number and print_number can handle int64 now. Considering I have added a new type cJSON_IsInt64, some new functions have been added: CJSON_PUBLIC(long long *) cJSON_GetInt64NumberValue(cJSON * const item) CJSON_PUBLIC(cJSON_bool) cJSON_IsInt64Number(const cJSON * const item) CJSON_PUBLIC(cJSON *) cJSON_CreateInt64Number(long long integer) CJSON_PUBLIC(cJSON*) cJSON_AddInt64NumberToObject(cJSON * const object, const char * const name, const long long integer) CJSON_PUBLIC(long long) cJSON_SetInt64NumberValue(cJSON * const object, const long long integer) And some existing functions are also adjusted for int64, including parse_number, cJSON_SetNumberHelper, print_number, cJSON_CreateNumber, cJSON_Compare and compare_json(in cJSON_Utils). Besides the code changes, we have also added some testcases for int64. These tests will run if ENABLE_INT64 is turned on.
This commit is contained in:
parent
b45f48e600
commit
c95332c58c
@ -14,12 +14,23 @@ set(CJSON_UTILS_VERSION_SO 1)
|
||||
|
||||
set(custom_compiler_flags)
|
||||
|
||||
option(ENABLE_INT64 "Enable the use of int64(long long), please note this will use c99 instead of c89" OFF)
|
||||
if (ENABLE_INT64)
|
||||
add_definitions(-DENABLE_INT64)
|
||||
list(APPEND custom_compiler_flags
|
||||
-std=c99
|
||||
)
|
||||
else()
|
||||
list(APPEND custom_compiler_flags
|
||||
-std=c89
|
||||
)
|
||||
endif ()
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags" ON)
|
||||
if (ENABLE_CUSTOM_COMPILER_FLAGS)
|
||||
if (("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU"))
|
||||
list(APPEND custom_compiler_flags
|
||||
-std=c89
|
||||
-pedantic
|
||||
-Wall
|
||||
-Wextra
|
||||
|
@ -119,6 +119,7 @@ You can change the build process with a list of different options that you can p
|
||||
* `-DENABLE_LOCALES=On`: Enable the usage of localeconv method. ( on by default )
|
||||
* `-DCJSON_OVERRIDE_BUILD_SHARED_LIBS=On`: Enable overriding the value of `BUILD_SHARED_LIBS` with `-DCJSON_BUILD_SHARED_LIBS`.
|
||||
* `-DENABLE_CJSON_VERSION_SO`: Enable cJSON so version. ( on by default )
|
||||
* `-DENABLE_INT64`: Enable int64 support for cjson. Please note this will use c99 instead of c89. ( off by default )
|
||||
|
||||
If you are packaging cJSON for a distribution of Linux, you would probably take these steps for example:
|
||||
```
|
||||
|
323
cJSON.c
323
cJSON.c
@ -106,6 +106,18 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
|
||||
return item->valuestring;
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(long long *) cJSON_GetInt64NumberValue(cJSON * const item)
|
||||
{
|
||||
if (!cJSON_IsInt64Number(item))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &(item->valueint);
|
||||
}
|
||||
#endif
|
||||
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
|
||||
{
|
||||
if (!cJSON_IsNumber(item))
|
||||
@ -301,6 +313,106 @@ typedef struct
|
||||
/* get a pointer to the buffer at the position */
|
||||
#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
/* 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;
|
||||
long long integer = 0;
|
||||
unsigned char *after_end = NULL;
|
||||
unsigned char number_c_string[64];
|
||||
unsigned char decimal_point = get_decimal_point();
|
||||
size_t i = 0;
|
||||
cJSON_bool is_integer = true;
|
||||
|
||||
if ((input_buffer == NULL) || (input_buffer->content == NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* copy the number into a temporary buffer and replace '.' with the decimal point
|
||||
* of the current locale (for strtod)
|
||||
* This also takes care of '\0' not necessarily being available for marking the end of the input */
|
||||
for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
|
||||
{
|
||||
switch (buffer_at_offset(input_buffer)[i])
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '+':
|
||||
case '-':
|
||||
number_c_string[i] = buffer_at_offset(input_buffer)[i];
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
number_c_string[i] = buffer_at_offset(input_buffer)[i];
|
||||
is_integer = false;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
number_c_string[i] = decimal_point;
|
||||
is_integer = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto loop_end;
|
||||
}
|
||||
}
|
||||
loop_end:
|
||||
number_c_string[i] = '\0';
|
||||
|
||||
/* use guard clause to process the int64 case first */
|
||||
if (is_integer)
|
||||
{
|
||||
/* for int64 values, set cJSON_IsInt64 */
|
||||
item->type = cJSON_Number | cJSON_IsInt64;
|
||||
integer = strtoll((const char*)number_c_string, (char**)&after_end, 10);
|
||||
if (number_c_string == after_end)
|
||||
{
|
||||
return false; /* parse_error */
|
||||
}
|
||||
item->valueint = integer;
|
||||
item->valuedouble = (double)integer;
|
||||
goto parse_end;
|
||||
}
|
||||
|
||||
number = strtod((const char*)number_c_string, (char**)&after_end);
|
||||
if (number_c_string == after_end)
|
||||
{
|
||||
return false; /* parse_error */
|
||||
}
|
||||
|
||||
item->valuedouble = number;
|
||||
|
||||
/* use saturation in case of overflow */
|
||||
if (number >= (double)LLONG_MAX)
|
||||
{
|
||||
item->valueint = LLONG_MAX;
|
||||
}
|
||||
else if (number <= (double)LLONG_MIN)
|
||||
{
|
||||
item->valueint = LLONG_MIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->valueint = (long long)number;
|
||||
}
|
||||
|
||||
item->type = cJSON_Number;
|
||||
|
||||
parse_end:
|
||||
input_buffer->offset += (size_t)(after_end - number_c_string);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
/* 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)
|
||||
{
|
||||
@ -377,7 +489,49 @@ loop_end:
|
||||
input_buffer->offset += (size_t)(after_end - number_c_string);
|
||||
return true;
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(long long) cJSON_SetInt64NumberValue(cJSON * const object, const long long integer)
|
||||
{
|
||||
if (object == NULL)
|
||||
{
|
||||
return integer;
|
||||
}
|
||||
|
||||
/* check the type before setting values */
|
||||
if (!(object->type & cJSON_Number) || !(object->type & cJSON_IsInt64))
|
||||
{
|
||||
return integer;
|
||||
}
|
||||
|
||||
object->valueint = integer;
|
||||
object->valuedouble = (double)integer;
|
||||
|
||||
return integer;
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
/* note that double max(DBL_MAX) is greater than long long max(LLONG_MAX) */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
||||
{
|
||||
if (number >= (double)LLONG_MAX)
|
||||
{
|
||||
object->valueint = LLONG_MAX;
|
||||
}
|
||||
else if (number <= (double)LLONG_MIN)
|
||||
{
|
||||
object->valueint = LLONG_MIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
object->valueint = (long long)number;
|
||||
}
|
||||
|
||||
return object->valuedouble = number;
|
||||
}
|
||||
#else
|
||||
/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
||||
{
|
||||
@ -396,6 +550,7 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
||||
|
||||
return object->valuedouble = number;
|
||||
}
|
||||
#endif /* #ifdef __CJSON_USE_INT64 */
|
||||
|
||||
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
||||
{
|
||||
@ -541,6 +696,82 @@ static cJSON_bool compare_double(double a, double b)
|
||||
return (fabs(a - b) <= maxVal * DBL_EPSILON);
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
|
||||
{
|
||||
unsigned char *output_pointer = NULL;
|
||||
double d = item->valuedouble;
|
||||
long long integer = item->valueint;
|
||||
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;
|
||||
|
||||
if (output_buffer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item->type & cJSON_IsInt64)
|
||||
{
|
||||
/* use lld to print the long long integer */
|
||||
length = sprintf((char*)number_buffer, "%lld", integer);
|
||||
}
|
||||
else /* item->type == cJSON_NUMBER */
|
||||
{
|
||||
/* This checks for NaN and Infinity */
|
||||
if (isnan(d) || isinf(d))
|
||||
{
|
||||
length = sprintf((char*)number_buffer, "null");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
/* If not, print with 17 decimal places of precision */
|
||||
length = sprintf((char*)number_buffer, "%1.17g", d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* sprintf failed or buffer overrun occurred */
|
||||
if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* reserve appropriate space in the output */
|
||||
output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
|
||||
if (output_pointer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* copy the printed number to the output and replace locale
|
||||
* dependent decimal point with '.' */
|
||||
for (i = 0; i < ((size_t)length); i++)
|
||||
{
|
||||
if (number_buffer[i] == decimal_point)
|
||||
{
|
||||
output_pointer[i] = '.';
|
||||
continue;
|
||||
}
|
||||
|
||||
output_pointer[i] = number_buffer[i];
|
||||
}
|
||||
output_pointer[i] = '\0';
|
||||
|
||||
output_buffer->offset += (size_t)length;
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
|
||||
{
|
||||
@ -610,6 +841,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
/* parse 4 digit hexadecimal number */
|
||||
static unsigned parse_hex4(const unsigned char * const input)
|
||||
@ -2124,6 +2356,20 @@ CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * co
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddInt64NumberToObject(cJSON * const object, const char * const name, const long long integer)
|
||||
{
|
||||
cJSON *int_item = cJSON_CreateInt64Number(integer);
|
||||
if (add_item_to_object(object, name, int_item, &global_hooks, false))
|
||||
{
|
||||
return int_item;
|
||||
}
|
||||
|
||||
cJSON_Delete(int_item);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
|
||||
{
|
||||
cJSON *number_item = cJSON_CreateNumber(number);
|
||||
@ -2426,6 +2672,48 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
|
||||
return item;
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateInt64Number(long long integer)
|
||||
{
|
||||
cJSON *item = cJSON_New_Item(&global_hooks);
|
||||
if(item)
|
||||
{
|
||||
item->type = cJSON_Number | cJSON_IsInt64;
|
||||
item->valueint = integer;
|
||||
item->valuedouble = (double)integer;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
|
||||
{
|
||||
cJSON *item = cJSON_New_Item(&global_hooks);
|
||||
if(item)
|
||||
{
|
||||
item->type = cJSON_Number;
|
||||
item->valuedouble = num;
|
||||
|
||||
/* use saturation in case of overflow */
|
||||
if (num >= (double)LLONG_MAX)
|
||||
{
|
||||
item->valueint = LLONG_MAX;
|
||||
}
|
||||
else if (num <= (double)LLONG_MIN)
|
||||
{
|
||||
item->valueint = LLONG_MIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->valueint = (long long)num;
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
#else
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
|
||||
{
|
||||
cJSON *item = cJSON_New_Item(&global_hooks);
|
||||
@ -2451,6 +2739,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
|
||||
|
||||
return item;
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
|
||||
{
|
||||
@ -2933,6 +3222,18 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
|
||||
return (item->type & 0xFF) == cJSON_NULL;
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInt64Number(const cJSON * const item)
|
||||
{
|
||||
if (item == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return cJSON_IsNumber(item) && (item->type & cJSON_IsInt64);
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
|
||||
{
|
||||
if (item == NULL)
|
||||
@ -3021,12 +3322,34 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
|
||||
case cJSON_NULL:
|
||||
return true;
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
case cJSON_Number:
|
||||
if (!compare_double(a->valuedouble, b->valuedouble))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a->type & cJSON_IsInt64) != (b->type & cJSON_IsInt64))
|
||||
{
|
||||
/* cJSON_IsInt64 should also be considered */
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a->type & cJSON_IsInt64) && (b->type & cJSON_IsInt64))
|
||||
{
|
||||
/* compare valueint if both values are int64 */
|
||||
return a->valueint == b->valueint;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
case cJSON_Number:
|
||||
if (compare_double(a->valuedouble, b->valuedouble))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
case cJSON_String:
|
||||
case cJSON_Raw:
|
||||
|
28
cJSON.h
28
cJSON.h
@ -85,6 +85,11 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* use int64 if it is enabled and supported */
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && defined(ENABLE_INT64)
|
||||
#define __CJSON_USE_INT64
|
||||
#endif
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
@ -98,6 +103,9 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
#ifdef __CJSON_USE_INT64
|
||||
#define cJSON_IsInt64 1024
|
||||
#endif
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
@ -113,8 +121,13 @@ typedef struct cJSON
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
#ifdef __CJSON_USE_INT64
|
||||
/* use long long if int64 is enabled */
|
||||
long long valueint;
|
||||
#else
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
@ -177,6 +190,9 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check item type and return its value */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(long long *) cJSON_GetInt64NumberValue(cJSON * const item);
|
||||
#endif
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
@ -185,6 +201,9 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInt64Number(const cJSON * const item);
|
||||
#endif
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
@ -197,6 +216,9 @@ 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);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateInt64Number(long long integer);
|
||||
#endif
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
@ -265,12 +287,18 @@ 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);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddInt64NumberToObject(cJSON * const object, const char * const name, const long long integer);
|
||||
#endif
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double 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);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
CJSON_PUBLIC(long long) cJSON_SetInt64NumberValue(cJSON * const object, const long long integer);
|
||||
#endif
|
||||
/* 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 */
|
||||
|
@ -610,6 +610,22 @@ static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensiti
|
||||
}
|
||||
switch (a->type & 0xFF)
|
||||
{
|
||||
#ifdef __CJSON_USE_INT64
|
||||
case cJSON_Number:
|
||||
/* numeric mismatch. */
|
||||
if ((a->valueint != b->valueint) || (!compare_double(a->valuedouble, b->valuedouble)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a->type & cJSON_IsInt64) != (b->type & cJSON_IsInt64))
|
||||
{
|
||||
/* cJSON_IsInt64 should also be considered */
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
case cJSON_Number:
|
||||
/* numeric mismatch. */
|
||||
if ((a->valueint != b->valueint) || (!compare_double(a->valuedouble, b->valuedouble)))
|
||||
@ -620,6 +636,7 @@ static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensiti
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
case cJSON_String:
|
||||
/* string mismatch. */
|
||||
|
@ -60,6 +60,12 @@ if(ENABLE_CJSON_TEST)
|
||||
minify_tests
|
||||
)
|
||||
|
||||
if (ENABLE_INT64)
|
||||
add_definitions(-DUNITY_SUPPORT_64)
|
||||
list(APPEND unity_tests
|
||||
misc_int64_tests
|
||||
)
|
||||
endif()
|
||||
option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.")
|
||||
if (ENABLE_VALGRIND)
|
||||
find_program(MEMORYCHECK_COMMAND valgrind)
|
||||
|
@ -278,6 +278,47 @@ static void cjson_add_number_should_fail_on_allocation_failure(void)
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
static void cjson_add_number_should_add_int64_number(void)
|
||||
{
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
cJSON *number = NULL;
|
||||
|
||||
cJSON_AddInt64NumberToObject(root, "number", 42LL);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(number = cJSON_GetObjectItemCaseSensitive(root, "number"));
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(number->type, cJSON_Number | cJSON_IsInt64);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(number->valuedouble, 42);
|
||||
TEST_ASSERT_EQUAL_INT64(number->valueint, 42LL);
|
||||
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
static void cjson_add_int64_number_should_fail_on_null_pointers(void)
|
||||
{
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
|
||||
TEST_ASSERT_NULL(cJSON_AddInt64NumberToObject(NULL, "number", 42LL));
|
||||
TEST_ASSERT_NULL(cJSON_AddInt64NumberToObject(root, NULL, 42LL));
|
||||
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
static void cjson_add_int64_number_should_fail_on_allocation_failure(void)
|
||||
{
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
|
||||
cJSON_InitHooks(&failing_hooks);
|
||||
|
||||
TEST_ASSERT_NULL(cJSON_AddInt64NumberToObject(root, "number", 42LL));
|
||||
|
||||
cJSON_InitHooks(NULL);
|
||||
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
static void cjson_add_string_should_add_string(void)
|
||||
{
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
@ -451,6 +492,12 @@ int CJSON_CDECL main(void)
|
||||
RUN_TEST(cjson_add_number_should_fail_with_null_pointers);
|
||||
RUN_TEST(cjson_add_number_should_fail_on_allocation_failure);
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
RUN_TEST(cjson_add_number_should_add_int64_number);
|
||||
RUN_TEST(cjson_add_int64_number_should_fail_on_null_pointers);
|
||||
RUN_TEST(cjson_add_int64_number_should_fail_on_allocation_failure);
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
RUN_TEST(cjson_add_string_should_add_string);
|
||||
RUN_TEST(cjson_add_string_should_fail_with_null_pointers);
|
||||
RUN_TEST(cjson_add_string_should_fail_on_allocation_failure);
|
||||
|
@ -72,6 +72,21 @@ static void cjson_compare_should_compare_numbers(void)
|
||||
TEST_ASSERT_FALSE(compare_from_string("1", "2", false));
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
static void cjson_compare_should_compare_int64_numbers(void)
|
||||
{
|
||||
TEST_ASSERT_TRUE(compare_from_string("1", "1", true));
|
||||
TEST_ASSERT_TRUE(compare_from_string("1", "1", false));
|
||||
TEST_ASSERT_TRUE(compare_from_string("9223372036854775807", "9223372036854775807", true));
|
||||
TEST_ASSERT_TRUE(compare_from_string("9223372036854775807", "9223372036854775807", false));
|
||||
TEST_ASSERT_TRUE(compare_from_string("-9223372036854775808", "-9223372036854775808", true));
|
||||
TEST_ASSERT_TRUE(compare_from_string("-9223372036854775808", "-9223372036854775808", false));
|
||||
|
||||
TEST_ASSERT_FALSE(compare_from_string("1", "2", true));
|
||||
TEST_ASSERT_FALSE(compare_from_string("1", "2", false));
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
static void cjson_compare_should_compare_booleans(void)
|
||||
{
|
||||
/* true */
|
||||
@ -196,6 +211,9 @@ int CJSON_CDECL main(void)
|
||||
RUN_TEST(cjson_compare_should_compare_null_pointer_as_not_equal);
|
||||
RUN_TEST(cjson_compare_should_compare_invalid_as_not_equal);
|
||||
RUN_TEST(cjson_compare_should_compare_numbers);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
RUN_TEST(cjson_compare_should_compare_int64_numbers);
|
||||
#endif
|
||||
RUN_TEST(cjson_compare_should_compare_booleans);
|
||||
RUN_TEST(cjson_compare_should_compare_null);
|
||||
RUN_TEST(cjson_compare_should_not_accept_invalid_types);
|
||||
|
185
tests/misc_int64_tests.c
Normal file
185
tests/misc_int64_tests.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "unity/examples/unity_config.h"
|
||||
#include "unity/src/unity.h"
|
||||
#include "common.h"
|
||||
|
||||
static void assert_is_int64(cJSON *int64_number_item)
|
||||
{
|
||||
assert_has_type(int64_number_item, cJSON_Number);
|
||||
TEST_ASSERT_BITS_MESSAGE(cJSON_IsInt64, cJSON_IsInt64, int64_number_item->type, "Item should be a int64 integer.");
|
||||
}
|
||||
|
||||
static void cjson_get_object_item_should_get_object_items_with_int64(void)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
cJSON *found = NULL;
|
||||
|
||||
item = cJSON_Parse("{\"one\":1, \"Two\":2, \"tHree\":3}");
|
||||
|
||||
found = cJSON_GetObjectItem(NULL, "test");
|
||||
TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL pointer.");
|
||||
|
||||
found = cJSON_GetObjectItem(item, NULL);
|
||||
TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL string.");
|
||||
|
||||
found = cJSON_GetObjectItem(item, "one");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
|
||||
TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 1);
|
||||
assert_is_int64(found);
|
||||
|
||||
found = cJSON_GetObjectItem(item, "tWo");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
|
||||
TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 2);
|
||||
assert_is_int64(found);
|
||||
|
||||
found = cJSON_GetObjectItem(item, "three");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find item.");
|
||||
TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 3);
|
||||
assert_is_int64(found);
|
||||
|
||||
found = cJSON_GetObjectItem(item, "four");
|
||||
TEST_ASSERT_NULL_MESSAGE(found, "Should not find something that isn't there.");
|
||||
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
|
||||
static void cjson_get_object_item_case_sensitive_should_get_object_items_with_int64(void)
|
||||
{
|
||||
cJSON *item = NULL;
|
||||
cJSON *found = NULL;
|
||||
|
||||
item = cJSON_Parse("{\"one\":1, \"Two\":2, \"tHree\":3}");
|
||||
|
||||
found = cJSON_GetObjectItemCaseSensitive(NULL, "test");
|
||||
TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL pointer.");
|
||||
|
||||
found = cJSON_GetObjectItemCaseSensitive(item, NULL);
|
||||
TEST_ASSERT_NULL_MESSAGE(found, "Failed to fail on NULL string.");
|
||||
|
||||
found = cJSON_GetObjectItemCaseSensitive(item, "one");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
|
||||
TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 1);
|
||||
assert_is_int64(found);
|
||||
|
||||
found = cJSON_GetObjectItemCaseSensitive(item, "Two");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find first item.");
|
||||
TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 2);
|
||||
assert_is_int64(found);
|
||||
|
||||
found = cJSON_GetObjectItemCaseSensitive(item, "tHree");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(found, "Failed to find item.");
|
||||
TEST_ASSERT_EQUAL_DOUBLE(found->valuedouble, 3);
|
||||
assert_is_int64(found);
|
||||
|
||||
found = cJSON_GetObjectItemCaseSensitive(item, "One");
|
||||
TEST_ASSERT_NULL_MESSAGE(found, "Should not find something that isn't there.");
|
||||
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
|
||||
static void cjson_set_number_value_should_set_numbers_with_int64(void)
|
||||
{
|
||||
cJSON number[1] = {{NULL, NULL, NULL, cJSON_Number | cJSON_IsInt64, NULL, 0, 0, NULL}};
|
||||
|
||||
cJSON_SetInt64NumberValue(number, 1LL);
|
||||
TEST_ASSERT_EQUAL_INT64(1LL, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(1.0, number->valuedouble);
|
||||
|
||||
cJSON_SetInt64NumberValue(number, -1LL);
|
||||
TEST_ASSERT_EQUAL_INT64(-1LL, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(-1.0, number->valuedouble);
|
||||
|
||||
cJSON_SetInt64NumberValue(number, 0LL);
|
||||
TEST_ASSERT_EQUAL_INT64(0LL, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(0.0, number->valuedouble);
|
||||
|
||||
cJSON_SetInt64NumberValue(number, LLONG_MAX);
|
||||
TEST_ASSERT_EQUAL_INT64(LLONG_MAX, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE((double)LLONG_MAX, number->valuedouble);
|
||||
|
||||
cJSON_SetInt64NumberValue(number, LLONG_MIN);
|
||||
TEST_ASSERT_EQUAL_INT64(LLONG_MIN, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE((double)LLONG_MIN, number->valuedouble);
|
||||
}
|
||||
|
||||
static void typecheck_functions_should_check_type_with_int64(void)
|
||||
{
|
||||
cJSON item[1];
|
||||
item->type = cJSON_Number;
|
||||
TEST_ASSERT_FALSE(cJSON_IsInt64Number(item));
|
||||
|
||||
item->type = cJSON_IsInt64;
|
||||
TEST_ASSERT_FALSE(cJSON_IsInt64Number(item));
|
||||
|
||||
item->type = cJSON_Number | cJSON_IsInt64;
|
||||
TEST_ASSERT_TRUE(cJSON_IsInt64Number(item));
|
||||
|
||||
item->type = cJSON_False;
|
||||
TEST_ASSERT_FALSE(cJSON_IsInt64Number(item));
|
||||
}
|
||||
|
||||
static void cjson_functions_should_not_crash_with_null_pointers_with_int64(void)
|
||||
{
|
||||
cJSON *item = cJSON_CreateString("item");
|
||||
|
||||
TEST_ASSERT_FALSE(cJSON_IsInt64Number(NULL));
|
||||
cJSON_AddInt64NumberToObject(NULL, "item", 0LL);
|
||||
cJSON_AddInt64NumberToObject(item, NULL, 0LL);
|
||||
cJSON_AddInt64NumberToObject(NULL, NULL, 0LL);
|
||||
TEST_ASSERT_NULL(cJSON_GetInt64NumberValue(NULL));
|
||||
TEST_ASSERT_EQUAL_INT64(0LL, cJSON_SetInt64NumberValue(NULL, 0LL));
|
||||
|
||||
cJSON_Delete(item);
|
||||
}
|
||||
|
||||
static void cjson_get_number_value_should_get_a_number_with_int64(void)
|
||||
{
|
||||
cJSON *string = cJSON_CreateString("test");
|
||||
cJSON *number = cJSON_CreateInt64Number(1LL);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT64(*cJSON_GetInt64NumberValue(number), number->valueint);
|
||||
TEST_ASSERT_NULL(cJSON_GetInt64NumberValue(string));
|
||||
TEST_ASSERT_NULL(cJSON_GetInt64NumberValue(NULL));
|
||||
|
||||
cJSON_Delete(number);
|
||||
cJSON_Delete(string);
|
||||
}
|
||||
|
||||
int CJSON_CDECL main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
|
||||
RUN_TEST(cjson_get_object_item_should_get_object_items_with_int64);
|
||||
RUN_TEST(cjson_get_object_item_case_sensitive_should_get_object_items_with_int64);
|
||||
RUN_TEST(cjson_set_number_value_should_set_numbers_with_int64);
|
||||
RUN_TEST(typecheck_functions_should_check_type_with_int64);
|
||||
RUN_TEST(cjson_functions_should_not_crash_with_null_pointers_with_int64);
|
||||
RUN_TEST(cjson_get_number_value_should_get_a_number_with_int64);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
@ -231,6 +231,15 @@ static void cjson_set_number_value_should_set_numbers(void)
|
||||
TEST_ASSERT_EQUAL(-1, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(-1.5, number->valuedouble);
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
cJSON_SetNumberValue(number, 1 + (double)LLONG_MAX);
|
||||
TEST_ASSERT_EQUAL(LLONG_MAX, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(1 + (double)LLONG_MAX, number->valuedouble);
|
||||
|
||||
cJSON_SetNumberValue(number, -1 + (double)LLONG_MIN);
|
||||
TEST_ASSERT_EQUAL(LLONG_MIN, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(-1 + (double)LLONG_MIN, number->valuedouble);
|
||||
#else
|
||||
cJSON_SetNumberValue(number, 1 + (double)INT_MAX);
|
||||
TEST_ASSERT_EQUAL(INT_MAX, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(1 + (double)INT_MAX, number->valuedouble);
|
||||
@ -238,6 +247,7 @@ static void cjson_set_number_value_should_set_numbers(void)
|
||||
cJSON_SetNumberValue(number, -1 + (double)INT_MIN);
|
||||
TEST_ASSERT_EQUAL(INT_MIN, number->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(-1 + (double)INT_MIN, number->valuedouble);
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
}
|
||||
|
||||
static void cjson_detach_item_via_pointer_should_detach_items(void)
|
||||
|
@ -55,6 +55,31 @@ static void assert_parse_number(const char *string, int integer, double real)
|
||||
TEST_ASSERT_EQUAL_DOUBLE(real, item->valuedouble);
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
static void assert_is_int64(cJSON *int64_number_item)
|
||||
{
|
||||
assert_is_number(int64_number_item);
|
||||
TEST_ASSERT_BITS_MESSAGE(cJSON_IsInt64, cJSON_IsInt64, int64_number_item->type, "Item should be a int64 integer");
|
||||
}
|
||||
|
||||
static void assert_parse_int64_number(const char *string, long long integer, double real)
|
||||
{
|
||||
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
|
||||
buffer.content = (const unsigned char*)string;
|
||||
buffer.length = strlen(string) + sizeof("");
|
||||
|
||||
TEST_ASSERT_TRUE(parse_number(item, &buffer));
|
||||
TEST_ASSERT_EQUAL_INT64(integer, item->valueint);
|
||||
TEST_ASSERT_EQUAL_DOUBLE(real, item->valuedouble);
|
||||
}
|
||||
|
||||
static void assert_parse_int64_number_with_type(const char *string, long long integer, double real)
|
||||
{
|
||||
assert_parse_int64_number(string, integer, real);
|
||||
assert_is_int64(item);
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
static void parse_number_should_parse_zero(void)
|
||||
{
|
||||
assert_parse_number("0", 0, 0);
|
||||
@ -81,8 +106,13 @@ static void parse_number_should_parse_positive_reals(void)
|
||||
assert_parse_number("0.001", 0, 0.001);
|
||||
assert_parse_number("10e-10", 0, 10e-10);
|
||||
assert_parse_number("10E-10", 0, 10e-10);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
assert_parse_int64_number("10e10", 100000000000LL, 10e10);
|
||||
assert_parse_int64_number("123e+127", LLONG_MAX, 123e127);
|
||||
#else
|
||||
assert_parse_number("10e10", INT_MAX, 10e10);
|
||||
assert_parse_number("123e+127", INT_MAX, 123e127);
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
assert_parse_number("123e-128", 0, 123e-128);
|
||||
}
|
||||
|
||||
@ -91,11 +121,30 @@ static void parse_number_should_parse_negative_reals(void)
|
||||
assert_parse_number("-0.001", 0, -0.001);
|
||||
assert_parse_number("-10e-10", 0, -10e-10);
|
||||
assert_parse_number("-10E-10", 0, -10e-10);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
assert_parse_int64_number("-10e20", LLONG_MIN, -10e20);
|
||||
assert_parse_int64_number("-123e+127", LLONG_MIN, -123e127);
|
||||
#else
|
||||
assert_parse_number("-10e20", INT_MIN, -10e20);
|
||||
assert_parse_number("-123e+127", INT_MIN, -123e127);
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
assert_parse_number("-123e-128", 0, -123e-128);
|
||||
}
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
static void parse_number_should_parse_int64_numbers(void)
|
||||
{
|
||||
assert_parse_int64_number_with_type("0", 0LL, 0);
|
||||
assert_parse_int64_number_with_type("-1", -1LL, -1);
|
||||
assert_parse_int64_number_with_type("-32768", -32768LL, -32768.0);
|
||||
assert_parse_int64_number_with_type("-2147483648", -2147483648LL, -2147483648.0);
|
||||
assert_parse_int64_number_with_type("2147483648", (long long)INT_MAX + 1, 2147483648.0);
|
||||
assert_parse_int64_number_with_type("-2147483649", -2147483649LL, -2147483649.0);
|
||||
assert_parse_int64_number_with_type("9223372036854775807", LLONG_MAX, 9223372036854775807.0);
|
||||
assert_parse_int64_number_with_type("-9223372036854775808", LLONG_MIN, -9223372036854775808.0);
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
int CJSON_CDECL main(void)
|
||||
{
|
||||
/* initialize cJSON item */
|
||||
@ -106,5 +155,8 @@ int CJSON_CDECL main(void)
|
||||
RUN_TEST(parse_number_should_parse_positive_integers);
|
||||
RUN_TEST(parse_number_should_parse_positive_reals);
|
||||
RUN_TEST(parse_number_should_parse_negative_reals);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
RUN_TEST(parse_number_should_parse_int64_numbers);
|
||||
#endif
|
||||
return UNITY_END();
|
||||
}
|
||||
|
@ -24,6 +24,25 @@
|
||||
#include "unity/src/unity.h"
|
||||
#include "common.h"
|
||||
|
||||
#ifdef __CJSON_USE_INT64
|
||||
static void assert_print_int64_number(const char *expected, long long input)
|
||||
{
|
||||
unsigned char printed[1024];
|
||||
cJSON item[1] = {{ NULL, NULL, NULL, cJSON_Number | cJSON_IsInt64, NULL, 0, 0, NULL }};
|
||||
printbuffer buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
|
||||
buffer.buffer = printed;
|
||||
buffer.length = sizeof(printed);
|
||||
buffer.offset = 0;
|
||||
buffer.noalloc = true;
|
||||
buffer.hooks = global_hooks;
|
||||
|
||||
cJSON_SetInt64NumberValue(item, input);
|
||||
TEST_ASSERT_TRUE_MESSAGE(print_number(item, &buffer), "Failed to print int64 number.");
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, buffer.buffer, "Printed int64 number is not as expected.");
|
||||
}
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
|
||||
static void assert_print_number(const char *expected, double input)
|
||||
{
|
||||
unsigned char printed[1024];
|
||||
@ -72,6 +91,12 @@ static void print_number_should_print_negative_integers(void)
|
||||
assert_print_number("-1", -1.0);
|
||||
assert_print_number("-32768", -32768.0);
|
||||
assert_print_number("-2147483648", -2147483648.0);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
assert_print_int64_number("-1", -1LL);
|
||||
assert_print_int64_number("-32768", -32768LL);
|
||||
assert_print_int64_number("-2147483647", -2147483647LL);
|
||||
assert_print_int64_number("-9223372036854775808", LLONG_MIN);
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
}
|
||||
|
||||
static void print_number_should_print_positive_integers(void)
|
||||
@ -79,6 +104,12 @@ static void print_number_should_print_positive_integers(void)
|
||||
assert_print_number("1", 1.0);
|
||||
assert_print_number("32767", 32767.0);
|
||||
assert_print_number("2147483647", 2147483647.0);
|
||||
#ifdef __CJSON_USE_INT64
|
||||
assert_print_int64_number("1", 1LL);
|
||||
assert_print_int64_number("32767", 32767LL);
|
||||
assert_print_int64_number("2147483647", 2147483647LL);
|
||||
assert_print_int64_number("9223372036854775807", LLONG_MAX);
|
||||
#endif /* __CJSON_USE_INT64 */
|
||||
}
|
||||
|
||||
static void print_number_should_print_positive_reals(void)
|
||||
|
Loading…
Reference in New Issue
Block a user