Update the latest cJSON library, resolve calling cJSON_ Print returned a failed problem.
This commit is contained in:
@@ -28,10 +28,60 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||||
|
#define __WINDOWS__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
|
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||||
|
|
||||||
|
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||||
|
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||||
|
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||||
|
|
||||||
|
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||||
|
|
||||||
|
setting default visibility to hidden by adding
|
||||||
|
-fvisibility=hidden (for gcc)
|
||||||
|
or
|
||||||
|
-xldscope=hidden (for sun cc)
|
||||||
|
to CFLAGS
|
||||||
|
|
||||||
|
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CJSON_CDECL __cdecl
|
||||||
|
#define CJSON_STDCALL __stdcall
|
||||||
|
|
||||||
|
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||||
|
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_EXPORT_SYMBOLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CJSON_HIDE_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||||
|
#endif
|
||||||
|
#else /* !__WINDOWS__ */
|
||||||
|
#define CJSON_CDECL
|
||||||
|
#define CJSON_STDCALL
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||||
|
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||||
|
#else
|
||||||
|
#define CJSON_PUBLIC(type) type
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* project version */
|
/* project version */
|
||||||
#define CJSON_VERSION_MAJOR 1
|
#define CJSON_VERSION_MAJOR 1
|
||||||
#define CJSON_VERSION_MINOR 7
|
#define CJSON_VERSION_MINOR 7
|
||||||
#define CJSON_VERSION_PATCH 1
|
#define CJSON_VERSION_PATCH 15
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -74,55 +124,13 @@ typedef struct cJSON
|
|||||||
|
|
||||||
typedef struct cJSON_Hooks
|
typedef struct cJSON_Hooks
|
||||||
{
|
{
|
||||||
void *(*malloc_fn)(size_t sz);
|
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||||
void (*free_fn)(void *ptr);
|
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||||
|
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||||
} cJSON_Hooks;
|
} cJSON_Hooks;
|
||||||
|
|
||||||
typedef int cJSON_bool;
|
typedef int cJSON_bool;
|
||||||
|
|
||||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
|
||||||
#define __WINDOWS__
|
|
||||||
#endif
|
|
||||||
#ifdef __WINDOWS__
|
|
||||||
|
|
||||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
|
|
||||||
|
|
||||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
|
||||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
|
||||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
|
||||||
|
|
||||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
|
||||||
|
|
||||||
setting default visibility to hidden by adding
|
|
||||||
-fvisibility=hidden (for gcc)
|
|
||||||
or
|
|
||||||
-xldscope=hidden (for sun cc)
|
|
||||||
to CFLAGS
|
|
||||||
|
|
||||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
|
||||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
|
||||||
#define CJSON_EXPORT_SYMBOLS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CJSON_HIDE_SYMBOLS)
|
|
||||||
#define CJSON_PUBLIC(type) type __stdcall
|
|
||||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
|
||||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
|
|
||||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
|
||||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
|
|
||||||
#endif
|
|
||||||
#else /* !WIN32 */
|
|
||||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
|
||||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
|
||||||
#else
|
|
||||||
#define CJSON_PUBLIC(type) type
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||||
* This is to prevent stack overflows. */
|
* This is to prevent stack overflows. */
|
||||||
#ifndef CJSON_NESTING_LIMIT
|
#ifndef CJSON_NESTING_LIMIT
|
||||||
@@ -138,9 +146,11 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
|||||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
|
||||||
/* Render a cJSON entity to text for transfer/storage. */
|
/* Render a cJSON entity to text for transfer/storage. */
|
||||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||||
@@ -152,11 +162,11 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON
|
|||||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||||
/* Delete a cJSON entity and all subentities. */
|
/* Delete a cJSON entity and all subentities. */
|
||||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||||
|
|
||||||
/* Returns the number of items in an array (or object). */
|
/* Returns the number of items in an array (or object). */
|
||||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||||
/* Get item "string" from object. Case insensitive. */
|
/* Get item "string" from object. Case insensitive. */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||||
@@ -165,8 +175,9 @@ CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *st
|
|||||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||||
|
|
||||||
/* Check if the item is a string and return its valuestring */
|
/* Check item type and return its value */
|
||||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||||
|
|
||||||
/* These functions check the type of an item */
|
/* These functions check the type of an item */
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||||
@@ -195,29 +206,30 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
|||||||
/* Create a string where valuestring references a string so
|
/* Create a string where valuestring references a string so
|
||||||
* it will not be freed by cJSON_Delete */
|
* it will not be freed by cJSON_Delete */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||||
/* Create an object/arrray that only references it's elements so
|
/* Create an object/array that only references it's elements so
|
||||||
* they will not be freed by cJSON_Delete */
|
* they will not be freed by cJSON_Delete */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||||
|
|
||||||
/* These utilities create an Array of count items. */
|
/* These utilities create an Array of count items.
|
||||||
|
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||||
|
|
||||||
/* Append item to the specified array/object. */
|
/* Append item to the specified array/object. */
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(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
|
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||||
* writing to `item->string` */
|
* writing to `item->string` */
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
CJSON_PUBLIC(cJSON_bool) 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. */
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
|
||||||
/* Remove/Detatch items from Arrays/Objects. */
|
/* Remove/Detach items from Arrays/Objects. */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||||
@@ -227,22 +239,24 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
|
|||||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
|
||||||
/* Update array items. */
|
/* Update array items. */
|
||||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
|
||||||
/* Duplicate a cJSON item */
|
/* Duplicate a cJSON item */
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||||
|
|
||||||
|
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||||
|
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||||
|
* but should point to a readable and writable address area. */
|
||||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||||
|
|
||||||
/* Helper functions for creating and adding items to an object at the same time.
|
/* Helper functions for creating and adding items to an object at the same time.
|
||||||
@@ -262,6 +276,15 @@ CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * c
|
|||||||
/* helper for the cJSON_SetNumberValue macro */
|
/* helper for the cJSON_SetNumberValue macro */
|
||||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||||
|
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||||
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||||
|
|
||||||
|
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
|
||||||
|
#define cJSON_SetBoolValue(object, boolValue) ( \
|
||||||
|
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
|
||||||
|
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
|
||||||
|
cJSON_Invalid\
|
||||||
|
)
|
||||||
|
|
||||||
/* Macro for iterating over an array or object */
|
/* Macro for iterating over an array or object */
|
||||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||||
|
@@ -22,8 +22,6 @@
|
|||||||
|
|
||||||
/* cJSON */
|
/* cJSON */
|
||||||
/* JSON parser in C. */
|
/* JSON parser in C. */
|
||||||
#define _MSC_VER 1900
|
|
||||||
#undef _MSC_VER
|
|
||||||
|
|
||||||
/* disable warnings about old C89 functions in MSVC */
|
/* disable warnings about old C89 functions in MSVC */
|
||||||
#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
|
#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
|
||||||
@@ -43,12 +41,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <float.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <float.h>
|
||||||
#include "cJSON.h"
|
|
||||||
#include <tos_k.h>
|
|
||||||
|
|
||||||
#ifdef ENABLE_LOCALES
|
#ifdef ENABLE_LOCALES
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
@@ -61,12 +56,36 @@
|
|||||||
#pragma GCC visibility pop
|
#pragma GCC visibility pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "cJSON.h"
|
||||||
|
#include <tos_k.h>
|
||||||
|
|
||||||
/* define our own boolean type */
|
/* define our own boolean type */
|
||||||
|
#ifdef true
|
||||||
|
#undef true
|
||||||
|
#endif
|
||||||
#define true ((cJSON_bool)1)
|
#define true ((cJSON_bool)1)
|
||||||
|
|
||||||
|
#ifdef false
|
||||||
|
#undef false
|
||||||
|
#endif
|
||||||
#define false ((cJSON_bool)0)
|
#define false ((cJSON_bool)0)
|
||||||
|
|
||||||
|
/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */
|
||||||
|
#ifndef isinf
|
||||||
|
#define isinf(d) (isnan((d - d)) && !isnan(d))
|
||||||
|
#endif
|
||||||
|
#ifndef isnan
|
||||||
|
#define isnan(d) (d != d)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NAN
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define NAN sqrt(-1.0)
|
||||||
|
#else
|
||||||
|
#define NAN 0.0/0.0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const unsigned char *json;
|
const unsigned char *json;
|
||||||
size_t position;
|
size_t position;
|
||||||
@@ -78,16 +97,28 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
|
|||||||
return (const char*) (global_error.json + global_error.position);
|
return (const char*) (global_error.json + global_error.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) {
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
|
||||||
if (!cJSON_IsString(item)) {
|
{
|
||||||
|
if (!cJSON_IsString(item))
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return item->valuestring;
|
return item->valuestring;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
|
||||||
|
{
|
||||||
|
if (!cJSON_IsNumber(item))
|
||||||
|
{
|
||||||
|
return (double) NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item->valuedouble;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
|
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
|
||||||
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 1)
|
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15)
|
||||||
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
|
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -125,34 +156,37 @@ static int case_insensitive_strcmp(const unsigned char *string1, const unsigned
|
|||||||
|
|
||||||
typedef struct internal_hooks
|
typedef struct internal_hooks
|
||||||
{
|
{
|
||||||
void *(*allocate)(size_t size);
|
void *(CJSON_CDECL *allocate)(size_t size);
|
||||||
void (*deallocate)(void *pointer);
|
void (CJSON_CDECL *deallocate)(void *pointer);
|
||||||
void *(*reallocate)(void *pointer, size_t size);
|
void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
|
||||||
} internal_hooks;
|
} internal_hooks;
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
|
/* work around MSVC error C2322: '...' address of dllimport '...' is not static */
|
||||||
static void *internal_malloc(size_t size)
|
static void * CJSON_CDECL internal_malloc(size_t size)
|
||||||
{
|
{
|
||||||
//return malloc(size);
|
//return malloc(size);
|
||||||
return tos_mmheap_alloc(size);
|
return tos_mmheap_alloc(size);
|
||||||
}
|
}
|
||||||
static void internal_free(void *pointer)
|
static void CJSON_CDECL internal_free(void *pointer)
|
||||||
{
|
{
|
||||||
//free(pointer);
|
//free(pointer);
|
||||||
tos_mmheap_free(pointer);
|
tos_mmheap_free(pointer);
|
||||||
}
|
}
|
||||||
static void *internal_realloc(void *pointer, size_t size)
|
static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
|
||||||
{
|
{
|
||||||
//return realloc(pointer, size);
|
//return realloc(pointer, size);
|
||||||
return tos_mmheap_realloc(pointer,size);
|
return tos_mmheap_realloc(pointer,size);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define internal_malloc tos_mmheap_alloc
|
#define internal_malloc tos_mmheap_alloc
|
||||||
#define internal_free tos_mmheap_free
|
#define internal_free tos_mmheap_free
|
||||||
#define internal_realloc tos_mmheap_realloc
|
#define internal_realloc tos_mmheap_realloc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* strlen of character literals resolved at compile time */
|
||||||
|
#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
|
||||||
|
|
||||||
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
|
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
|
||||||
|
|
||||||
static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
|
static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
|
||||||
@@ -333,7 +367,7 @@ loop_end:
|
|||||||
{
|
{
|
||||||
item->valueint = INT_MAX;
|
item->valueint = INT_MAX;
|
||||||
}
|
}
|
||||||
else if (number <= INT_MIN)
|
else if (number <= (double)INT_MIN)
|
||||||
{
|
{
|
||||||
item->valueint = INT_MIN;
|
item->valueint = INT_MIN;
|
||||||
}
|
}
|
||||||
@@ -355,7 +389,7 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
|||||||
{
|
{
|
||||||
object->valueint = INT_MAX;
|
object->valueint = INT_MAX;
|
||||||
}
|
}
|
||||||
else if (number <= INT_MIN)
|
else if (number <= (double)INT_MIN)
|
||||||
{
|
{
|
||||||
object->valueint = INT_MIN;
|
object->valueint = INT_MIN;
|
||||||
}
|
}
|
||||||
@@ -367,6 +401,33 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
|||||||
return object->valuedouble = number;
|
return object->valuedouble = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
||||||
|
{
|
||||||
|
char *copy = NULL;
|
||||||
|
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
|
||||||
|
if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (strlen(valuestring) <= strlen(object->valuestring))
|
||||||
|
{
|
||||||
|
strcpy(object->valuestring, valuestring);
|
||||||
|
return object->valuestring;
|
||||||
|
}
|
||||||
|
copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks);
|
||||||
|
if (copy == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (object->valuestring != NULL)
|
||||||
|
{
|
||||||
|
cJSON_free(object->valuestring);
|
||||||
|
}
|
||||||
|
object->valuestring = copy;
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
@@ -454,10 +515,8 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (newbuffer)
|
|
||||||
{
|
memcpy(newbuffer, p->buffer, p->offset + 1);
|
||||||
memcpy(newbuffer, p->buffer, p->offset + 1);
|
|
||||||
}
|
|
||||||
p->hooks.deallocate(p->buffer);
|
p->hooks.deallocate(p->buffer);
|
||||||
}
|
}
|
||||||
p->length = newsize;
|
p->length = newsize;
|
||||||
@@ -479,6 +538,13 @@ static void update_offset(printbuffer * const buffer)
|
|||||||
buffer->offset += strlen((const char*)buffer_pointer);
|
buffer->offset += strlen((const char*)buffer_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* securely comparison of floating-point variables */
|
||||||
|
static cJSON_bool compare_double(double a, double b)
|
||||||
|
{
|
||||||
|
double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
|
||||||
|
return (fabs(a - b) <= maxVal * DBL_EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
/* Render the number nicely from the given item into a string. */
|
/* Render the number nicely from the given item into a string. */
|
||||||
static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
|
static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
|
||||||
{
|
{
|
||||||
@@ -486,9 +552,9 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
|||||||
double d = item->valuedouble;
|
double d = item->valuedouble;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
unsigned char number_buffer[26]; /* temporary buffer to print the number into */
|
unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */
|
||||||
unsigned char decimal_point = get_decimal_point();
|
unsigned char decimal_point = get_decimal_point();
|
||||||
double test;
|
double test = 0.0;
|
||||||
|
|
||||||
if (output_buffer == NULL)
|
if (output_buffer == NULL)
|
||||||
{
|
{
|
||||||
@@ -496,24 +562,28 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This checks for NaN and Infinity */
|
/* This checks for NaN and Infinity */
|
||||||
if ((d * 0) != 0)
|
if (isnan(d) || isinf(d))
|
||||||
{
|
{
|
||||||
length = sprintf((char*)number_buffer, "null");
|
length = sprintf((char*)number_buffer, "null");
|
||||||
}
|
}
|
||||||
|
else if(d == (double)item->valueint)
|
||||||
|
{
|
||||||
|
length = sprintf((char*)number_buffer, "%d", item->valueint);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
|
||||||
length = sprintf((char*)number_buffer, "%1.15g", d);
|
length = sprintf((char*)number_buffer, "%1.15g", d);
|
||||||
|
|
||||||
/* Check whether the original double can be recovered */
|
/* Check whether the original double can be recovered */
|
||||||
if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d))
|
if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
|
||||||
{
|
{
|
||||||
/* If not, print with 17 decimal places of precision */
|
/* If not, print with 17 decimal places of precision */
|
||||||
length = sprintf((char*)number_buffer, "%1.17g", d);
|
length = sprintf((char*)number_buffer, "%1.17g", d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sprintf failed or buffer overrun occured */
|
/* sprintf failed or buffer overrun occurred */
|
||||||
if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
|
if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -976,6 +1046,11 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cannot_access_at_index(buffer, 0))
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
|
while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
|
||||||
{
|
{
|
||||||
buffer->offset++;
|
buffer->offset++;
|
||||||
@@ -1005,8 +1080,23 @@ static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse an object - create a new root, and populate. */
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
|
||||||
|
{
|
||||||
|
size_t buffer_length;
|
||||||
|
|
||||||
|
if (NULL == value)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adding null character size due to require_null_terminated. */
|
||||||
|
buffer_length = strlen(value) + sizeof("");
|
||||||
|
|
||||||
|
return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse an object - create a new root, and populate. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)
|
||||||
{
|
{
|
||||||
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
|
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
|
||||||
cJSON *item = NULL;
|
cJSON *item = NULL;
|
||||||
@@ -1015,13 +1105,13 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return
|
|||||||
global_error.json = NULL;
|
global_error.json = NULL;
|
||||||
global_error.position = 0;
|
global_error.position = 0;
|
||||||
|
|
||||||
if (value == NULL)
|
if (value == NULL || 0 == buffer_length)
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.content = (const unsigned char*)value;
|
buffer.content = (const unsigned char*)value;
|
||||||
buffer.length = strlen((const char*)value) + sizeof("");
|
buffer.length = buffer_length;
|
||||||
buffer.offset = 0;
|
buffer.offset = 0;
|
||||||
buffer.hooks = global_hooks;
|
buffer.hooks = global_hooks;
|
||||||
|
|
||||||
@@ -1091,7 +1181,12 @@ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
|
|||||||
return cJSON_ParseWithOpts(value, 0, 0);
|
return cJSON_ParseWithOpts(value, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define cjson_min(a, b) ((a < b) ? a : b)
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length)
|
||||||
|
{
|
||||||
|
return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
|
static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
|
||||||
{
|
{
|
||||||
@@ -1122,10 +1217,10 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
|
|||||||
if (hooks->reallocate != NULL)
|
if (hooks->reallocate != NULL)
|
||||||
{
|
{
|
||||||
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
|
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
|
||||||
buffer->buffer = NULL;
|
|
||||||
if (printed == NULL) {
|
if (printed == NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
buffer->buffer = NULL;
|
||||||
}
|
}
|
||||||
else /* otherwise copy the JSON over to a new buffer */
|
else /* otherwise copy the JSON over to a new buffer */
|
||||||
{
|
{
|
||||||
@@ -1198,20 +1293,20 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON
|
|||||||
return (char*)p.buffer;
|
return (char*)p.buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt)
|
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)
|
||||||
{
|
{
|
||||||
printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
|
printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
|
||||||
|
|
||||||
if ((len < 0) || (buf == NULL))
|
if ((length < 0) || (buffer == NULL))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.buffer = (unsigned char*)buf;
|
p.buffer = (unsigned char*)buffer;
|
||||||
p.length = (size_t)len;
|
p.length = (size_t)length;
|
||||||
p.offset = 0;
|
p.offset = 0;
|
||||||
p.noalloc = true;
|
p.noalloc = true;
|
||||||
p.format = fmt;
|
p.format = format;
|
||||||
p.hooks = global_hooks;
|
p.hooks = global_hooks;
|
||||||
|
|
||||||
return print_value(item, &p);
|
return print_value(item, &p);
|
||||||
@@ -1319,10 +1414,6 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp
|
|||||||
size_t raw_length = 0;
|
size_t raw_length = 0;
|
||||||
if (item->valuestring == NULL)
|
if (item->valuestring == NULL)
|
||||||
{
|
{
|
||||||
if (!output_buffer->noalloc)
|
|
||||||
{
|
|
||||||
output_buffer->hooks.deallocate(output_buffer->buffer);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1428,6 +1519,10 @@ static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buf
|
|||||||
success:
|
success:
|
||||||
input_buffer->depth--;
|
input_buffer->depth--;
|
||||||
|
|
||||||
|
if (head != NULL) {
|
||||||
|
head->prev = current_item;
|
||||||
|
}
|
||||||
|
|
||||||
item->type = cJSON_Array;
|
item->type = cJSON_Array;
|
||||||
item->child = head;
|
item->child = head;
|
||||||
|
|
||||||
@@ -1568,7 +1663,7 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
|
|||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
if (!parse_string(current_item, input_buffer))
|
if (!parse_string(current_item, input_buffer))
|
||||||
{
|
{
|
||||||
goto fail; /* faile to parse name */
|
goto fail; /* failed to parse name */
|
||||||
}
|
}
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
|
|
||||||
@@ -1600,6 +1695,10 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
|
|||||||
success:
|
success:
|
||||||
input_buffer->depth--;
|
input_buffer->depth--;
|
||||||
|
|
||||||
|
if (head != NULL) {
|
||||||
|
head->prev = current_item;
|
||||||
|
}
|
||||||
|
|
||||||
item->type = cJSON_Object;
|
item->type = cJSON_Object;
|
||||||
item->child = head;
|
item->child = head;
|
||||||
|
|
||||||
@@ -1688,7 +1787,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
|
|||||||
update_offset(output_buffer);
|
update_offset(output_buffer);
|
||||||
|
|
||||||
/* print comma if not last */
|
/* print comma if not last */
|
||||||
length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0));
|
length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
|
||||||
output_pointer = ensure(output_buffer, length + 1);
|
output_pointer = ensure(output_buffer, length + 1);
|
||||||
if (output_pointer == NULL)
|
if (output_pointer == NULL)
|
||||||
{
|
{
|
||||||
@@ -1794,7 +1893,7 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam
|
|||||||
current_element = object->child;
|
current_element = object->child;
|
||||||
if (case_sensitive)
|
if (case_sensitive)
|
||||||
{
|
{
|
||||||
while ((current_element != NULL) && (strcmp(name, current_element->string) != 0))
|
while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
|
||||||
{
|
{
|
||||||
current_element = current_element->next;
|
current_element = current_element->next;
|
||||||
}
|
}
|
||||||
@@ -1807,6 +1906,10 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((current_element == NULL) || (current_element->string == NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return current_element;
|
return current_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1858,35 +1961,39 @@ static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
|
|||||||
{
|
{
|
||||||
cJSON *child = NULL;
|
cJSON *child = NULL;
|
||||||
|
|
||||||
if ((item == NULL) || (array == NULL))
|
if ((item == NULL) || (array == NULL) || (array == item))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
child = array->child;
|
child = array->child;
|
||||||
|
/*
|
||||||
|
* To find the last item in array quickly, we use prev in array
|
||||||
|
*/
|
||||||
if (child == NULL)
|
if (child == NULL)
|
||||||
{
|
{
|
||||||
/* list is empty, start new one */
|
/* list is empty, start new one */
|
||||||
array->child = item;
|
array->child = item;
|
||||||
|
item->prev = item;
|
||||||
|
item->next = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* append to the end */
|
/* append to the end */
|
||||||
while (child->next)
|
if (child->prev)
|
||||||
{
|
{
|
||||||
child = child->next;
|
suffix_object(child->prev, item);
|
||||||
|
array->child->prev = item;
|
||||||
}
|
}
|
||||||
suffix_object(child, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add item to array/object. */
|
/* Add item to array/object. */
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
|
||||||
{
|
{
|
||||||
add_item_to_array(array, item);
|
return add_item_to_array(array, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
|
#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
|
||||||
@@ -1907,65 +2014,70 @@ static void* cast_away_const(const void* string)
|
|||||||
|
|
||||||
static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
|
static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key)
|
||||||
{
|
{
|
||||||
if ((object == NULL) || (string == NULL) || (item == NULL))
|
char *new_key = NULL;
|
||||||
|
int new_type = cJSON_Invalid;
|
||||||
|
|
||||||
|
if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (constant_key)
|
||||||
|
{
|
||||||
|
new_key = (char*)cast_away_const(string);
|
||||||
|
new_type = item->type | cJSON_StringIsConst;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
|
||||||
|
if (new_key == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_type = item->type & ~cJSON_StringIsConst;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
|
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
|
||||||
{
|
{
|
||||||
hooks->deallocate(item->string);
|
hooks->deallocate(item->string);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constant_key)
|
item->string = new_key;
|
||||||
{
|
item->type = new_type;
|
||||||
item->string = (char*)cast_away_const(string);
|
|
||||||
item->type |= cJSON_StringIsConst;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
|
|
||||||
if (key == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
item->string = key;
|
|
||||||
item->type &= ~cJSON_StringIsConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
return add_item_to_array(object, item);
|
return add_item_to_array(object, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
|
||||||
{
|
{
|
||||||
add_item_to_object(object, string, item, &global_hooks, false);
|
return add_item_to_object(object, string, item, &global_hooks, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add an item to an object with constant string as key */
|
/* Add an item to an object with constant string as key */
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
|
||||||
{
|
{
|
||||||
add_item_to_object(object, string, item, &global_hooks, true);
|
return add_item_to_object(object, string, item, &global_hooks, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
|
||||||
{
|
{
|
||||||
if (array == NULL)
|
if (array == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item_to_array(array, create_reference(item, &global_hooks));
|
return add_item_to_array(array, create_reference(item, &global_hooks));
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
|
||||||
{
|
{
|
||||||
if ((object == NULL) || (string == NULL))
|
if ((object == NULL) || (string == NULL))
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
|
return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
|
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
|
||||||
@@ -2083,7 +2195,7 @@ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const it
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->prev != NULL)
|
if (item != parent->child)
|
||||||
{
|
{
|
||||||
/* not the first element */
|
/* not the first element */
|
||||||
item->prev->next = item->next;
|
item->prev->next = item->next;
|
||||||
@@ -2099,6 +2211,12 @@ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const it
|
|||||||
/* first element */
|
/* first element */
|
||||||
parent->child = item->next;
|
parent->child = item->next;
|
||||||
}
|
}
|
||||||
|
else if (item->next == NULL)
|
||||||
|
{
|
||||||
|
/* last element */
|
||||||
|
parent->child->prev = item->prev;
|
||||||
|
}
|
||||||
|
|
||||||
/* make sure the detached item doesn't point anywhere anymore */
|
/* make sure the detached item doesn't point anywhere anymore */
|
||||||
item->prev = NULL;
|
item->prev = NULL;
|
||||||
item->next = NULL;
|
item->next = NULL;
|
||||||
@@ -2146,20 +2264,19 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Replace array/object items with new ones. */
|
/* Replace array/object items with new ones. */
|
||||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
|
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
|
||||||
{
|
{
|
||||||
cJSON *after_inserted = NULL;
|
cJSON *after_inserted = NULL;
|
||||||
|
|
||||||
if (which < 0)
|
if (which < 0)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
after_inserted = get_array_item(array, (size_t)which);
|
after_inserted = get_array_item(array, (size_t)which);
|
||||||
if (after_inserted == NULL)
|
if (after_inserted == NULL)
|
||||||
{
|
{
|
||||||
add_item_to_array(array, newitem);
|
return add_item_to_array(array, newitem);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newitem->next = after_inserted;
|
newitem->next = after_inserted;
|
||||||
@@ -2173,6 +2290,7 @@ CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newit
|
|||||||
{
|
{
|
||||||
newitem->prev->next = newitem;
|
newitem->prev->next = newitem;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
|
||||||
@@ -2194,14 +2312,28 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON
|
|||||||
{
|
{
|
||||||
replacement->next->prev = replacement;
|
replacement->next->prev = replacement;
|
||||||
}
|
}
|
||||||
if (replacement->prev != NULL)
|
|
||||||
{
|
|
||||||
replacement->prev->next = replacement;
|
|
||||||
}
|
|
||||||
if (parent->child == item)
|
if (parent->child == item)
|
||||||
{
|
{
|
||||||
|
if (parent->child->prev == parent->child)
|
||||||
|
{
|
||||||
|
replacement->prev = replacement;
|
||||||
|
}
|
||||||
parent->child = replacement;
|
parent->child = replacement;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{ /*
|
||||||
|
* To find the last item in array quickly, we use prev in array.
|
||||||
|
* We can't modify the last item's next pointer where this item was the parent's child
|
||||||
|
*/
|
||||||
|
if (replacement->prev != NULL)
|
||||||
|
{
|
||||||
|
replacement->prev->next = replacement;
|
||||||
|
}
|
||||||
|
if (replacement->next == NULL)
|
||||||
|
{
|
||||||
|
parent->child->prev = replacement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
item->next = NULL;
|
item->next = NULL;
|
||||||
item->prev = NULL;
|
item->prev = NULL;
|
||||||
@@ -2210,14 +2342,14 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
|
||||||
{
|
{
|
||||||
if (which < 0)
|
if (which < 0)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
|
return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
|
static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
|
||||||
@@ -2233,21 +2365,24 @@ static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSO
|
|||||||
cJSON_free(replacement->string);
|
cJSON_free(replacement->string);
|
||||||
}
|
}
|
||||||
replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
|
replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
|
||||||
|
if (replacement->string == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
replacement->type &= ~cJSON_StringIsConst;
|
replacement->type &= ~cJSON_StringIsConst;
|
||||||
|
|
||||||
cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
|
return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
|
||||||
{
|
{
|
||||||
replace_item_in_object(object, string, newitem, false);
|
return replace_item_in_object(object, string, newitem, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
|
||||||
{
|
{
|
||||||
replace_item_in_object(object, string, newitem, true);
|
return replace_item_in_object(object, string, newitem, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create basic types: */
|
/* Create basic types: */
|
||||||
@@ -2284,12 +2419,12 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b)
|
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
|
||||||
{
|
{
|
||||||
cJSON *item = cJSON_New_Item(&global_hooks);
|
cJSON *item = cJSON_New_Item(&global_hooks);
|
||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
item->type = b ? cJSON_True : cJSON_False;
|
item->type = boolean ? cJSON_True : cJSON_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
@@ -2308,7 +2443,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
|
|||||||
{
|
{
|
||||||
item->valueint = INT_MAX;
|
item->valueint = INT_MAX;
|
||||||
}
|
}
|
||||||
else if (num <= INT_MIN)
|
else if (num <= (double)INT_MIN)
|
||||||
{
|
{
|
||||||
item->valueint = INT_MIN;
|
item->valueint = INT_MIN;
|
||||||
}
|
}
|
||||||
@@ -2424,6 +2559,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
a = cJSON_CreateArray();
|
a = cJSON_CreateArray();
|
||||||
|
|
||||||
for(i = 0; a && (i < (size_t)count); i++)
|
for(i = 0; a && (i < (size_t)count); i++)
|
||||||
{
|
{
|
||||||
n = cJSON_CreateNumber(numbers[i]);
|
n = cJSON_CreateNumber(numbers[i]);
|
||||||
@@ -2443,6 +2579,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
|
|||||||
p = n;
|
p = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a && a->child) {
|
||||||
|
a->child->prev = n;
|
||||||
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2479,6 +2619,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
|
|||||||
p = n;
|
p = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a && a->child) {
|
||||||
|
a->child->prev = n;
|
||||||
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2496,7 +2640,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
|
|||||||
|
|
||||||
a = cJSON_CreateArray();
|
a = cJSON_CreateArray();
|
||||||
|
|
||||||
for(i = 0;a && (i < (size_t)count); i++)
|
for(i = 0; a && (i < (size_t)count); i++)
|
||||||
{
|
{
|
||||||
n = cJSON_CreateNumber(numbers[i]);
|
n = cJSON_CreateNumber(numbers[i]);
|
||||||
if(!n)
|
if(!n)
|
||||||
@@ -2515,10 +2659,14 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
|
|||||||
p = n;
|
p = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a && a->child) {
|
||||||
|
a->child->prev = n;
|
||||||
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
cJSON *n = NULL;
|
cJSON *n = NULL;
|
||||||
@@ -2551,6 +2699,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
|
|||||||
p = n;
|
p = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a && a->child) {
|
||||||
|
a->child->prev = n;
|
||||||
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2622,6 +2774,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
|||||||
}
|
}
|
||||||
child = child->next;
|
child = child->next;
|
||||||
}
|
}
|
||||||
|
if (newitem && newitem->child)
|
||||||
|
{
|
||||||
|
newitem->child->prev = newchild;
|
||||||
|
}
|
||||||
|
|
||||||
return newitem;
|
return newitem;
|
||||||
|
|
||||||
@@ -2634,69 +2790,96 @@ fail:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void skip_oneline_comment(char **input)
|
||||||
|
{
|
||||||
|
*input += static_strlen("//");
|
||||||
|
|
||||||
|
for (; (*input)[0] != '\0'; ++(*input))
|
||||||
|
{
|
||||||
|
if ((*input)[0] == '\n') {
|
||||||
|
*input += static_strlen("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skip_multiline_comment(char **input)
|
||||||
|
{
|
||||||
|
*input += static_strlen("/*");
|
||||||
|
|
||||||
|
for (; (*input)[0] != '\0'; ++(*input))
|
||||||
|
{
|
||||||
|
if (((*input)[0] == '*') && ((*input)[1] == '/'))
|
||||||
|
{
|
||||||
|
*input += static_strlen("*/");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void minify_string(char **input, char **output) {
|
||||||
|
(*output)[0] = (*input)[0];
|
||||||
|
*input += static_strlen("\"");
|
||||||
|
*output += static_strlen("\"");
|
||||||
|
|
||||||
|
|
||||||
|
for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
|
||||||
|
(*output)[0] = (*input)[0];
|
||||||
|
|
||||||
|
if ((*input)[0] == '\"') {
|
||||||
|
(*output)[0] = '\"';
|
||||||
|
*input += static_strlen("\"");
|
||||||
|
*output += static_strlen("\"");
|
||||||
|
return;
|
||||||
|
} else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
|
||||||
|
(*output)[1] = (*input)[1];
|
||||||
|
*input += static_strlen("\"");
|
||||||
|
*output += static_strlen("\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void) cJSON_Minify(char *json)
|
CJSON_PUBLIC(void) cJSON_Minify(char *json)
|
||||||
{
|
{
|
||||||
unsigned char *into = (unsigned char*)json;
|
char *into = json;
|
||||||
|
|
||||||
if (json == NULL)
|
if (json == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*json)
|
while (json[0] != '\0')
|
||||||
{
|
{
|
||||||
if (*json == ' ')
|
switch (json[0])
|
||||||
{
|
{
|
||||||
json++;
|
case ' ':
|
||||||
}
|
case '\t':
|
||||||
else if (*json == '\t')
|
case '\r':
|
||||||
{
|
case '\n':
|
||||||
/* Whitespace characters. */
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
else if (*json == '\r')
|
|
||||||
{
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
else if (*json=='\n')
|
|
||||||
{
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
else if ((*json == '/') && (json[1] == '/'))
|
|
||||||
{
|
|
||||||
/* double-slash comments, to end of line. */
|
|
||||||
while (*json && (*json != '\n'))
|
|
||||||
{
|
|
||||||
json++;
|
json++;
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
else if ((*json == '/') && (json[1] == '*'))
|
case '/':
|
||||||
{
|
if (json[1] == '/')
|
||||||
/* multiline comments. */
|
|
||||||
while (*json && !((*json == '*') && (json[1] == '/')))
|
|
||||||
{
|
|
||||||
json++;
|
|
||||||
}
|
|
||||||
json += 2;
|
|
||||||
}
|
|
||||||
else if (*json == '\"')
|
|
||||||
{
|
|
||||||
/* string literals, which are \" sensitive. */
|
|
||||||
*into++ = (unsigned char)*json++;
|
|
||||||
while (*json && (*json != '\"'))
|
|
||||||
{
|
|
||||||
if (*json == '\\')
|
|
||||||
{
|
{
|
||||||
*into++ = (unsigned char)*json++;
|
skip_oneline_comment(&json);
|
||||||
}
|
}
|
||||||
*into++ = (unsigned char)*json++;
|
else if (json[1] == '*')
|
||||||
}
|
{
|
||||||
*into++ = (unsigned char)*json++;
|
skip_multiline_comment(&json);
|
||||||
}
|
} else {
|
||||||
else
|
json++;
|
||||||
{
|
}
|
||||||
/* All other characters. */
|
break;
|
||||||
*into++ = (unsigned char)*json++;
|
|
||||||
|
case '\"':
|
||||||
|
minify_string(&json, (char**)&into);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
into[0] = json[0];
|
||||||
|
json++;
|
||||||
|
into++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2806,7 +2989,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
|
|||||||
|
|
||||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
|
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
|
||||||
{
|
{
|
||||||
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
|
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2843,7 +3026,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case cJSON_Number:
|
case cJSON_Number:
|
||||||
if (a->valuedouble == b->valuedouble)
|
if (compare_double(a->valuedouble, b->valuedouble))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user