Compare commits

...

6 Commits

Author SHA1 Message Date
Max Bruckner
11fd27ade7 Change version to 1.0.1 2016-11-20 01:08:54 +07:00
Max Bruckner
65ac0a1a2b cJSON_Utils tests: fix formatting 2016-11-19 17:50:01 +07:00
Max Bruckner
679004914f Define a boolean type
This is not changing the behavior of the code, but it is improving the
readability and helps to make the intention clearer.

One thing to take care: 'true' should never be compared against.
2016-11-19 17:29:22 +07:00
Max Bruckner
b88da9b0de Initialize all variables 2016-11-19 17:29:21 +07:00
Max Bruckner
a5ff796c20 Replace 0 with more expressive NULL or '\0' 2016-11-19 17:28:14 +07:00
Max Bruckner
d47339e274 cJSON_Utils: Fix comparing of cJSON_ types
When comparing the type, it has to be masked with 0xFF because of
cJSON_IsConst and cJSON_IsReference.
2016-11-18 22:52:52 +07:00
6 changed files with 400 additions and 360 deletions

View File

@@ -7,7 +7,7 @@ project(cJSON C)
set(PROJECT_VERSION_MAJOR 1)
set(PROJECT_VERSION_MINOR 0)
set(PROJECT_VERSION_PATCH 0)
set(PROJECT_VERSION_PATCH 1)
set(CJSON_VERSION_SO 1)
set(CJSON_UTILS_VERSION_SO 1)
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")

View File

@@ -7,7 +7,7 @@ UTILS_TEST = cJSON_test_utils
LDLIBS = -lm
LIBVERSION = 1.0.0
LIBVERSION = 1.0.1
CJSON_SOVERSION = 1
UTILS_SOVERSION = 1

305
cJSON.c
View File

