mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
981f59b163 | ||
|
|
e4eadb9a81 | ||
|
|
ff0681e4fd | ||
|
|
a2309a509d | ||
|
|
c49ffbfba8 | ||
|
|
e7533aa6f0 | ||
|
|
de8eaaba89 | ||
|
|
b2da44d6cb | ||
|
|
f6998a6a34 | ||
|
|
e3e0b5150b | ||
|
|
1df987a170 | ||
|
|
ddadb44a67 | ||
|
|
9ef44fc0b6 | ||
|
|
8c58e62597 | ||
|
|
8893e39712 | ||
|
|
3d6ae11340 | ||
|
|
a1f2600883 | ||
|
|
fcc85bdfbc | ||
|
|
7d08a3518a | ||
|
|
cc486a0354 | ||
|
|
fcc89c4bb2 | ||
|
|
a0431e226f | ||
|
|
89edfb6741 | ||
|
|
e69db83de5 | ||
|
|
5310da351d | ||
|
|
68196f5b14 | ||
|
|
d992cd46e6 | ||
|
|
84b48121bb | ||
|
|
f10e2f884a | ||
|
|
eeb6d237b6 | ||
|
|
5b4420298f | ||
|
|
e1eb06fae0 | ||
|
|
6aefa45056 | ||
|
|
345d57e9e5 | ||
|
|
3da18a2df9 | ||
|
|
bf17703012 | ||
|
|
6622c54f18 | ||
|
|
8df4cd46eb | ||
|
|
3917fb5255 | ||
|
|
99896d879c | ||
|
|
4d1dcaa160 | ||
|
|
de93d76d0b | ||
|
|
602c241a0b | ||
|
|
23dafa4739 | ||
|
|
59cf4112d2 | ||
|
|
5cfda2292f | ||
|
|
038b04d80a | ||
|
|
624bc85143 | ||
|
|
1f0ad823c9 | ||
|
|
29b6643bab | ||
|
|
a8e1368697 | ||
|
|
bea0be48b6 | ||
|
|
91d11cd050 | ||
|
|
9591ecddbe | ||
|
|
1568015de6 | ||
|
|
7ed067e680 | ||
|
|
4703f01cf4 | ||
|
|
d0a9f46888 | ||
|
|
23b269d5f9 | ||
|
|
11fd27ade7 | ||
|
|
65ac0a1a2b | ||
|
|
679004914f | ||
|
|
b88da9b0de | ||
|
|
a5ff796c20 | ||
|
|
d47339e274 | ||
|
|
06008b0444 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -8,3 +8,8 @@ test
|
|||||||
tags
|
tags
|
||||||
*.dylib
|
*.dylib
|
||||||
build/
|
build/
|
||||||
|
cJSON_test
|
||||||
|
cJSON_test_utils
|
||||||
|
libcjson.so.*
|
||||||
|
libcjson_utils.so.*
|
||||||
|
*.orig
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ include(GNUInstallDirs)
|
|||||||
project(cJSON C)
|
project(cJSON C)
|
||||||
|
|
||||||
set(PROJECT_VERSION_MAJOR 1)
|
set(PROJECT_VERSION_MAJOR 1)
|
||||||
set(PROJECT_VERSION_MINOR 0)
|
set(PROJECT_VERSION_MINOR 2)
|
||||||
set(PROJECT_VERSION_PATCH 0)
|
set(PROJECT_VERSION_PATCH 1)
|
||||||
set(CJSON_VERSION_SO 1)
|
set(CJSON_VERSION_SO 1)
|
||||||
set(CJSON_UTILS_VERSION_SO 1)
|
set(CJSON_UTILS_VERSION_SO 1)
|
||||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||||
|
|
||||||
option(ENABLE_CUSTOM_COMPILER_FLAGS ON)
|
option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags for Clang and GCC" ON)
|
||||||
if (ENABLE_CUSTOM_COMPILER_FLAGS)
|
if (ENABLE_CUSTOM_COMPILER_FLAGS)
|
||||||
if(("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang"))
|
if(("${CMAKE_C_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang"))
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89 -pedantic -Wall -Wextra -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ Contributors
|
|||||||
============
|
============
|
||||||
|
|
||||||
* [Ajay Bhargav](https://github.com/ajaybhargav)
|
* [Ajay Bhargav](https://github.com/ajaybhargav)
|
||||||
|
* [Alper Akcan](https://github.com/alperakcan)
|
||||||
* [Anton Sergeev](https://github.com/anton-sergeev)
|
* [Anton Sergeev](https://github.com/anton-sergeev)
|
||||||
* [Christian Schulze](https://github.com/ChristianSch)
|
* [Christian Schulze](https://github.com/ChristianSch)
|
||||||
* [Dave Gamble](https://github.com/DaveGamble)
|
* [Dave Gamble](https://github.com/DaveGamble)
|
||||||
@@ -13,8 +14,10 @@ Contributors
|
|||||||
* Ian Mobley
|
* Ian Mobley
|
||||||
* Irwan Djadjadi
|
* Irwan Djadjadi
|
||||||
* [IvanVoid](https://github.com/npi3pak)
|
* [IvanVoid](https://github.com/npi3pak)
|
||||||
|
* [Jiri Zouhar](https://github.com/loigu)
|
||||||
* [Jonathan Fether](https://github.com/jfether)
|
* [Jonathan Fether](https://github.com/jfether)
|
||||||
* [Kevin Branigan](https://github.com/kbranigan)
|
* [Kevin Branigan](https://github.com/kbranigan)
|
||||||
|
* [Kyle Chisholm](https://github.com/ChisholmKyle)
|
||||||
* [Linus Wallgren](https://github.com/ecksun)
|
* [Linus Wallgren](https://github.com/ecksun)
|
||||||
* [Max Bruckner](https://github.com/FSMaxB)
|
* [Max Bruckner](https://github.com/FSMaxB)
|
||||||
* Mike Pontillo
|
* Mike Pontillo
|
||||||
@@ -22,6 +25,8 @@ Contributors
|
|||||||
* [Rafael Leal Dias](https://github.com/rafaeldias)
|
* [Rafael Leal Dias](https://github.com/rafaeldias)
|
||||||
* [Rod Vagg](https://github.com/rvagg)
|
* [Rod Vagg](https://github.com/rvagg)
|
||||||
* [Roland Meertens](https://github.com/rmeertens)
|
* [Roland Meertens](https://github.com/rmeertens)
|
||||||
|
* [Romain Porte](https://github.com/MicroJoe)
|
||||||
|
* [Stephan Gatzka](https://github.com/gatzka)
|
||||||
* [Weston Schmidt](https://github.com/schmidtw)
|
* [Weston Schmidt](https://github.com/schmidtw)
|
||||||
|
|
||||||
And probably more people on [SourceForge](https://sourceforge.net/p/cjson/bugs/search/?q=status%3Aclosed-rejected+or+status%3Aclosed-out-of-date+or+status%3Awont-fix+or+status%3Aclosed-fixed+or+status%3Aclosed&page=0)
|
And probably more people on [SourceForge](https://sourceforge.net/p/cjson/bugs/search/?q=status%3Aclosed-rejected+or+status%3Aclosed-out-of-date+or+status%3Awont-fix+or+status%3Aclosed-fixed+or+status%3Aclosed&page=0)
|
||||||
|
|||||||
17
Makefile
17
Makefile
@@ -5,9 +5,12 @@ UTILS_LIBNAME = libcjson_utils
|
|||||||
CJSON_TEST = cJSON_test
|
CJSON_TEST = cJSON_test
|
||||||
UTILS_TEST = cJSON_test_utils
|
UTILS_TEST = cJSON_test_utils
|
||||||
|
|
||||||
|
CJSON_TEST_SRC = cJSON.c test.c
|
||||||
|
UTILS_TEST_SRC = cJSON.c cJSON_Utils.c test_utils.c
|
||||||
|
|
||||||
LDLIBS = -lm
|
LDLIBS = -lm
|
||||||
|
|
||||||
LIBVERSION = 1.0.0
|
LIBVERSION = 1.2.1
|
||||||
CJSON_SOVERSION = 1
|
CJSON_SOVERSION = 1
|
||||||
UTILS_SOVERSION = 1
|
UTILS_SOVERSION = 1
|
||||||
|
|
||||||
@@ -20,7 +23,7 @@ INSTALL_LIBRARY_PATH = $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH)
|
|||||||
|
|
||||||
INSTALL ?= cp -a
|
INSTALL ?= cp -a
|
||||||
|
|
||||||
R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings $(CFLAGS)
|
R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat $(CFLAGS)
|
||||||
|
|
||||||
uname := $(shell sh -c 'uname -s 2>/dev/null || echo false')
|
uname := $(shell sh -c 'uname -s 2>/dev/null || echo false')
|
||||||
|
|
||||||
@@ -62,15 +65,15 @@ test: tests
|
|||||||
./$(UTILS_TEST)
|
./$(UTILS_TEST)
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) -ansi -pedantic -c $(R_CFLAGS) $<
|
$(CC) -c $(R_CFLAGS) $<
|
||||||
|
|
||||||
#tests
|
#tests
|
||||||
#cJSON
|
#cJSON
|
||||||
$(CJSON_TEST): cJSON.c cJSON.h test.c
|
$(CJSON_TEST): $(CJSON_TEST_SRC) cJSON.h
|
||||||
$(CC) $^ -o $@ $(LDLIBS) -I.
|
$(CC) $(R_CFLAGS) $(CJSON_TEST_SRC) -o $@ $(LDLIBS) -I.
|
||||||
#cJSON_Utils
|
#cJSON_Utils
|
||||||
$(UTILS_TEST): cJSON.c cJSON.h test.c
|
$(UTILS_TEST): $(UTILS_TEST_SRC) cJSON.h cJSON_Utils.h
|
||||||
$(CC) $^ -o $@ $(LDLIBS) -I.
|
$(CC) $(R_CFLAGS) $(UTILS_TEST_SRC) -o $@ $(LDLIBS) -I.
|
||||||
|
|
||||||
#static libraries
|
#static libraries
|
||||||
#cJSON
|
#cJSON
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ make
|
|||||||
And install it with `make install` if you want. By default it installs the headers `/usr/local/include/cjson` and the libraries to `/usr/local/lib`. It also installs files for pkg-config to make it easier to detect and use an existing installation of CMake. And it installs CMake config files, that can be used by other CMake based projects to discover the library.
|
And install it with `make install` if you want. By default it installs the headers `/usr/local/include/cjson` and the libraries to `/usr/local/lib`. It also installs files for pkg-config to make it easier to detect and use an existing installation of CMake. And it installs CMake config files, that can be used by other CMake based projects to discover the library.
|
||||||
|
|
||||||
You can change the build process with a list of different options that you can pass to CMake. Turn them on with `On` and off with `Off`:
|
You can change the build process with a list of different options that you can pass to CMake. Turn them on with `On` and off with `Off`:
|
||||||
* `-DENABLE_CJSON_TESTS=On`: Enable building the tests. (on by default)
|
* `-DENABLE_CJSON_TEST=On`: Enable building the tests. (on by default)
|
||||||
* `-DENABLE_CJSON_UTILS=On`: Enable building cJSON_Utils. (off by default)
|
* `-DENABLE_CJSON_UTILS=On`: Enable building cJSON_Utils. (off by default)
|
||||||
* `-DENABLE_TARGET_EXPORT=On`: Enable the export of CMake targets. Turn off if it makes problems. (on by default)
|
* `-DENABLE_TARGET_EXPORT=On`: Enable the export of CMake targets. Turn off if it makes problems. (on by default)
|
||||||
* `-DENABLE_CUSTOM_COMPILER_FLAGS=On`: Enable custom compiler flags (currently for Clang and GCC). Turn off if it makes problems. (on by default)
|
* `-DENABLE_CUSTOM_COMPILER_FLAGS=On`: Enable custom compiler flags (currently for Clang and GCC). Turn off if it makes problems. (on by default)
|
||||||
@@ -90,7 +90,7 @@ If you are packaging cJSON for a distribution of Linux, you would probably take
|
|||||||
```
|
```
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DENABLE_CJSON_UTILS=On -DENABLE_CJSON_TESTS=Off -DCMAKE_INSTALL_PREFIX=/usr
|
cmake .. -DENABLE_CJSON_UTILS=On -DENABLE_CJSON_TEST=Off -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
make
|
make
|
||||||
make DESTDIR=$pkgdir install
|
make DESTDIR=$pkgdir install
|
||||||
```
|
```
|
||||||
|
|||||||
21
cJSON.h
21
cJSON.h
@@ -28,6 +28,14 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* project version */
|
||||||
|
#define CJSON_VERSION_MAJOR 1
|
||||||
|
#define CJSON_VERSION_MINOR 2
|
||||||
|
#define CJSON_VERSION_PATCH 1
|
||||||
|
|
||||||
|
/* returns the version of cJSON as a string */
|
||||||
|
extern const char* cJSON_Version(void);
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/* cJSON Types: */
|
/* cJSON Types: */
|
||||||
@@ -38,6 +46,7 @@ extern "C"
|
|||||||
#define cJSON_String (1 << 4)
|
#define cJSON_String (1 << 4)
|
||||||
#define cJSON_Array (1 << 5)
|
#define cJSON_Array (1 << 5)
|
||||||
#define cJSON_Object (1 << 6)
|
#define cJSON_Object (1 << 6)
|
||||||
|
#define cJSON_Raw (1 << 7) /* raw json */
|
||||||
|
|
||||||
#define cJSON_IsReference 256
|
#define cJSON_IsReference 256
|
||||||
#define cJSON_StringIsConst 512
|
#define cJSON_StringIsConst 512
|
||||||
@@ -54,7 +63,7 @@ typedef struct cJSON
|
|||||||
/* The type of the item, as above. */
|
/* The type of the item, as above. */
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
/* The item's string, if type==cJSON_String */
|
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||||
char *valuestring;
|
char *valuestring;
|
||||||
/* The item's number, if type==cJSON_Number */
|
/* The item's number, if type==cJSON_Number */
|
||||||
int valueint;
|
int valueint;
|
||||||
@@ -83,6 +92,8 @@ extern char *cJSON_Print(const cJSON *item);
|
|||||||
extern char *cJSON_PrintUnformatted(const cJSON *item);
|
extern char *cJSON_PrintUnformatted(const cJSON *item);
|
||||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||||
extern char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, int fmt);
|
extern char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, int fmt);
|
||||||
|
/* Render a cJSON entity to text using a buffer already allocated in memory with length buf_len. Returns 1 on success and 0 on failure. */
|
||||||
|
extern int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const int fmt);
|
||||||
/* Delete a cJSON entity and all subentities. */
|
/* Delete a cJSON entity and all subentities. */
|
||||||
extern void cJSON_Delete(cJSON *c);
|
extern void cJSON_Delete(cJSON *c);
|
||||||
|
|
||||||
@@ -103,6 +114,8 @@ extern cJSON *cJSON_CreateFalse(void);
|
|||||||
extern cJSON *cJSON_CreateBool(int b);
|
extern cJSON *cJSON_CreateBool(int b);
|
||||||
extern cJSON *cJSON_CreateNumber(double num);
|
extern cJSON *cJSON_CreateNumber(double num);
|
||||||
extern cJSON *cJSON_CreateString(const char *string);
|
extern cJSON *cJSON_CreateString(const char *string);
|
||||||
|
/* raw json */
|
||||||
|
extern cJSON *cJSON_CreateRaw(const char *raw);
|
||||||
extern cJSON *cJSON_CreateArray(void);
|
extern cJSON *cJSON_CreateArray(void);
|
||||||
extern cJSON *cJSON_CreateObject(void);
|
extern cJSON *cJSON_CreateObject(void);
|
||||||
|
|
||||||
@@ -115,7 +128,10 @@ extern cJSON *cJSON_CreateStringArray(const char **strings, int count);
|
|||||||
/* Append item to the specified array/object. */
|
/* Append item to the specified array/object. */
|
||||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
extern void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
extern void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
extern void cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object */
|
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||||
|
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||||
|
* writing to `item->string` */
|
||||||
|
extern void cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
@@ -150,6 +166,7 @@ extern void cJSON_Minify(char *json);
|
|||||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||||
|
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
|
||||||
|
|
||||||
/* 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,val) ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
|
#define cJSON_SetIntValue(object,val) ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
|
||||||
|
|||||||
110
cJSON_Utils.c
110
cJSON_Utils.c
@@ -6,13 +6,13 @@
|
|||||||
|
|
||||||
static char* cJSONUtils_strdup(const char* str)
|
static char* cJSONUtils_strdup(const char* str)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len = 0;
|
||||||
char* copy;
|
char *copy = NULL;
|
||||||
|
|
||||||
len = strlen(str) + 1;
|
len = strlen(str) + 1;
|
||||||
if (!(copy = (char*)malloc(len)))
|
if (!(copy = (char*)malloc(len)))
|
||||||
{
|
{
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(copy, str, len);
|
memcpy(copy, str, len);
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target)
|
|||||||
char *found = cJSONUtils_FindPointerFromObjectTo(obj, target);
|
char *found = cJSONUtils_FindPointerFromObjectTo(obj, target);
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
if (type == cJSON_Array)
|
if ((type & 0xFF) == cJSON_Array)
|
||||||
{
|
{
|
||||||
/* reserve enough memory for a 64 bit integer + '/' and '\0' */
|
/* reserve enough memory for a 64 bit integer + '/' and '\0' */
|
||||||
char *ret = (char*)malloc(strlen(found) + 23);
|
char *ret = (char*)malloc(strlen(found) + 23);
|
||||||
@@ -140,7 +140,7 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else if (type == cJSON_Object)
|
else if ((type & 0xFF) == cJSON_Object)
|
||||||
{
|
{
|
||||||
char *ret = (char*)malloc(strlen(found) + cJSONUtils_PointerEncodedstrlen(obj->string) + 2);
|
char *ret = (char*)malloc(strlen(found) + cJSONUtils_PointerEncodedstrlen(obj->string) + 2);
|
||||||
*ret = '/';
|
*ret = '/';
|
||||||
@@ -153,12 +153,12 @@ char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target)
|
|||||||
|
|
||||||
/* reached leaf of the tree, found nothing */
|
/* reached leaf of the tree, found nothing */
|
||||||
free(found);
|
free(found);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* not found */
|
/* not found */
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
|
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 */
|
/* follow path of the pointer */
|
||||||
while ((*pointer++ == '/') && object)
|
while ((*pointer++ == '/') && object)
|
||||||
{
|
{
|
||||||
if (object->type == cJSON_Array)
|
if ((object->type & 0xFF) == cJSON_Array)
|
||||||
{
|
{
|
||||||
int which = 0;
|
int which = 0;
|
||||||
/* parse array index */
|
/* parse array index */
|
||||||
@@ -177,11 +177,11 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
|
|||||||
if (*pointer && (*pointer != '/'))
|
if (*pointer && (*pointer != '/'))
|
||||||
{
|
{
|
||||||
/* not end of string or new path token */
|
/* not end of string or new path token */
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
object = cJSON_GetArrayItem(object, which);
|
object = cJSON_GetArrayItem(object, which);
|
||||||
}
|
}
|
||||||
else if (object->type == cJSON_Object)
|
else if ((object->type & 0xFF) == cJSON_Object)
|
||||||
{
|
{
|
||||||
object = object->child;
|
object = object->child;
|
||||||
/* GetObjectItem. */
|
/* GetObjectItem. */
|
||||||
@@ -197,7 +197,7 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +208,11 @@ cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
|
|||||||
static void cJSONUtils_InplaceDecodePointerString(char *string)
|
static void cJSONUtils_InplaceDecodePointerString(char *string)
|
||||||
{
|
{
|
||||||
char *s2 = string;
|
char *s2 = string;
|
||||||
|
|
||||||
|
if (string == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (; *string; s2++, string++)
|
for (; *string; s2++, string++)
|
||||||
{
|
{
|
||||||
*s2 = (*string != '~')
|
*s2 = (*string != '~')
|
||||||
@@ -222,32 +227,39 @@ static void cJSONUtils_InplaceDecodePointerString(char *string)
|
|||||||
|
|
||||||
static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path)
|
static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path)
|
||||||
{
|
{
|
||||||
char *parentptr = 0;
|
char *parentptr = NULL;
|
||||||
char *childptr = 0;
|
char *childptr = NULL;
|
||||||
cJSON *parent = 0;
|
cJSON *parent = NULL;
|
||||||
cJSON *ret = 0;
|
cJSON *ret = NULL;
|
||||||
|
|
||||||
/* copy path and split it in parent and child */
|
/* copy path and split it in parent and child */
|
||||||
parentptr = cJSONUtils_strdup(path);
|
parentptr = cJSONUtils_strdup(path);
|
||||||
childptr = strrchr(parentptr, '/'); /* last '/' */
|
if (parentptr == NULL) {
|
||||||
if (childptr)
|
return NULL;
|
||||||
{
|
|
||||||
/* split strings */
|
|
||||||
*childptr++ = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
childptr = strrchr(parentptr, '/'); /* last '/' */
|
||||||
|
if (childptr == NULL)
|
||||||
|
{
|
||||||
|
free(parentptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* split strings */
|
||||||
|
*childptr++ = '\0';
|
||||||
|
|
||||||
parent = cJSONUtils_GetPointer(object, parentptr);
|
parent = cJSONUtils_GetPointer(object, parentptr);
|
||||||
cJSONUtils_InplaceDecodePointerString(childptr);
|
cJSONUtils_InplaceDecodePointerString(childptr);
|
||||||
|
|
||||||
if (!parent)
|
if (!parent)
|
||||||
{
|
{
|
||||||
/* Couldn't find object to remove child from. */
|
/* 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));
|
ret = cJSON_DetachItemFromArray(parent, atoi(childptr));
|
||||||
}
|
}
|
||||||
else if (parent->type == cJSON_Object)
|
else if ((parent->type & 0xFF) == cJSON_Object)
|
||||||
{
|
{
|
||||||
ret = cJSON_DetachItemFromObject(parent, childptr);
|
ret = cJSON_DetachItemFromObject(parent, childptr);
|
||||||
}
|
}
|
||||||
@@ -259,12 +271,12 @@ static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path)
|
|||||||
|
|
||||||
static int cJSONUtils_Compare(cJSON *a, cJSON *b)
|
static int cJSONUtils_Compare(cJSON *a, cJSON *b)
|
||||||
{
|
{
|
||||||
if (a->type != b->type)
|
if ((a->type & 0xFF) != (b->type & 0xFF))
|
||||||
{
|
{
|
||||||
/* mismatched type. */
|
/* mismatched type. */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
switch (a->type)
|
switch (a->type & 0xFF)
|
||||||
{
|
{
|
||||||
case cJSON_Number:
|
case cJSON_Number:
|
||||||
/* numeric mismatch. */
|
/* numeric mismatch. */
|
||||||
@@ -290,7 +302,7 @@ static int cJSONUtils_Compare(cJSON *a, cJSON *b)
|
|||||||
b = b->child;
|
b = b->child;
|
||||||
while (a && b)
|
while (a && b)
|
||||||
{
|
{
|
||||||
int err;
|
int err = 0;
|
||||||
/* compare object keys */
|
/* compare object keys */
|
||||||
if (cJSONUtils_strcasecmp(a->string, b->string))
|
if (cJSONUtils_strcasecmp(a->string, b->string))
|
||||||
{
|
{
|
||||||
@@ -317,13 +329,13 @@ static int cJSONUtils_Compare(cJSON *a, cJSON *b)
|
|||||||
|
|
||||||
static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
|
static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
|
||||||
{
|
{
|
||||||
cJSON *op = 0;
|
cJSON *op = NULL;
|
||||||
cJSON *path = 0;
|
cJSON *path = NULL;
|
||||||
cJSON *value = 0;
|
cJSON *value = NULL;
|
||||||
cJSON *parent = 0;
|
cJSON *parent = NULL;
|
||||||
int opcode = 0;
|
int opcode = 0;
|
||||||
char *parentptr = 0;
|
char *parentptr = NULL;
|
||||||
char *childptr = 0;
|
char *childptr = NULL;
|
||||||
|
|
||||||
op = cJSON_GetObjectItem(patch, "op");
|
op = cJSON_GetObjectItem(patch, "op");
|
||||||
path = cJSON_GetObjectItem(patch, "path");
|
path = cJSON_GetObjectItem(patch, "path");
|
||||||
@@ -448,7 +460,7 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
|
|||||||
cJSON_Delete(value);
|
cJSON_Delete(value);
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
else if (parent->type == cJSON_Array)
|
else if ((parent->type & 0xFF) == cJSON_Array)
|
||||||
{
|
{
|
||||||
if (!strcmp(childptr, "-"))
|
if (!strcmp(childptr, "-"))
|
||||||
{
|
{
|
||||||
@@ -459,7 +471,7 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
|
|||||||
cJSON_InsertItemInArray(parent, atoi(childptr), value);
|
cJSON_InsertItemInArray(parent, atoi(childptr), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (parent->type == cJSON_Object)
|
else if ((parent->type & 0xFF) == cJSON_Object)
|
||||||
{
|
{
|
||||||
cJSON_DeleteItemFromObject(parent, childptr);
|
cJSON_DeleteItemFromObject(parent, childptr);
|
||||||
cJSON_AddItemToObject(parent, childptr, value);
|
cJSON_AddItemToObject(parent, childptr, value);
|
||||||
@@ -475,8 +487,8 @@ static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
|
|||||||
|
|
||||||
int cJSONUtils_ApplyPatches(cJSON *object, cJSON *patches)
|
int cJSONUtils_ApplyPatches(cJSON *object, cJSON *patches)
|
||||||
{
|
{
|
||||||
int err;
|
int err = 0;
|
||||||
if (patches->type != cJSON_Array)
|
if ((patches->type & 0xFF) != cJSON_Array)
|
||||||
{
|
{
|
||||||
/* malformed patches. */
|
/* malformed patches. */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -526,13 +538,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)
|
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);
|
cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (from->type)
|
switch ((from->type & 0xFF))
|
||||||
{
|
{
|
||||||
case cJSON_Number:
|
case cJSON_Number:
|
||||||
if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble))
|
if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble))
|
||||||
@@ -550,7 +562,7 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f
|
|||||||
|
|
||||||
case cJSON_Array:
|
case cJSON_Array:
|
||||||
{
|
{
|
||||||
int c;
|
int c = 0;
|
||||||
char *newpath = (char*)malloc(strlen(path) + 23); /* Allow space for 64bit int. */
|
char *newpath = (char*)malloc(strlen(path) + 23); /* Allow space for 64bit int. */
|
||||||
/* generate patches for all array elements that exist in "from" and "to" */
|
/* 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++)
|
for (c = 0, from = from->child, to = to->child; from && to; from = from->next, to = to->next, c++)
|
||||||
@@ -575,8 +587,8 @@ static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *f
|
|||||||
|
|
||||||
case cJSON_Object:
|
case cJSON_Object:
|
||||||
{
|
{
|
||||||
cJSON *a;
|
cJSON *a = NULL;
|
||||||
cJSON *b;
|
cJSON *b = NULL;
|
||||||
cJSONUtils_SortObject(from);
|
cJSONUtils_SortObject(from);
|
||||||
cJSONUtils_SortObject(to);
|
cJSONUtils_SortObject(to);
|
||||||
|
|
||||||
@@ -666,13 +678,13 @@ static cJSON *cJSONUtils_SortList(cJSON *list)
|
|||||||
if (second && second->prev)
|
if (second && second->prev)
|
||||||
{
|
{
|
||||||
/* Split the lists */
|
/* Split the lists */
|
||||||
second->prev->next = 0;
|
second->prev->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursively sort the sub-lists. */
|
/* Recursively sort the sub-lists. */
|
||||||
first = cJSONUtils_SortList(first);
|
first = cJSONUtils_SortList(first);
|
||||||
second = cJSONUtils_SortList(second);
|
second = cJSONUtils_SortList(second);
|
||||||
list = ptr = 0;
|
list = ptr = NULL;
|
||||||
|
|
||||||
while (first && second) /* Merge the sub-lists */
|
while (first && second) /* Merge the sub-lists */
|
||||||
{
|
{
|
||||||
@@ -740,14 +752,14 @@ void cJSONUtils_SortObject(cJSON *object)
|
|||||||
|
|
||||||
cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
|
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 */
|
/* scalar value, array or NULL, just duplicate */
|
||||||
cJSON_Delete(target);
|
cJSON_Delete(target);
|
||||||
return cJSON_Duplicate(patch, 1);
|
return cJSON_Duplicate(patch, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target || (target->type != cJSON_Object))
|
if (!target || ((target->type & 0xFF) != cJSON_Object))
|
||||||
{
|
{
|
||||||
cJSON_Delete(target);
|
cJSON_Delete(target);
|
||||||
target = cJSON_CreateObject();
|
target = cJSON_CreateObject();
|
||||||
@@ -756,7 +768,7 @@ cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
|
|||||||
patch = patch->child;
|
patch = patch->child;
|
||||||
while (patch)
|
while (patch)
|
||||||
{
|
{
|
||||||
if (patch->type == cJSON_NULL)
|
if ((patch->type & 0xFF) == cJSON_NULL)
|
||||||
{
|
{
|
||||||
/* NULL is the indicator to remove a value, see RFC7396 */
|
/* NULL is the indicator to remove a value, see RFC7396 */
|
||||||
cJSON_DeleteItemFromObject(target, patch->string);
|
cJSON_DeleteItemFromObject(target, patch->string);
|
||||||
@@ -773,13 +785,13 @@ cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
|
|||||||
|
|
||||||
cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
|
cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
|
||||||
{
|
{
|
||||||
cJSON *patch = 0;
|
cJSON *patch = NULL;
|
||||||
if (!to)
|
if (!to)
|
||||||
{
|
{
|
||||||
/* patch to delete everything */
|
/* patch to delete everything */
|
||||||
return cJSON_CreateNull();
|
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);
|
return cJSON_Duplicate(to, 1);
|
||||||
}
|
}
|
||||||
@@ -821,7 +833,7 @@ cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
|
|||||||
if (!patch->child)
|
if (!patch->child)
|
||||||
{
|
{
|
||||||
cJSON_Delete(patch);
|
cJSON_Delete(patch);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return patch;
|
return patch;
|
||||||
|
|||||||
155
test.c
155
test.c
@@ -22,13 +22,14 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
|
|
||||||
/* Parse text to JSON, then render back to text, and print! */
|
/* Parse text to JSON, then render back to text, and print! */
|
||||||
void doit(char *text)
|
static void doit(char *text)
|
||||||
{
|
{
|
||||||
char *out;
|
char *out = NULL;
|
||||||
cJSON *json;
|
cJSON *json = NULL;
|
||||||
|
|
||||||
json = cJSON_Parse(text);
|
json = cJSON_Parse(text);
|
||||||
if (!json)
|
if (!json)
|
||||||
@@ -44,12 +45,13 @@ void doit(char *text)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Read a file, parse, render back, etc. */
|
/* Read a file, parse, render back, etc. */
|
||||||
void dofile(char *filename)
|
static void dofile(char *filename)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f = NULL;
|
||||||
long len;
|
long len = 0;
|
||||||
char *data;
|
char *data = NULL;
|
||||||
|
|
||||||
/* open in read binary mode */
|
/* open in read binary mode */
|
||||||
f = fopen(filename,"rb");
|
f = fopen(filename,"rb");
|
||||||
@@ -59,6 +61,11 @@ void dofile(char *filename)
|
|||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
data = (char*)malloc(len + 1);
|
data = (char*)malloc(len + 1);
|
||||||
|
if (data == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to allocate memory.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
fread(data, 1, len, f);
|
fread(data, 1, len, f);
|
||||||
data[len] = '\0';
|
data[len] = '\0';
|
||||||
@@ -67,6 +74,7 @@ void dofile(char *filename)
|
|||||||
doit(data);
|
doit(data);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Used by some code below as an example datatype. */
|
/* Used by some code below as an example datatype. */
|
||||||
struct record
|
struct record
|
||||||
@@ -81,17 +89,83 @@ struct record
|
|||||||
const char *country;
|
const char *country;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Create a bunch of objects as demonstration. */
|
/* Create a bunch of objects as demonstration. */
|
||||||
void create_objects(void)
|
static int print_preallocated(cJSON *root)
|
||||||
|
{
|
||||||
|
/* declarations */
|
||||||
|
char *out = NULL;
|
||||||
|
char *buf = NULL;
|
||||||
|
char *buf_fail = NULL;
|
||||||
|
int len = 0;
|
||||||
|
int len_fail = 0;
|
||||||
|
|
||||||
|
/* formatted print */
|
||||||
|
out = cJSON_Print(root);
|
||||||
|
|
||||||
|
/* create buffer to succeed */
|
||||||
|
/* the extra 64 bytes are in case a floating point value is printed */
|
||||||
|
len = strlen(out) + 64;
|
||||||
|
buf = (char*)malloc(len);
|
||||||
|
if (buf == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to allocate memory.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create buffer to fail */
|
||||||
|
len_fail = strlen(out);
|
||||||
|
buf_fail = (char*)malloc(len_fail);
|
||||||
|
if (buf_fail == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to allocate memory.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print to buffer */
|
||||||
|
if (!cJSON_PrintPreallocated(root, buf, len, 1)) {
|
||||||
|
printf("cJSON_PrintPreallocated failed!\n");
|
||||||
|
if (strcmp(out, buf) != 0) {
|
||||||
|
printf("cJSON_PrintPreallocated not the same as cJSON_Print!\n");
|
||||||
|
printf("cJSON_Print result:\n%s\n", out);
|
||||||
|
printf("cJSON_PrintPreallocated result:\n%s\n", buf);
|
||||||
|
}
|
||||||
|
free(out);
|
||||||
|
free(buf_fail);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
printf("%s\n", buf);
|
||||||
|
|
||||||
|
/* force it to fail */
|
||||||
|
if (cJSON_PrintPreallocated(root, buf_fail, len_fail, 1)) {
|
||||||
|
printf("cJSON_PrintPreallocated failed to show error with insufficient memory!\n");
|
||||||
|
printf("cJSON_Print result:\n%s\n", out);
|
||||||
|
printf("cJSON_PrintPreallocated result:\n%s\n", buf_fail);
|
||||||
|
free(out);
|
||||||
|
free(buf_fail);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(out);
|
||||||
|
free(buf_fail);
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a bunch of objects as demonstration. */
|
||||||
|
static void create_objects(void)
|
||||||
{
|
{
|
||||||
/* declare a few. */
|
/* declare a few. */
|
||||||
cJSON *root;
|
cJSON *root = NULL;
|
||||||
cJSON *fmt;
|
cJSON *fmt = NULL;
|
||||||
cJSON *img;
|
cJSON *img = NULL;
|
||||||
cJSON *thm;
|
cJSON *thm = NULL;
|
||||||
cJSON *fld;
|
cJSON *fld = NULL;
|
||||||
char *out;
|
int i = 0;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Our "days of the week" array: */
|
/* Our "days of the week" array: */
|
||||||
const char *strings[7] =
|
const char *strings[7] =
|
||||||
@@ -152,21 +226,20 @@ void create_objects(void)
|
|||||||
cJSON_AddNumberToObject(fmt, "frame rate", 24);
|
cJSON_AddNumberToObject(fmt, "frame rate", 24);
|
||||||
|
|
||||||
/* Print to text */
|
/* Print to text */
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
/* Delete the cJSON */
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
/* print it */
|
|
||||||
printf("%s\n",out);
|
|
||||||
/* release the string */
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
/* Our "days of the week" array: */
|
/* Our "days of the week" array: */
|
||||||
root = cJSON_CreateStringArray(strings, 7);
|
root = cJSON_CreateStringArray(strings, 7);
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
/* Our matrix: */
|
/* Our matrix: */
|
||||||
root = cJSON_CreateArray();
|
root = cJSON_CreateArray();
|
||||||
@@ -177,11 +250,11 @@ void create_objects(void)
|
|||||||
|
|
||||||
/* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */
|
/* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
|
|
||||||
/* Our "gallery" item: */
|
/* Our "gallery" item: */
|
||||||
root = cJSON_CreateObject();
|
root = cJSON_CreateObject();
|
||||||
@@ -195,13 +268,13 @@ void create_objects(void)
|
|||||||
cJSON_AddStringToObject(thm, "Width", "100");
|
cJSON_AddStringToObject(thm, "Width", "100");
|
||||||
cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));
|
cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
/* Our array of "records": */
|
/* Our array of "records": */
|
||||||
|
|
||||||
root = cJSON_CreateArray();
|
root = cJSON_CreateArray();
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
@@ -218,17 +291,20 @@ void create_objects(void)
|
|||||||
|
|
||||||
/* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */
|
/* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
root = cJSON_CreateObject();
|
root = cJSON_CreateObject();
|
||||||
cJSON_AddNumberToObject(root, "number", 1.0 / zero);
|
cJSON_AddNumberToObject(root, "number", 1.0 / zero);
|
||||||
out = cJSON_Print(root);
|
|
||||||
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
@@ -306,6 +382,9 @@ int main(void)
|
|||||||
"</body>\n"
|
"</body>\n"
|
||||||
"</html>\n";
|
"</html>\n";
|
||||||
|
|
||||||
|
/* print the version */
|
||||||
|
printf("Version: %s\n", cJSON_Version());
|
||||||
|
|
||||||
/* Process each json textblock by parsing, then rebuilding: */
|
/* Process each json textblock by parsing, then rebuilding: */
|
||||||
doit(text1);
|
doit(text1);
|
||||||
doit(text2);
|
doit(text2);
|
||||||
|
|||||||
339
test_utils.c
339
test_utils.c
@@ -5,167 +5,202 @@
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/* Some variables */
|
/* Some variables */
|
||||||
char *temp = NULL;
|
char *temp = NULL;
|
||||||
char *patchtext = NULL;
|
char *patchtext = NULL;
|
||||||
char *patchedtext = NULL;
|
char *patchedtext = NULL;
|
||||||
|
|
||||||
int i;
|
int i = 0;
|
||||||
/* JSON Pointer tests: */
|
/* JSON Pointer tests: */
|
||||||
cJSON *root;
|
cJSON *root = NULL;
|
||||||
const char *json="{"
|
const char *json=
|
||||||
"\"foo\": [\"bar\", \"baz\"],"
|
"{"
|
||||||
"\"\": 0,"
|
"\"foo\": [\"bar\", \"baz\"],"
|
||||||
"\"a/b\": 1,"
|
"\"\": 0,"
|
||||||
"\"c%d\": 2,"
|
"\"a/b\": 1,"
|
||||||
"\"e^f\": 3,"
|
"\"c%d\": 2,"
|
||||||
"\"g|h\": 4,"
|
"\"e^f\": 3,"
|
||||||
"\"i\\\\j\": 5,"
|
"\"g|h\": 4,"
|
||||||
"\"k\\\"l\": 6,"
|
"\"i\\\\j\": 5,"
|
||||||
"\" \": 7,"
|
"\"k\\\"l\": 6,"
|
||||||
"\"m~n\": 8"
|
"\" \": 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\":{}}}"}};
|
|
||||||
|
|
||||||
|
|
||||||
/* Misc tests */
|
const char *tests[12] = {"","/foo","/foo/0","/","/a~1b","/c%d","/e^f","/g|h","/i\\j","/k\"l","/ ","/m~0n"};
|
||||||
int numbers[10]={0,1,2,3,4,5,6,7,8,9};
|
|
||||||
const char *random="QWERTYUIOPASDFGHJKLZXCVBNM";
|
/* JSON Apply Patch tests: */
|
||||||
char buf[2]={0,0},*before,*after;
|
const char *patches[15][3] =
|
||||||
cJSON *object,*nums,*num6,*sortme;
|
{
|
||||||
|
{"{ \"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\":{}}}"}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Misc tests */
|
||||||
printf("JSON Pointer Tests\n");
|
int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
root=cJSON_Parse(json);
|
const char *random = "QWERTYUIOPASDFGHJKLZXCVBNM";
|
||||||
for (i=0;i<12;i++)
|
char buf[2] = {0,0};
|
||||||
{
|
char *before = NULL;
|
||||||
char *output=cJSON_Print(cJSONUtils_GetPointer(root,tests[i]));
|
char *after = NULL;
|
||||||
printf("Test %d:\n%s\n\n",i+1,output);
|
cJSON *object = NULL;
|
||||||
free(output);
|
cJSON *nums = NULL;
|
||||||
}
|
cJSON *num6 = NULL;
|
||||||
cJSON_Delete(root);
|
cJSON *sortme = NULL;
|
||||||
|
|
||||||
|
|
||||||
printf("JSON Apply Patch Tests\n");
|
printf("JSON Pointer Tests\n");
|
||||||
for (i=0;i<15;i++)
|
root = cJSON_Parse(json);
|
||||||
{
|
for (i = 0; i < 12; i++)
|
||||||
cJSON *object=cJSON_Parse(patches[i][0]);
|
{
|
||||||
cJSON *patch=cJSON_Parse(patches[i][1]);
|
char *output = cJSON_Print(cJSONUtils_GetPointer(root, tests[i]));
|
||||||
int err=cJSONUtils_ApplyPatches(object,patch);
|
printf("Test %d:\n%s\n\n", i + 1, output);
|
||||||
char *output=cJSON_Print(object);
|
free(output);
|
||||||
printf("Test %d (err %d):\n%s\n\n",i+1,err,output);
|
}
|
||||||
free(output);cJSON_Delete(object);cJSON_Delete(patch);
|
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 Apply Patch Tests\n");
|
||||||
printf("JSON Pointer construct\n");
|
for (i = 0; i < 15; i++)
|
||||||
object=cJSON_CreateObject();
|
{
|
||||||
nums=cJSON_CreateIntArray(numbers,10);
|
cJSON *object_to_be_patched = cJSON_Parse(patches[i][0]);
|
||||||
num6=cJSON_GetArrayItem(nums,6);
|
cJSON *patch = cJSON_Parse(patches[i][1]);
|
||||||
cJSON_AddItemToObject(object,"numbers",nums);
|
int err = cJSONUtils_ApplyPatches(object_to_be_patched, patch);
|
||||||
temp=cJSONUtils_FindPointerFromObjectTo(object,num6);
|
char *output = cJSON_Print(object_to_be_patched);
|
||||||
printf("Pointer: [%s]\n",temp);
|
printf("Test %d (err %d):\n%s\n\n", i + 1, err, output);
|
||||||
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: */
|
free(output);
|
||||||
sortme=cJSON_CreateObject();
|
cJSON_Delete(object_to_be_patched);
|
||||||
for (i=0;i<26;i++)
|
cJSON_Delete(patch);
|
||||||
{
|
}
|
||||||
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);
|
/* JSON Generate Patch tests: */
|
||||||
}
|
printf("JSON Generate Patch Tests\n");
|
||||||
|
for (i = 0; i < 15; i++)
|
||||||
/* Generate Merge tests: */
|
{
|
||||||
for (i=0;i<15;i++)
|
cJSON *from;
|
||||||
{
|
cJSON *to;
|
||||||
cJSON *from=cJSON_Parse(merges[i][0]);
|
cJSON *patch;
|
||||||
cJSON *to=cJSON_Parse(merges[i][2]);
|
char *out;
|
||||||
cJSON *patch=cJSONUtils_GenerateMergePatch(from,to);
|
if (!strlen(patches[i][2]))
|
||||||
from=cJSONUtils_MergePatch(from,patch);
|
{
|
||||||
patchtext=cJSON_PrintUnformatted(patch);
|
continue;
|
||||||
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");
|
from = cJSON_Parse(patches[i][0]);
|
||||||
cJSON_Delete(from);cJSON_Delete(to);cJSON_Delete(patch);free(patchtext);free(patchedtext);
|
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_to_be_merged = cJSON_Parse(merges[i][0]);
|
||||||
|
cJSON *patch = cJSON_Parse(merges[i][1]);
|
||||||
|
char *before_merge = cJSON_PrintUnformatted(object_to_be_merged);
|
||||||
|
patchtext = cJSON_PrintUnformatted(patch);
|
||||||
|
printf("Before: [%s] -> [%s] = ", before_merge, patchtext);
|
||||||
|
object_to_be_merged = cJSONUtils_MergePatch(object_to_be_merged, patch);
|
||||||
|
after = cJSON_PrintUnformatted(object_to_be_merged);
|
||||||
|
printf("[%s] vs [%s] (%s)\n", after, merges[i][2], strcmp(after, merges[i][2]) ? "FAIL" : "OK");
|
||||||
|
|
||||||
|
free(before_merge);
|
||||||
|
free(patchtext);
|
||||||
|
free(after);
|
||||||
|
cJSON_Delete(object_to_be_merged);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user