@@ -46,7 +46,12 @@
#error "Failed to determine the size of an integer"
#endif
static const char *global_ep;
/* define our own boolean type */
typedef int bool;
#define true ((bool)1)
#define false ((bool)0)
static const char *global_ep = NULL;
const char *cJSON_GetErrorPtr(void)
{
@@ -66,7 +71,7 @@ static int cJSON_strcasecmp(const char *s1, const char *s2)
}
for(; tolower(*(const unsigned char *)s1) == tolower(*(const unsigned char *)s2); ++s1, ++s2)
{
if (*s1 == 0)
if (*s1 == '\0')
{
return 0;
}
@@ -80,13 +85,13 @@ static void (*cJSON_free)(void *ptr) = free;
static char* cJSON_strdup(const char* str)
{
size_t len;
char* copy;
size_t len = 0;
char *copy = NULL;
len = strlen(str) + 1;
if (!(copy = (char*)cJSON_malloc(len)))
{
return 0;
return NULL;
}
memcpy(copy, str, len);
@@ -113,7 +118,7 @@ static cJSON *cJSON_New_Item(void)
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node)
{
memset(node, 0, sizeof(cJSON));
memset(node, '\0', sizeof(cJSON));
}
return node;
@@ -122,7 +127,7 @@ static cJSON *cJSON_New_Item(void)
/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
cJSON *next;
cJSON *next = NULL;
while (c)
{
next = c->next;
@@ -244,11 +249,11 @@ typedef struct
/* realloc printbuffer if necessary to have at least "needed" bytes more */
static char* ensure(printbuffer *p, int needed)
{
char *newbuffer;
int newsize;
char *newbuffer = NULL;
int newsize = 0;
if (!p || !p->buffer)
{
return 0;
return NULL;
}
needed += p->offset;
if (needed <= p->length)
@@ -262,9 +267,9 @@ static char* ensure(printbuffer *p, int needed)
{
cJSON_free(p->buffer);
p->length = 0;
p->buffer = 0;
p->buffer = NULL;
return 0;
return NULL;
}
if (newbuffer)
{
@@ -280,7 +285,7 @@ static char* ensure(printbuffer *p, int needed)
/* calculate the new length of the string in a printbuffer */
static int update(const printbuffer *p)
{
char *str;
char *str = NULL;
if (!p || !p->buffer)
{
return 0;
@@ -293,7 +298,7 @@ static int update(const printbuffer *p)
/* Render the number nicely from the given item into a string. */
static char *print_number(const cJSON *item, printbuffer *p)
{
char *str = 0;
char *str = NULL;
double d = item->valuedouble;
/* special case for 0. */
if (d == 0)
@@ -468,17 +473,17 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
{
const char *ptr = str + 1;
const char *end_ptr =str + 1;
char *ptr2;
char *out;
char *ptr2 = NULL;
char *out = NULL;
int len = 0;
unsigned uc;
unsigned uc2;
unsigned uc = 0;
unsigned uc2 = 0;
/* not a string! */
if (*str != '\"')
{
*ep = str;
return 0;
return NULL;
}
while ((*end_ptr != '\"') && *end_ptr && ++len)
@@ -488,7 +493,7 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
if (*end_ptr == '\0')
{
/* prevent buffer overflow when last input character is a backslash */
return 0;
return NULL;
}
/* Skip escaped quotes. */
end_ptr++;
@@ -499,7 +504,7 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
out = (char*)cJSON_malloc(len + 1);
if (!out)
{
return 0;
return NULL;
}
item->valuestring = out; /* assign here so out will be deleted during cJSON_Delete() later */
item->type = cJSON_String;
@@ -547,13 +552,13 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
{
/* invalid */
*ep = str;
return 0;
return NULL;
}
/* check for invalid. */
if (((uc >= 0xDC00) && (uc <= 0xDFFF)) || (uc == 0))
{
*ep = str;
return 0;
return NULL;
}
/* UTF16 surrogate pairs. */
@@ -563,13 +568,13 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
{
/* invalid */
*ep = str;
return 0;
return NULL;
}
if ((ptr[1] != '\\') || (ptr[2] != 'u'))
{
/* missing second-half of surrogate. */
*ep = str;
return 0;
return NULL;
}
uc2 = parse_hex4(ptr + 3);
ptr += 6; /* \uXXXX */
@@ -577,7 +582,7 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
{
/* invalid second-half of surrogate. */
*ep = str;
return 0;
return NULL;
}
/* calculate unicode codepoint from the surrogate pair */
uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
@@ -626,7 +631,7 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
break;
default:
*ep = str;
return 0;
return NULL;
}
ptr++;
}
@@ -643,12 +648,12 @@ static const char *parse_string(cJSON *item, const char *str, const char **ep)
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str, printbuffer *p)
{
const char *ptr;
char *ptr2;
char *out;
const char *ptr = NULL;
char *ptr2 = NULL;
char *out = NULL;
int len = 0;
int flag = 0;
unsigned char token;
bool flag = false;
unsigned char token = '\0';
/* empty string */
if (!str)
@@ -663,7 +668,7 @@ static char *print_string_ptr(const char *str, printbuffer *p)
}
if (!out)
{
return 0;
return NULL;
}
strcpy(out, "\"\"");
@@ -693,7 +698,7 @@ static char *print_string_ptr(const char *str, printbuffer *p)
}
if (!out)
{
return 0;
return NULL;
}
ptr2 = out;
@@ -730,7 +735,7 @@ static char *print_string_ptr(const char *str, printbuffer *p)
}
if (!out)
{
return 0;
return NULL;
}
ptr2 = out;
@@ -793,11 +798,11 @@ static char *print_string(const cJSON *item, printbuffer *p)
/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item, const char *value, const char **ep);
static char *print_value(const cJSON *item, int depth, int fmt, printbuffer *p);
static char *print_value(const cJSON *item, int depth, bool fmt, printbuffer *p);
static const char *parse_array(cJSON *item, const char *value, const char **ep);
static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p);
static char *print_array(const cJSON *item, int depth, bool fmt, printbuffer *p);
static const char *parse_object(cJSON *item, const char *value, const char **ep);
static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p);
static char *print_object(const cJSON *item, int depth, bool fmt, printbuffer *p);
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in)
@@ -811,16 +816,16 @@ static const char *skip(const char *in)
}
/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int require_null_terminated)
cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, bool require_null_terminated)
{
const char *end = 0;
const char *end = NULL;
/* use global error pointer if no specific one was given */
const char **ep = return_parse_end ? return_parse_end : &global_ep;
cJSON *c = cJSON_New_Item();
*ep = 0;
*ep = NULL;
if (!c) /* memory fail */
{
return 0;
return NULL;
}
end = parse_value(c, skip(value), ep);
@@ -828,7 +833,7 @@ cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int
{
/* parse failure. ep is set. */
cJSON_Delete(c);
return 0;
return NULL;
}
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
@@ -839,7 +844,7 @@ cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int
{
cJSON_Delete(c);
*ep = end;
return 0;
return NULL;
}
}
if (return_parse_end)
@@ -867,13 +872,13 @@ char *cJSON_PrintUnformatted(const cJSON *item)
return print_value(item, 0, 0, 0);
}
char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, int fmt)
char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, bool fmt)
{
printbuffer p;
p.buffer = (char*)cJSON_malloc(prebuffer);
if (!p.buffer)
{
return 0;
return NULL;
}
p.length = prebuffer;
p.offset = 0;
@@ -888,7 +893,7 @@ static const char *parse_value(cJSON *item, const char *value, const char **ep)
if (!value)
{
/* Fail on null. */
return 0;
return NULL;
}
/* parse the different types of values */
@@ -927,17 +932,17 @@ static const char *parse_value(cJSON *item, const char *value, const char **ep)
/* failure. */
*ep = value;
return 0;
return NULL;
}
/* Render a value to text. */
static char *print_value(const cJSON *item, int depth, int fmt, printbuffer *p)
static char *print_value(const cJSON *item, int depth, bool fmt, printbuffer *p)
{
char *out = 0;
char *out = NULL;
if (!item)
{
return 0;
return NULL;
}
if (p)
{
@@ -1012,12 +1017,12 @@ static char *print_value(const cJSON *item, int depth, int fmt, printbuffer *p)
/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value,const char **ep)
{
cJSON *child;
cJSON *child = NULL;
if (*value != '[')
{
/* not an array! */
*ep = value;
return 0;
return NULL;
}
item->type = cJSON_Array;
@@ -1032,23 +1037,23 @@ static const char *parse_array(cJSON *item,const char *value,const char **ep)
if (!item->child)
{
/* memory fail */
return 0;
return NULL;
}
/* skip any spacing, get the value. */
value = skip(parse_value(child, skip(value), ep));
if (!value)
{
return 0;
return NULL;
}
/* loop through the comma separated array elements */
while (*value == ',')
{
cJSON *new_item;
cJSON *new_item = NULL;
if (!(new_item = cJSON_New_Item()))
{
/* memory fail */
return 0;
return NULL;
}
/* add new item to end of the linked list */
child->next = new_item;
@@ -1060,7 +1065,7 @@ static const char *parse_array(cJSON *item,const char *value,const char **ep)
if (!value)
{
/* memory fail */
return 0;
return NULL;
}
}
@@ -1073,21 +1078,21 @@ static const char *parse_array(cJSON *item,const char *value,const char **ep)
/* malformed. */
*ep = value;
return 0;
return NULL;
}
/* Render an array to text */
static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
static char *print_array(const cJSON *item, int depth, bool fmt, printbuffer *p)
{
char **entries;
char *out = 0;
char *ptr;
char *ret;
char *out = NULL;
char *ptr = NULL;
char *ret = NULL;
int len = 5;
cJSON *child = item->child;
int numentries = 0;
int i = 0;
int fail = 0;
bool fail = false;
size_t tmplen = 0;
/* How many entries in the array? */
@@ -1124,7 +1129,7 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, 1);
if (!ptr)
{
return 0;
return NULL;
}
*ptr = '[';
p->offset++;
@@ -1140,14 +1145,14 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, len + 1);
if (!ptr)
{
return 0;
return NULL;
}
*ptr++ = ',';
if(fmt)
{
*ptr++ = ' ';
}
*ptr = 0;
*ptr = '\0';
p->offset += len;
}
child = child->next;
@@ -1155,7 +1160,7 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, 2);
if (!ptr)
{
return 0;
return NULL;
}
*ptr++ = ']';
*ptr = '\0';
@@ -1167,9 +1172,9 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
entries = (char**)cJSON_malloc(numentries * sizeof(char*));
if (!entries)
{
return 0;
return NULL;
}
memset(entries, 0, numentries * sizeof(char*));
memset(entries, '\0', numentries * sizeof(char*));
/* Retrieve all the results: */
child = item->child;
@@ -1183,7 +1188,7 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
}
else
{
fail = 1;
fail = true;
}
child = child->next;
}
@@ -1196,7 +1201,7 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
/* If that fails, we fail. */
if (!out)
{
fail = 1;
fail = true;
}
/* Handle failure. */
@@ -1211,7 +1216,7 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
}
}
cJSON_free(entries);
return 0;
return NULL;
}
/* Compose the output array. */
@@ -1230,7 +1235,7 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
{
*ptr++ = ' ';
}
*ptr = 0;
*ptr = '\0';
}
cJSON_free(entries[i]);
}
@@ -1245,12 +1250,12 @@ static char *print_array(const cJSON *item, int depth, int fmt, printbuffer *p)
/* Build an object from the text. */
static const char *parse_object(cJSON *item, const char *value, const char **ep)
{
cJSON *child;
cJSON *child = NULL;
if (*value != '{')
{
/* not an object! */
*ep = value;
return 0;
return NULL;
}
item->type = cJSON_Object;
@@ -1265,38 +1270,38 @@ static const char *parse_object(cJSON *item, const char *value, const char **ep)
item->child = child;
if (!item->child)
{
return 0;
return NULL;
}
/* parse first key */
value = skip(parse_string(child, skip(value), ep));
if (!value)
{
return 0;
return NULL;
}
/* use string as key, not value */
child->string = child->valuestring;
child->valuestring = 0;
child->valuestring = NULL;
if (*value != ':')
{
/* invalid object. */
*ep = value;
return 0;
return NULL;
}
/* skip any spacing, get the value. */
value = skip(parse_value(child, skip(value + 1), ep));
if (!value)
{
return 0;
return NULL;
}
while (*value == ',')
{
cJSON *new_item;
cJSON *new_item = NULL;
if (!(new_item = cJSON_New_Item()))
{
/* memory fail */
return 0;
return NULL;
}
/* add to linked list */
child->next = new_item;
@@ -1306,24 +1311,24 @@ static const char *parse_object(cJSON *item, const char *value, const char **ep)
value = skip(parse_string(child, skip(value + 1), ep));
if (!value)
{
return 0;
return NULL;
}
/* use string as key, not value */
child->string = child->valuestring;
child->valuestring = 0;
child->valuestring = NULL;
if (*value != ':')
{
/* invalid object. */
*ep = value;
return 0;
return NULL;
}
/* skip any spacing, get the value. */
value = skip(parse_value(child, skip(value + 1), ep));
if (!value)
{
return 0;
return NULL;
}
}
/* end of object */
@@ -1334,24 +1339,24 @@ static const char *parse_object(cJSON *item, const char *value, const char **ep)
/* malformed */
*ep = value;
return 0;
return NULL;
}
/* Render an object to text. */
static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
static char *print_object(const cJSON *item, int depth, bool fmt, printbuffer *p)
{
char **entries = 0;
char **names = 0;
char *out = 0;
char *ptr;
char *ret;
char *str;
char **entries = NULL;
char **names = NULL;
char *out = NULL;
char *ptr = NULL;
char *ret = NULL;
char *str = NULL;
int len = 7;
int i = 0;
int j;
int j = 0;
cJSON *child = item->child;
int numentries = 0;
int fail = 0;
bool fail = false;
size_t tmplen = 0;
/* Count the number of entries. */
@@ -1374,7 +1379,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
}
if (!out)
{
return 0;
return NULL;
}
ptr = out;
*ptr++ = '{';
@@ -1399,7 +1404,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, len + 1);
if (!ptr)
{
return 0;
return NULL;
}
*ptr++ = '{';
@@ -1419,7 +1424,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, depth);
if (!ptr)
{
return 0;
return NULL;
}
for (j = 0; j < depth; j++)
{
@@ -1436,7 +1441,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, len);
if (!ptr)
{
return 0;
return NULL;
}
*ptr++ = ':';
if (fmt)
@@ -1454,7 +1459,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, len + 1);
if (!ptr)
{
return 0;
return NULL;
}
if (child->next)
{
@@ -1474,7 +1479,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
ptr = ensure(p, fmt ? (depth + 1) : 2);
if (!ptr)
{
return 0;
return NULL;
}
if (fmt)
{
@@ -1493,16 +1498,16 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
entries = (char**)cJSON_malloc(numentries * sizeof(char*));
if (!entries)
{
return 0;
return NULL;
}
names = (char**)cJSON_malloc(numentries * sizeof(char*));
if (!names)
{
cJSON_free(entries);
return 0;
return NULL;
}
memset(entries,0, sizeof(char*) * numentries);
memset(names, 0, sizeof(char*) * numentries);
memset(entries, '\0', sizeof(char*) * numentries);
memset(names, '\0', sizeof(char*) * numentries);
/* Collect all the results into our arrays: */
child = item->child;
@@ -1521,7 +1526,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
}
else
{
fail = 1;
fail = true;
}
child = child->next;
}
@@ -1533,7 +1538,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
}
if (!out)
{
fail = 1;
fail = true;
}
/* Handle failure */
@@ -1553,7 +1558,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
}
cJSON_free(names);
cJSON_free(entries);
return 0;
return NULL;
}
/* Compose the output: */
@@ -1563,7 +1568,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
{
*ptr++ = '\n';
}
*ptr = 0;
*ptr = '\0';
for (i = 0; i < numentries; i++)
{
if (fmt)
@@ -1591,7 +1596,7 @@ static char *print_object(const cJSON *item, int depth, int fmt, printbuffer *p)
{
*ptr++ = '\n';
}
*ptr = 0;
*ptr = '\0';
cJSON_free(names[i]);
cJSON_free(entries[i]);
}
@@ -1627,7 +1632,7 @@ int cJSON_GetArraySize(const cJSON *array)
cJSON *cJSON_GetArrayItem(const cJSON *array, int item)
{
cJSON *c = array ? array->child : 0;
cJSON *c = array ? array->child : NULL;
while (c && item > 0)
{
item--;
@@ -1639,7 +1644,7 @@ cJSON *cJSON_GetArrayItem(const cJSON *array, int item)
cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string)
{
cJSON *c = object ? object->child : 0;
cJSON *c = object ? object->child : NULL;
while (c && cJSON_strcasecmp(c->string, string))
{
c = c->next;
@@ -1647,7 +1652,7 @@ cJSON *cJSON_GetObjectItem(const cJSON *object, const char *string)
return c;
}
int cJSON_HasObjectItem(const cJSON *object,const char *string)
bool cJSON_HasObjectItem(const cJSON *object,const char *string)
{
return cJSON_GetObjectItem(object, string) ? 1 : 0;
}
@@ -1665,12 +1670,12 @@ static cJSON *create_reference(const cJSON *item)
cJSON *ref = cJSON_New_Item();
if (!ref)
{
return 0;
return NULL;
}
memcpy(ref, item, sizeof(cJSON));
ref->string = 0;
ref->string = NULL;
ref->type |= cJSON_IsReference;
ref->next = ref->prev = 0;
ref->next = ref->prev = NULL;
return ref;
}
@@ -1752,7 +1757,7 @@ cJSON *cJSON_DetachItemFromArray(cJSON *array, int which)
if (!c)
{
/* item doesn't exist */
return 0;
return NULL;
}
if (c->prev)
{
@@ -1768,7 +1773,7 @@ cJSON *cJSON_DetachItemFromArray(cJSON *array, int which)
array->child = c->next;
}
/* make sure the detached item doesn't point anywhere anymore */
c->prev = c->next = 0;
c->prev = c->next = NULL;
return c;
}
@@ -1792,7 +1797,7 @@ cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string)
return cJSON_DetachItemFromArray(object, i);
}
return 0;
return NULL;
}
void cJSON_DeleteItemFromObject(cJSON *object, const char *string)
@@ -1853,7 +1858,7 @@ void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
{
newitem->prev->next = newitem;
}
c->next = c->prev = 0;
c->next = c->prev = NULL;
cJSON_Delete(c);
}
@@ -1913,7 +1918,7 @@ cJSON *cJSON_CreateFalse(void)
return item;
}
cJSON *cJSON_CreateBool(int b)
cJSON *cJSON_CreateBool(bool b)
{
cJSON *item = cJSON_New_Item();
if(item)
@@ -1947,7 +1952,7 @@ cJSON *cJSON_CreateString(const char *string)
if(!item->valuestring)
{
cJSON_Delete(item);
return 0;
return NULL;
}
}
@@ -1979,9 +1984,9 @@ cJSON *cJSON_CreateObject(void)
/* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers, int count)
{
int i;
cJSON *n = 0;
cJSON *p = 0;
int i = 0;
cJSON *n = NULL;
cJSON *p = NULL;
cJSON *a = cJSON_CreateArray();
for(i = 0; a && (i < count); i++)
{
@@ -1989,7 +1994,7 @@ cJSON *cJSON_CreateIntArray(const int *numbers, int count)
if (!n)
{
cJSON_Delete(a);
return 0;
return NULL;
}
if(!i)
{
@@ -2007,9 +2012,9 @@ cJSON *cJSON_CreateIntArray(const int *numbers, int count)
cJSON *cJSON_CreateFloatArray(const float *numbers, int count)
{
int i;
cJSON *n = 0;
cJSON *p = 0;
int i = 0;
cJSON *n = NULL;
cJSON *p = NULL;
cJSON *a = cJSON_CreateArray();
for(i = 0; a && (i < count); i++)
{
@@ -2017,7 +2022,7 @@ cJSON *cJSON_CreateFloatArray(const float *numbers, int count)
if(!n)
{
cJSON_Delete(a);
return 0;
return NULL;
}
if(!i)
{
@@ -2035,9 +2040,9 @@ cJSON *cJSON_CreateFloatArray(const float *numbers, int count)
cJSON *cJSON_CreateDoubleArray(const double *numbers, int count)
{
int i;
cJSON *n = 0;
cJSON *p = 0;
int i = 0;
cJSON *n = NULL;
cJSON *p = NULL;
cJSON *a = cJSON_CreateArray();
for(i = 0;a && (i < count); i++)
{
@@ -2045,7 +2050,7 @@ cJSON *cJSON_CreateDoubleArray(const double *numbers, int count)
if(!n)
{
cJSON_Delete(a);
return 0;
return NULL;
}
if(!i)
{
@@ -2063,9 +2068,9 @@ cJSON *cJSON_CreateDoubleArray(const double *numbers, int count)
cJSON *cJSON_CreateStringArray(const char **strings, int count)
{
int i;
cJSON *n = 0;
cJSON *p = 0;
int i = 0;
cJSON *n = NULL;
cJSON *p = NULL;
cJSON *a = cJSON_CreateArray();
for (i = 0; a && (i < count); i++)
{
@@ -2073,7 +2078,7 @@ cJSON *cJSON_CreateStringArray(const char **strings, int count)
if(!n)
{
cJSON_Delete(a);
return 0;
return NULL;
}
if(!i)
{
@@ -2090,23 +2095,23 @@ cJSON *cJSON_CreateStringArray(const char **strings, int count)
}
/* Duplication */
cJSON *cJSON_Duplicate(const cJSON *item, int recurse)
cJSON *cJSON_Duplicate(const cJSON *item, bool recurse)
{
cJSON *newitem;
cJSON *cptr;
cJSON *nptr = 0;
cJSON *newchild;
cJSON *newitem = NULL;
cJSON *cptr = NULL;
cJSON *nptr = NULL;
cJSON *newchild = NULL;
/* Bail on bad ptr */
if (!item)
{
return 0;
return NULL;
}
/* Create new item */
newitem = cJSON_New_Item();
if (!newitem)
{
return 0;
return NULL;
}
/* Copy over all vars */
newitem->type = item->type & (~cJSON_IsReference);
@@ -2118,7 +2123,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, int recurse)
if (!newitem->valuestring)
{
cJSON_Delete(newitem);
return 0;
return NULL;
}
}
if (item->string)
@@ -2127,7 +2132,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, int recurse)
if (!newitem->string)
{
cJSON_Delete(newitem);
return 0;
return NULL;
}
}
/* If non-recursive, then we're done! */
@@ -2143,7 +2148,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, int recurse)
if (!newchild)
{
cJSON_Delete(newitem);
return 0;
return NULL;
}
if (nptr)
{

View File

@@ -6,13 +6,13 @@
static char* cJSONUtils_strdup(const char* str)
{
size_t len;
char* copy;
size_t len = 0;
char *copy = NULL;
len = strlen(str) + 1;
if (!(copy = (char*)malloc(len)))
{
return 0;
return NULL;
}
memcpy(copy, str, len);
@@ -131,7 +131,7 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target)
char *found = cJSONUtils_FindPointerFromObjectTo(obj, target);
if (found)
{
if (type == cJSON_Array)
if ((type & 0xFF) == cJSON_Array)
{
/* reserve enough memory for a 64 bit integer + '/' and '\0' */
char *ret = (char*)malloc(strlen(found) + 23);
@@ -140,7 +140,7 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target)
return ret;
}
else if (type == cJSON_Object)
else if ((type & 0xFF) == cJSON_Object)
{
char *ret = (char*)malloc(strlen(found) + cJSONUtils_PointerEncodedstrlen(obj->string) + 2);
*ret = '/';
@@ -153,12 +153,12 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target)
/* reached leaf of the tree, found nothing */
free(found);
return 0;
return NULL;
}
}
/* not found */
return 0;
return NULL;
}
cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
@@ -166,7 +166,7 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
/* follow path of the pointer */
while ((*pointer++ == '/') && object)
{
if (object->type == cJSON_Array)
if ((object->type & 0xFF) == cJSON_Array)
{
int which = 0;
/* parse array index */
@@ -177,11 +177,11 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
if (*pointer && (*pointer != '/'))
{
/* not end of string or new path token */
return 0;
return NULL;
}
object = cJSON_GetArrayItem(object, which);
}
else if (object->type == cJSON_Object)
else if ((object->type & 0xFF) == cJSON_Object)
{
object = object->child;
/* GetObjectItem. */
@@ -197,7 +197,7 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
}
else
{
return 0;
return NULL;
}
}
@@ -222,10 +222,10 @@ static void cJSONUtils_InplaceDecodePointerString(char *string)
static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path)
{
char *parentptr = 0;
char *childptr = 0;
cJSON *parent = 0;
cJSON *ret = 0;
char *parentptr = NULL;
char *childptr = NULL;
cJSON *parent = NULL;
cJSON *ret = NULL;
/* copy path and split it in parent and child */
parentptr = cJSONUtils_strdup(path);
@@ -241,13 +241,13 @@ static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path)
if (!parent)
{
/* Couldn't find object to remove child from. */
ret = 0;
ret = NULL;
}
else if (parent->type == cJSON_Array)
else if ((parent->type & 0xFF) == cJSON_Array)
{
ret = cJSON_DetachItemFromArray(parent, atoi(childptr));
}
else if (parent->type == cJSON_Object)
else if ((parent->type & 0xFF) == cJSON_Object)
{
ret = cJSON_DetachItemFromObject(parent, childptr);
}
@@ -259,12 +259,12 @@ static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path)
static int cJSONUtils_Compare(cJSON *a, cJSON *b)
{
if (a->type != b->type)
if ((a->type & 0xFF) != (b->type & 0xFF))
{
/* mismatched type. */
return -1;
}
switch (a->type)
switch (a->type & 0xFF)
{
case cJSON_Number:
/* numeric mismatch. */
@@ -290,7 +290,7 @@ static int cJSONUtils_Compare(cJSON *a, cJSON *b)
b = b->child;
while (a && b)
{
int err;
int err = 0;
/* compare object keys */
if (cJSONUtils_strcasecmp(a->string, b->string))
{
@@ -317,13 +317,13 @@ static int cJSONUtils_Compare(cJSON *a, cJSON *b)
static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
{
cJSON *op = 0;
cJSON *path = 0;
cJSON *value = 0;
cJSON *parent = 0;
cJSON *op = NULL;
cJSON *path = NULL;
cJSON *value = NULL;
cJSON *parent = NULL;
int opcode = 0;
char *parentptr = 0;
char *childptr = 0;
char *parentptr = NULL;
char *childptr = NULL;
op = cJSON_GetObjectItem(patch, "op");
path = cJSON_GetObjectItem(patch, "path");
@@ -448,7 +448,7 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
cJSON_Delete(value);
return 9;
}
else if (parent->type == cJSON_Array)
else if ((parent->type & 0xFF) == cJSON_Array)
{
if (!strcmp(childptr, "-"))
{
@@ -459,7 +459,7 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
cJSON_InsertItemInArray(parent, atoi(childptr), value);
}
}
else if (parent->type == cJSON_Object)
else if ((parent->type & 0xFF) == cJSON_Object)
{
cJSON_DeleteItemFromObject(parent, childptr);
cJSON_AddItemToObject(parent, childptr, value);
@@ -475,8 +475,8 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
int cJSONUtils_ApplyPatches(cJSON *object, cJSON *patches)
{
int err;
if (patches->type != cJSON_Array)
int err = 0;
if ((patches->type & 0xFF) != cJSON_Array)
{
/* malformed patches. */
return 1;
@@ -526,13 +526,13 @@ void cJSONUtils_AddPatchToArray(cJSON *array, const char *op, const char *path,
static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *from, cJSON *to)
{
if (from->type != to->type)
if ((from->type & 0xFF) != (to->type & 0xFF))
{
cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
return;
}
switch (from->type)
switch ((from->type & 0xFF))
{
case cJSON_Number:
if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble))
@@ -550,7 +550,7 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f
case cJSON_Array:
{
int c;
int c = 0;
char *newpath = (char*)malloc(strlen(path) + 23); /* Allow space for 64bit int. */
/* generate patches for all array elements that exist in "from" and "to" */
for (c = 0, from = from->child, to = to->child; from && to; from = from->next, to = to->next, c++)
@@ -575,8 +575,8 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f
case cJSON_Object:
{
cJSON *a;
cJSON *b;
cJSON *a = NULL;
cJSON *b = NULL;
cJSONUtils_SortObject(from);
cJSONUtils_SortObject(to);
@@ -666,13 +666,13 @@ static cJSON *cJSONUtils_SortList(cJSON *list)
if (second && second->prev)
{
/* Split the lists */
second->prev->next = 0;
second->prev->next = NULL;
}
/* Recursively sort the sub-lists. */
first = cJSONUtils_SortList(first);
second = cJSONUtils_SortList(second);
list = ptr = 0;
list = ptr = NULL;
while (first && second) /* Merge the sub-lists */
{
@@ -740,14 +740,14 @@ void cJSONUtils_SortObject(cJSON *object)
cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
{
if (!patch || (patch->type != cJSON_Object))
if (!patch || ((patch->type & 0xFF) != cJSON_Object))
{
/* scalar value, array or NULL, just duplicate */
cJSON_Delete(target);
return cJSON_Duplicate(patch, 1);
}
if (!target || (target->type != cJSON_Object))
if (!target || ((target->type & 0xFF) != cJSON_Object))
{
cJSON_Delete(target);
target = cJSON_CreateObject();
@@ -756,7 +756,7 @@ cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
patch = patch->child;
while (patch)
{
if (patch->type == cJSON_NULL)
if ((patch->type & 0xFF) == cJSON_NULL)
{
/* NULL is the indicator to remove a value, see RFC7396 */
cJSON_DeleteItemFromObject(target, patch->string);
@@ -773,13 +773,13 @@ cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
{
cJSON *patch = 0;
cJSON *patch = NULL;
if (!to)
{
/* patch to delete everything */
return cJSON_CreateNull();
}
if ((to->type != cJSON_Object) || !from || (from->type != cJSON_Object))
if (((to->type & 0xFF) != cJSON_Object) || !from || ((from->type & 0xFF) != cJSON_Object))
{
return cJSON_Duplicate(to, 1);
}
@@ -821,7 +821,7 @@ cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
if (!patch->child)
{
cJSON_Delete(patch);
return 0;
return NULL;
}
return patch;

24
test.c
View File

@@ -27,8 +27,8 @@
/* Parse text to JSON, then render back to text, and print! */
void doit(char *text)
{
char *out;
cJSON *json;
char *out = NULL;
cJSON *json = NULL;
json = cJSON_Parse(text);
if (!json)
@@ -47,9 +47,9 @@ void doit(char *text)
/* Read a file, parse, render back, etc. */
void dofile(char *filename)
{
FILE *f;
long len;
char *data;
FILE *f = NULL;
long len = 0;
char *data = NULL;
/* open in read binary mode */
f = fopen(filename,"rb");
@@ -85,13 +85,13 @@ struct record
void create_objects(void)
{
/* declare a few. */
cJSON *root;
cJSON *fmt;
cJSON *img;
cJSON *thm;
cJSON *fld;
char *out;
int i;
cJSON *root = NULL;
cJSON *fmt = NULL;
cJSON *img = NULL;
cJSON *thm = NULL;
cJSON *fld = NULL;
char *out = NULL;
int i = 0;
/* Our "days of the week" array: */
const char *strings[7] =

View File

@@ -5,167 +5,202 @@
int main(void)
{
/* Some variables */
char *temp = NULL;
char *patchtext = NULL;
char *patchedtext = NULL;
/* Some variables */
char *temp = NULL;
char *patchtext = NULL;
char *patchedtext = NULL;
int i;
/* JSON Pointer tests: */
cJSON *root;
const char *json="{"
"\"foo\": [\"bar\", \"baz\"],"
"\"\": 0,"
"\"a/b\": 1,"
"\"c%d\": 2,"
"\"e^f\": 3,"
"\"g|h\": 4,"
"\"i\\\\j\": 5,"
"\"k\\\"l\": 6,"
"\" \": 7,"
"\"m~n\": 8"
"}";
const char *tests[12]={"","/foo","/foo/0","/","/a~1b","/c%d","/e^f","/g|h","/i\\j","/k\"l","/ ","/m~0n"};
/* JSON Apply Patch tests: */
const char *patches[15][3]={
{"{ \"foo\": \"bar\"}", "[{ \"op\": \"add\", \"path\": \"/baz\", \"value\": \"qux\" }]","{\"baz\": \"qux\",\"foo\": \"bar\"}"},
{"{ \"foo\": [ \"bar\", \"baz\" ] }", "[{ \"op\": \"add\", \"path\": \"/foo/1\", \"value\": \"qux\" }]","{\"foo\": [ \"bar\", \"qux\", \"baz\" ] }"},
{"{\"baz\": \"qux\",\"foo\": \"bar\"}"," [{ \"op\": \"remove\", \"path\": \"/baz\" }]","{\"foo\": \"bar\" }"},
{"{ \"foo\": [ \"bar\", \"qux\", \"baz\" ] }","[{ \"op\": \"remove\", \"path\": \"/foo/1\" }]","{\"foo\": [ \"bar\", \"baz\" ] }"},
{"{ \"baz\": \"qux\",\"foo\": \"bar\"}","[{ \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" }]","{\"baz\": \"boo\",\"foo\": \"bar\"}"},
{"{\"foo\": {\"bar\": \"baz\",\"waldo\": \"fred\"},\"qux\": {\"corge\": \"grault\"}}","[{ \"op\": \"move\", \"from\": \"/foo/waldo\", \"path\": \"/qux/thud\" }]","{\"foo\": {\"bar\": \"baz\"},\"qux\": {\"corge\": \"grault\",\"thud\": \"fred\"}}"},
{"{ \"foo\": [ \"all\", \"grass\", \"cows\", \"eat\" ] }","[ { \"op\": \"move\", \"from\": \"/foo/1\", \"path\": \"/foo/3\" }]","{ \"foo\": [ \"all\", \"cows\", \"eat\", \"grass\" ] }"},
{"{\"baz\": \"qux\",\"foo\": [ \"a\", 2, \"c\" ]}","[{ \"op\": \"test\", \"path\": \"/baz\", \"value\": \"qux\" },{ \"op\": \"test\", \"path\": \"/foo/1\", \"value\": 2 }]",""},
{"{ \"baz\": \"qux\" }","[ { \"op\": \"test\", \"path\": \"/baz\", \"value\": \"bar\" }]",""},
{"{ \"foo\": \"bar\" }","[{ \"op\": \"add\", \"path\": \"/child\", \"value\": { \"grandchild\": { } } }]","{\"foo\": \"bar\",\"child\": {\"grandchild\": {}}}"},
{"{ \"foo\": \"bar\" }","[{ \"op\": \"add\", \"path\": \"/baz\", \"value\": \"qux\", \"xyz\": 123 }]","{\"foo\": \"bar\",\"baz\": \"qux\"}"},
{"{ \"foo\": \"bar\" }","[{ \"op\": \"add\", \"path\": \"/baz/bat\", \"value\": \"qux\" }]",""},
{"{\"/\": 9,\"~1\": 10}","[{\"op\": \"test\", \"path\": \"/~01\", \"value\": 10}]",""},
{"{\"/\": 9,\"~1\": 10}","[{\"op\": \"test\", \"path\": \"/~01\", \"value\": \"10\"}]",""},
{"{ \"foo\": [\"bar\"] }","[ { \"op\": \"add\", \"path\": \"/foo/-\", \"value\": [\"abc\", \"def\"] }]","{\"foo\": [\"bar\", [\"abc\", \"def\"]] }"}};
/* JSON Apply Merge tests: */
const char *merges[15][3]={
{"{\"a\":\"b\"}", "{\"a\":\"c\"}", "{\"a\":\"c\"}"},
{"{\"a\":\"b\"}", "{\"b\":\"c\"}", "{\"a\":\"b\",\"b\":\"c\"}"},
{"{\"a\":\"b\"}", "{\"a\":null}", "{}"},
{"{\"a\":\"b\",\"b\":\"c\"}", "{\"a\":null}", "{\"b\":\"c\"}"},
{"{\"a\":[\"b\"]}", "{\"a\":\"c\"}", "{\"a\":\"c\"}"},
{"{\"a\":\"c\"}", "{\"a\":[\"b\"]}", "{\"a\":[\"b\"]}"},
{"{\"a\":{\"b\":\"c\"}}", "{\"a\":{\"b\":\"d\",\"c\":null}}", "{\"a\":{\"b\":\"d\"}}"},
{"{\"a\":[{\"b\":\"c\"}]}", "{\"a\":[1]}", "{\"a\":[1]}"},
{"[\"a\",\"b\"]", "[\"c\",\"d\"]", "[\"c\",\"d\"]"},
{"{\"a\":\"b\"}", "[\"c\"]", "[\"c\"]"},
{"{\"a\":\"foo\"}", "null", "null"},
{"{\"a\":\"foo\"}", "\"bar\"", "\"bar\""},
{"{\"e\":null}", "{\"a\":1}", "{\"e\":null,\"a\":1}"},
{"[1,2]", "{\"a\":\"b\",\"c\":null}", "{\"a\":\"b\"}"},
{"{}","{\"a\":{\"bb\":{\"ccc\":null}}}", "{\"a\":{\"bb\":{}}}"}};
int i = 0;
/* JSON Pointer tests: */
cJSON *root = NULL;
const char *json=
"{"
"\"foo\": [\"bar\", \"baz\"],"
"\"\": 0,"
"\"a/b\": 1,"
"\"c%d\": 2,"
"\"e^f\": 3,"
"\"g|h\": 4,"
"\"i\\\\j\": 5,"
"\"k\\\"l\": 6,"
"\" \": 7,"
"\"m~n\": 8"
"}";
/* Misc tests */
int numbers[10]={0,1,2,3,4,5,6,7,8,9};
const char *random="QWERTYUIOPASDFGHJKLZXCVBNM";
char buf[2]={0,0},*before,*after;
cJSON *object,*nums,*num6,*sortme;
const char *tests[12] = {"","/foo","/foo/0","/","/a~1b","/c%d","/e^f","/g|h","/i\\j","/k\"l","/ ","/m~0n"};
/* JSON Apply Patch tests: */
const char *patches[15][3] =
{
{"{ \"foo\": \"bar\"}", "[{ \"op\": \"add\", \"path\": \"/baz\", \"value\": \"qux\" }]","{\"baz\": \"qux\",\"foo\": \"bar\"}"},
{"{ \"foo\": [ \"bar\", \"baz\" ] }", "[{ \"op\": \"add\", \"path\": \"/foo/1\", \"value\": \"qux\" }]","{\"foo\": [ \"bar\", \"qux\", \"baz\" ] }"},
{"{\"baz\": \"qux\",\"foo\": \"bar\"}"," [{ \"op\": \"remove\", \"path\": \"/baz\" }]","{\"foo\": \"bar\" }"},
{"{ \"foo\": [ \"bar\", \"qux\", \"baz\" ] }","[{ \"op\": \"remove\", \"path\": \"/foo/1\" }]","{\"foo\": [ \"bar\", \"baz\" ] }"},
{"{ \"baz\": \"qux\",\"foo\": \"bar\"}","[{ \"op\": \"replace\", \"path\": \"/baz\", \"value\": \"boo\" }]","{\"baz\": \"boo\",\"foo\": \"bar\"}"},
{"{\"foo\": {\"bar\": \"baz\",\"waldo\": \"fred\"},\"qux\": {\"corge\": \"grault\"}}","[{ \"op\": \"move\", \"from\": \"/foo/waldo\", \"path\": \"/qux/thud\" }]","{\"foo\": {\"bar\": \"baz\"},\"qux\": {\"corge\": \"grault\",\"thud\": \"fred\"}}"},
{"{ \"foo\": [ \"all\", \"grass\", \"cows\", \"eat\" ] }","[ { \"op\": \"move\", \"from\": \"/foo/1\", \"path\": \"/foo/3\" }]","{ \"foo\": [ \"all\", \"cows\", \"eat\", \"grass\" ] }"},
{"{\"baz\": \"qux\",\"foo\": [ \"a\", 2, \"c\" ]}","[{ \"op\": \"test\", \"path\": \"/baz\", \"value\": \"qux\" },{ \"op\": \"test\", \"path\": \"/foo/1\", \"value\": 2 }]",""},
{"{ \"baz\": \"qux\" }","[ { \"op\": \"test\", \"path\": \"/baz\", \"value\": \"bar\" }]",""},
{"{ \"foo\": \"bar\" }","[{ \"op\": \"add\", \"path\": \"/child\", \"value\": { \"grandchild\": { } } }]","{\"foo\": \"bar\",\"child\": {\"grandchild\": {}}}"},
{"{ \"foo\": \"bar\" }","[{ \"op\": \"add\", \"path\": \"/baz\", \"value\": \"qux\", \"xyz\": 123 }]","{\"foo\": \"bar\",\"baz\": \"qux\"}"},
{"{ \"foo\": \"bar\" }","[{ \"op\": \"add\", \"path\": \"/baz/bat\", \"value\": \"qux\" }]",""},
{"{\"/\": 9,\"~1\": 10}","[{\"op\": \"test\", \"path\": \"/~01\", \"value\": 10}]",""},
{"{\"/\": 9,\"~1\": 10}","[{\"op\": \"test\", \"path\": \"/~01\", \"value\": \"10\"}]",""},
{"{ \"foo\": [\"bar\"] }","[ { \"op\": \"add\", \"path\": \"/foo/-\", \"value\": [\"abc\", \"def\"] }]","{\"foo\": [\"bar\", [\"abc\", \"def\"]] }"}
};
/* JSON Apply Merge tests: */
const char *merges[15][3] =
{
{"{\"a\":\"b\"}", "{\"a\":\"c\"}", "{\"a\":\"c\"}"},
{"{\"a\":\"b\"}", "{\"b\":\"c\"}", "{\"a\":\"b\",\"b\":\"c\"}"},
{"{\"a\":\"b\"}", "{\"a\":null}", "{}"},
{"{\"a\":\"b\",\"b\":\"c\"}", "{\"a\":null}", "{\"b\":\"c\"}"},
{"{\"a\":[\"b\"]}", "{\"a\":\"c\"}", "{\"a\":\"c\"}"},
{"{\"a\":\"c\"}", "{\"a\":[\"b\"]}", "{\"a\":[\"b\"]}"},
{"{\"a\":{\"b\":\"c\"}}", "{\"a\":{\"b\":\"d\",\"c\":null}}", "{\"a\":{\"b\":\"d\"}}"},
{"{\"a\":[{\"b\":\"c\"}]}", "{\"a\":[1]}", "{\"a\":[1]}"},
{"[\"a\",\"b\"]", "[\"c\",\"d\"]", "[\"c\",\"d\"]"},
{"{\"a\":\"b\"}", "[\"c\"]", "[\"c\"]"},
{"{\"a\":\"foo\"}", "null", "null"},
{"{\"a\":\"foo\"}", "\"bar\"", "\"bar\""},
{"{\"e\":null}", "{\"a\":1}", "{\"e\":null,\"a\":1}"},
{"[1,2]", "{\"a\":\"b\",\"c\":null}", "{\"a\":\"b\"}"},
{"{}","{\"a\":{\"bb\":{\"ccc\":null}}}", "{\"a\":{\"bb\":{}}}"}
};
printf("JSON Pointer Tests\n");
root=cJSON_Parse(json);
for (i=0;i<12;i++)
{
char *output=cJSON_Print(cJSONUtils_GetPointer(root,tests[i]));
printf("Test %d:\n%s\n\n",i+1,output);
free(output);
}
cJSON_Delete(root);
/* Misc tests */
int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
const char *random = "QWERTYUIOPASDFGHJKLZXCVBNM";
char buf[2] = {0,0};
char *before = NULL;
char *after = NULL;
cJSON *object = NULL;
cJSON *nums = NULL;
cJSON *num6 = NULL;
cJSON *sortme = NULL;
printf("JSON Apply Patch Tests\n");
for (i=0;i<15;i++)
{
cJSON *object=cJSON_Parse(patches[i][0]);
cJSON *patch=cJSON_Parse(patches[i][1]);
int err=cJSONUtils_ApplyPatches(object,patch);
char *output=cJSON_Print(object);
printf("Test %d (err %d):\n%s\n\n",i+1,err,output);
free(output);cJSON_Delete(object);cJSON_Delete(patch);
}
printf("JSON Pointer Tests\n");
root = cJSON_Parse(json);
for (i = 0; i < 12; i++)
{
char *output = cJSON_Print(cJSONUtils_GetPointer(root, tests[i]));
printf("Test %d:\n%s\n\n", i + 1, output);
free(output);
}
cJSON_Delete(root);
/* JSON Generate Patch tests: */
printf("JSON Generate Patch Tests\n");
for (i=0;i<15;i++)
{
cJSON *from,*to,*patch;char *out;
if (!strlen(patches[i][2])) continue;
from=cJSON_Parse(patches[i][0]);
to=cJSON_Parse(patches[i][2]);
patch=cJSONUtils_GeneratePatches(from,to);
out=cJSON_Print(patch);
printf("Test %d: (patch: %s):\n%s\n\n",i+1,patches[i][1],out);
free(out);cJSON_Delete(from);cJSON_Delete(to);cJSON_Delete(patch);
}
/* Misc tests: */
printf("JSON Pointer construct\n");
object=cJSON_CreateObject();
nums=cJSON_CreateIntArray(numbers,10);
num6=cJSON_GetArrayItem(nums,6);
cJSON_AddItemToObject(object,"numbers",nums);
temp=cJSONUtils_FindPointerFromObjectTo(object,num6);
printf("Pointer: [%s]\n",temp);
free(temp);
temp=cJSONUtils_FindPointerFromObjectTo(object,nums);
printf("Pointer: [%s]\n",temp);
free(temp);
temp=cJSONUtils_FindPointerFromObjectTo(object,object);
printf("Pointer: [%s]\n",temp);
free(temp);
cJSON_Delete(object);
printf("JSON Apply Patch Tests\n");
for (i = 0; i < 15; i++)
{
cJSON *object = cJSON_Parse(patches[i][0]);
cJSON *patch = cJSON_Parse(patches[i][1]);
int err = cJSONUtils_ApplyPatches(object, patch);
char *output = cJSON_Print(object);
printf("Test %d (err %d):\n%s\n\n", i + 1, err, output);
/* JSON Sort test: */
sortme=cJSON_CreateObject();
for (i=0;i<26;i++)
{
buf[0]=random[i];cJSON_AddItemToObject(sortme,buf,cJSON_CreateNumber(1));
}
before=cJSON_PrintUnformatted(sortme);
cJSONUtils_SortObject(sortme);
after=cJSON_PrintUnformatted(sortme);
printf("Before: [%s]\nAfter: [%s]\n\n",before,after);
free(before);free(after);cJSON_Delete(sortme);
/* Merge tests: */
printf("JSON Merge Patch tests\n");
for (i=0;i<15;i++)
{
cJSON *object=cJSON_Parse(merges[i][0]);
cJSON *patch=cJSON_Parse(merges[i][1]);
char *before=cJSON_PrintUnformatted(object);
patchtext=cJSON_PrintUnformatted(patch);
printf("Before: [%s] -> [%s] = ",before,patchtext);
object=cJSONUtils_MergePatch(object,patch);
after=cJSON_PrintUnformatted(object);
printf("[%s] vs [%s] (%s)\n",after,merges[i][2],strcmp(after,merges[i][2])?"FAIL":"OK");
free(output);
cJSON_Delete(object);
cJSON_Delete(patch);
}
free(before);free(patchtext);free(after);cJSON_Delete(object);cJSON_Delete(patch);
}
/* Generate Merge tests: */
for (i=0;i<15;i++)
{
cJSON *from=cJSON_Parse(merges[i][0]);
cJSON *to=cJSON_Parse(merges[i][2]);
cJSON *patch=cJSONUtils_GenerateMergePatch(from,to);
from=cJSONUtils_MergePatch(from,patch);
patchtext=cJSON_PrintUnformatted(patch);
patchedtext=cJSON_PrintUnformatted(from);
printf("Patch [%s] vs [%s] = [%s] vs [%s] (%s)\n",patchtext,merges[i][1],patchedtext,merges[i][2],strcmp(patchedtext,merges[i][2])?"FAIL":"OK");
cJSON_Delete(from);cJSON_Delete(to);cJSON_Delete(patch);free(patchtext);free(patchedtext);
}
/* JSON Generate Patch tests: */
printf("JSON Generate Patch Tests\n");
for (i = 0; i < 15; i++)
{
cJSON *from;
cJSON *to;
cJSON *patch;
char *out;
if (!strlen(patches[i][2]))
{
continue;
}
from = cJSON_Parse(patches[i][0]);
to = cJSON_Parse(patches[i][2]);
patch = cJSONUtils_GeneratePatches(from, to);
out = cJSON_Print(patch);
printf("Test %d: (patch: %s):\n%s\n\n", i + 1, patches[i][1], out);
return 0;
free(out);
cJSON_Delete(from);
cJSON_Delete(to);
cJSON_Delete(patch);
}
/* Misc tests: */
printf("JSON Pointer construct\n");
object = cJSON_CreateObject();
nums = cJSON_CreateIntArray(numbers, 10);
num6 = cJSON_GetArrayItem(nums, 6);
cJSON_AddItemToObject(object, "numbers", nums);
temp = cJSONUtils_FindPointerFromObjectTo(object, num6);
printf("Pointer: [%s]\n", temp);
free(temp);
temp = cJSONUtils_FindPointerFromObjectTo(object, nums);
printf("Pointer: [%s]\n", temp);
free(temp);
temp = cJSONUtils_FindPointerFromObjectTo(object, object);
printf("Pointer: [%s]\n", temp);
free(temp);
cJSON_Delete(object);
/* JSON Sort test: */
sortme = cJSON_CreateObject();
for (i = 0; i < 26; i++)
{
buf[0] = random[i];
cJSON_AddItemToObject(sortme, buf, cJSON_CreateNumber(1));
}
before = cJSON_PrintUnformatted(sortme);
cJSONUtils_SortObject(sortme);
after = cJSON_PrintUnformatted(sortme);
printf("Before: [%s]\nAfter: [%s]\n\n", before, after);
free(before);
free(after);
cJSON_Delete(sortme);
/* Merge tests: */
printf("JSON Merge Patch tests\n");
for (i = 0; i < 15; i++)
{
cJSON *object = cJSON_Parse(merges[i][0]);
cJSON *patch = cJSON_Parse(merges[i][1]);
char *before = cJSON_PrintUnformatted(object);
patchtext = cJSON_PrintUnformatted(patch);
printf("Before: [%s] -> [%s] = ", before, patchtext);
object = cJSONUtils_MergePatch(object, patch);
after = cJSON_PrintUnformatted(object);
printf("[%s] vs [%s] (%s)\n", after, merges[i][2], strcmp(after, merges[i][2]) ? "FAIL" : "OK");
free(before);
free(patchtext);
free(after);
cJSON_Delete(object);
cJSON_Delete(patch);
}
/* Generate Merge tests: */
for (i = 0; i < 15; i++)
{
cJSON *from = cJSON_Parse(merges[i][0]);
cJSON *to = cJSON_Parse(merges[i][2]);
cJSON *patch = cJSONUtils_GenerateMergePatch(from,to);
from = cJSONUtils_MergePatch(from,patch);
patchtext = cJSON_PrintUnformatted(patch);
patchedtext = cJSON_PrintUnformatted(from);
printf("Patch [%s] vs [%s] = [%s] vs [%s] (%s)\n", patchtext, merges[i][1], patchedtext, merges[i][2], strcmp(patchedtext, merges[i][2]) ? "FAIL" : "OK");
cJSON_Delete(from);
cJSON_Delete(to);
cJSON_Delete(patch);
free(patchtext);
free(patchedtext);
}
return 0;
}