mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 15:05:19 +00:00
Upgrade cJSON version to v1.7.16 (#2404)
This commit is contained in:
parent
b1fa27e91d
commit
45a4e774de
|
@ -22,7 +22,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
||||||
|
|
||||||
| third party components | version number | latest release | vendor pages | CVE details |
|
| third party components | version number | latest release | vendor pages | CVE details |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| cjson | 1.7.10 | 1.7.14 | https://github.com/DaveGamble/cJSON | https://www.cvedetails.com/vendor/19164/Cjson-Project.html |
|
| cjson | 1.7.16 | 1.7.16 | https://github.com/DaveGamble/cJSON | https://www.cvedetails.com/vendor/19164/Cjson-Project.html |
|
||||||
| contiki-ng (er-coap) | unspecified | 3.0 | https://github.com/contiki-os/contiki | https://www.cvedetails.com/vendor/16528/Contiki-os.html |
|
| contiki-ng (er-coap) | unspecified | 3.0 | https://github.com/contiki-os/contiki | https://www.cvedetails.com/vendor/16528/Contiki-os.html |
|
||||||
| freebsd libm | unspecified | 13.0 | https://www.freebsd.org/ | https://www.cvedetails.com/vendor/6/Freebsd.html |
|
| freebsd libm | unspecified | 13.0 | https://www.freebsd.org/ | https://www.cvedetails.com/vendor/6/Freebsd.html |
|
||||||
| LVGL | 6.0.1 | 7.11.0 | https://lvgl.io/ | |
|
| LVGL | 6.0.1 | 7.11.0 | https://lvgl.io/ | |
|
||||||
|
|
444
test-tools/host-tool/external/cJSON/cJSON.c
vendored
444
test-tools/host-tool/external/cJSON/cJSON.c
vendored
|
@ -43,6 +43,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
#ifdef ENABLE_LOCALES
|
#ifdef ENABLE_LOCALES
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
@ -58,9 +59,33 @@
|
||||||
#include "cJSON.h"
|
#include "cJSON.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;
|
||||||
|
@ -72,7 +97,7 @@ 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;
|
||||||
|
@ -81,18 +106,27 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item)
|
||||||
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
|
/* This is a safeguard to prevent copy-pasters from using incompatible C and
|
||||||
* header files */
|
* header files */
|
||||||
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) \
|
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) \
|
||||||
|| (CJSON_VERSION_PATCH != 10)
|
|| (CJSON_VERSION_PATCH != 16)
|
||||||
#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
|
||||||
|
|
||||||
CJSON_PUBLIC(const char *) cJSON_Version(void)
|
CJSON_PUBLIC(const char *) cJSON_Version(void)
|
||||||
{
|
{
|
||||||
static char version[15];
|
static char version[15];
|
||||||
snprintf(version, sizeof(version), "%i.%i.%i", CJSON_VERSION_MAJOR,
|
sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR,
|
||||||
CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
|
CJSON_VERSION_PATCH);
|
||||||
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
@ -127,8 +161,8 @@ typedef struct internal_hooks {
|
||||||
} internal_hooks;
|
} internal_hooks;
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
/* work around MSVC error C2322: '...' address of dillimport '...'
|
/* work around MSVC error C2322: '...' address of dllimport '...' is not static
|
||||||
is not static */
|
*/
|
||||||
static void *CJSON_CDECL
|
static void *CJSON_CDECL
|
||||||
internal_malloc(size_t size)
|
internal_malloc(size_t size)
|
||||||
{
|
{
|
||||||
|
@ -150,13 +184,11 @@ internal_realloc(void *pointer, size_t size)
|
||||||
#define internal_realloc realloc
|
#define internal_realloc realloc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* clang-format off */
|
/* strlen of character literals resolved at compile time */
|
||||||
static internal_hooks global_hooks = {
|
#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
|
||||||
internal_malloc,
|
|
||||||
internal_free,
|
static internal_hooks global_hooks = { internal_malloc, internal_free,
|
||||||
internal_realloc
|
internal_realloc };
|
||||||
};
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
static unsigned char *
|
static unsigned char *
|
||||||
cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
|
cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
|
||||||
|
@ -271,8 +303,8 @@ typedef struct {
|
||||||
/* get a pointer to the buffer at the position */
|
/* get a pointer to the buffer at the position */
|
||||||
#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
|
#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
|
||||||
|
|
||||||
/* Parse the input text to generate a number, and populate the result
|
/* Parse the input text to generate a number, and populate the result into item.
|
||||||
into item. */
|
*/
|
||||||
static cJSON_bool
|
static cJSON_bool
|
||||||
parse_number(cJSON *const item, parse_buffer *const input_buffer)
|
parse_number(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
{
|
{
|
||||||
|
@ -287,9 +319,8 @@ parse_number(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the number into a temporary buffer and replace '.' with the decimal
|
/* copy the number into a temporary buffer and replace '.' with the decimal
|
||||||
* point of the current locale (for strtod)
|
* point of the current locale (for strtod) This also takes care of '\0' not
|
||||||
* This also takes care of '\0' not necessarily being available for marking
|
* necessarily being available for marking the end of the input */
|
||||||
* the end of the input */
|
|
||||||
for (i = 0; (i < (sizeof(number_c_string) - 1))
|
for (i = 0; (i < (sizeof(number_c_string) - 1))
|
||||||
&& can_access_at_index(input_buffer, i);
|
&& can_access_at_index(input_buffer, i);
|
||||||
i++) {
|
i++) {
|
||||||
|
@ -363,6 +394,32 @@ 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;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
@ -438,9 +495,8 @@ 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;
|
||||||
|
@ -463,6 +519,14 @@ 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
|
static cJSON_bool
|
||||||
print_number(const cJSON *const item, printbuffer *const output_buffer)
|
print_number(const cJSON *const item, printbuffer *const output_buffer)
|
||||||
|
@ -471,35 +535,37 @@ print_number(const cJSON *const item, printbuffer *const output_buffer)
|
||||||
double d = item->valuedouble;
|
double d = item->valuedouble;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
unsigned char
|
unsigned char number_buffer[26] = {
|
||||||
number_buffer[26]; /* temporary buffer to print the number into */
|
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) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This checks for NaN and Infinity */
|
/* This checks for NaN and Infinity */
|
||||||
if ((d * 0) != 0) {
|
if (isnan(d) || isinf(d)) {
|
||||||
length = snprintf((char *)number_buffer, sizeof(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
|
/* Try 15 decimal places of precision to avoid nonsignificant nonzero
|
||||||
* digits */
|
* digits */
|
||||||
length =
|
length = sprintf((char *)number_buffer, "%1.15g", d);
|
||||||
snprintf((char *)number_buffer, sizeof(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)
|
if ((sscanf((char *)number_buffer, "%lg", &test) != 1)
|
||||||
|| ((double)test != d)) {
|
|| !compare_double((double)test, d)) {
|
||||||
/* If not, print with 17 decimal places of precision */
|
/* If not, print with 17 decimal places of precision */
|
||||||
length = snprintf((char *)number_buffer, sizeof(number_buffer),
|
length = sprintf((char *)number_buffer, "%1.17g", d);
|
||||||
"%1.17g", d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* snprintf 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;
|
||||||
}
|
}
|
||||||
|
@ -709,8 +775,7 @@ parse_string(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
if (((size_t)(input_end - input_buffer->content)
|
if (((size_t)(input_end - input_buffer->content)
|
||||||
>= input_buffer->length)
|
>= input_buffer->length)
|
||||||
|| (*input_end != '\"')) {
|
|| (*input_end != '\"')) {
|
||||||
goto fail;
|
goto fail; /* string ended unexpectedly */
|
||||||
/* string ended unexpectedly */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is at most how much we need for the output */
|
/* This is at most how much we need for the output */
|
||||||
|
@ -719,8 +784,7 @@ parse_string(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
output = (unsigned char *)input_buffer->hooks.allocate(allocation_length
|
output = (unsigned char *)input_buffer->hooks.allocate(allocation_length
|
||||||
+ sizeof(""));
|
+ sizeof(""));
|
||||||
if (output == NULL) {
|
if (output == NULL) {
|
||||||
goto fail;
|
goto fail; /* allocation failure */
|
||||||
/* allocation failure */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,7 +869,7 @@ print_string_ptr(const unsigned char *const input,
|
||||||
printbuffer *const output_buffer)
|
printbuffer *const output_buffer)
|
||||||
{
|
{
|
||||||
const unsigned char *input_pointer = NULL;
|
const unsigned char *input_pointer = NULL;
|
||||||
unsigned char *output = NULL, *output_end;
|
unsigned char *output = NULL;
|
||||||
unsigned char *output_pointer = NULL;
|
unsigned char *output_pointer = NULL;
|
||||||
size_t output_length = 0;
|
size_t output_length = 0;
|
||||||
/* numbers of additional characters needed for escaping */
|
/* numbers of additional characters needed for escaping */
|
||||||
|
@ -853,7 +917,6 @@ print_string_ptr(const unsigned char *const input,
|
||||||
if (output == NULL) {
|
if (output == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
output_end = output + output_length + sizeof("\"\"");
|
|
||||||
|
|
||||||
/* no characters have to be escaped */
|
/* no characters have to be escaped */
|
||||||
if (escape_characters == 0) {
|
if (escape_characters == 0) {
|
||||||
|
@ -902,9 +965,7 @@ print_string_ptr(const unsigned char *const input,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* escape and print as unicode codepoint */
|
/* escape and print as unicode codepoint */
|
||||||
snprintf((char *)output_pointer,
|
sprintf((char *)output_pointer, "u%04x", *input_pointer);
|
||||||
output_end - output_pointer, "u%04x",
|
|
||||||
*input_pointer);
|
|
||||||
output_pointer += 4;
|
output_pointer += 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -945,6 +1006,10 @@ 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)
|
while (can_access_at_index(buffer, 0)
|
||||||
&& (buffer_at_offset(buffer)[0] <= 32)) {
|
&& (buffer_at_offset(buffer)[0] <= 32)) {
|
||||||
buffer->offset++;
|
buffer->offset++;
|
||||||
|
@ -975,10 +1040,28 @@ skip_utf8_bom(parse_buffer *const buffer)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse an object - create a new root, and populate. */
|
|
||||||
CJSON_PUBLIC(cJSON *)
|
CJSON_PUBLIC(cJSON *)
|
||||||
cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
|
cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
|
||||||
cJSON_bool require_null_terminated)
|
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;
|
||||||
|
@ -987,12 +1070,12 @@ cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
|
||||||
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;
|
||||||
|
|
||||||
|
@ -1056,7 +1139,13 @@ 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 *
|
static unsigned char *
|
||||||
print(const cJSON *const item, cJSON_bool format,
|
print(const cJSON *const item, cJSON_bool format,
|
||||||
|
@ -1113,6 +1202,10 @@ fail:
|
||||||
hooks->deallocate(buffer->buffer);
|
hooks->deallocate(buffer->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (printed != NULL) {
|
||||||
|
hooks->deallocate(printed);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1156,20 +1249,20 @@ cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON_bool)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_PrintPreallocated(cJSON *item, char *buf, const int len,
|
cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
|
||||||
const cJSON_bool fmt)
|
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);
|
||||||
|
@ -1341,8 +1434,7 @@ parse_array(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
/* allocate next item */
|
/* allocate next item */
|
||||||
cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
|
cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
|
||||||
if (new_item == NULL) {
|
if (new_item == NULL) {
|
||||||
goto fail;
|
goto fail; /* allocation failure */
|
||||||
/* allocation failure */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* attach next item to list */
|
/* attach next item to list */
|
||||||
|
@ -1361,8 +1453,7 @@ parse_array(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
input_buffer->offset++;
|
input_buffer->offset++;
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
if (!parse_value(current_item, input_buffer)) {
|
if (!parse_value(current_item, input_buffer)) {
|
||||||
goto fail;
|
goto fail; /* failed to parse value */
|
||||||
/* failed to parse value */
|
|
||||||
}
|
}
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
} while (can_access_at_index(input_buffer, 0)
|
} while (can_access_at_index(input_buffer, 0)
|
||||||
|
@ -1370,13 +1461,16 @@ parse_array(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
|
|
||||||
if (cannot_access_at_index(input_buffer, 0)
|
if (cannot_access_at_index(input_buffer, 0)
|
||||||
|| buffer_at_offset(input_buffer)[0] != ']') {
|
|| buffer_at_offset(input_buffer)[0] != ']') {
|
||||||
goto fail;
|
goto fail; /* expected end of array */
|
||||||
/* expected end of array */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -1461,16 +1555,14 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
|
|
||||||
if (cannot_access_at_index(input_buffer, 0)
|
if (cannot_access_at_index(input_buffer, 0)
|
||||||
|| (buffer_at_offset(input_buffer)[0] != '{')) {
|
|| (buffer_at_offset(input_buffer)[0] != '{')) {
|
||||||
goto fail;
|
goto fail; /* not an object */
|
||||||
/* not an object */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input_buffer->offset++;
|
input_buffer->offset++;
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
if (can_access_at_index(input_buffer, 0)
|
if (can_access_at_index(input_buffer, 0)
|
||||||
&& (buffer_at_offset(input_buffer)[0] == '}')) {
|
&& (buffer_at_offset(input_buffer)[0] == '}')) {
|
||||||
goto success;
|
goto success; /* empty object */
|
||||||
/* empty object */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we skipped to the end of the buffer */
|
/* check if we skipped to the end of the buffer */
|
||||||
|
@ -1486,8 +1578,7 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
/* allocate next item */
|
/* allocate next item */
|
||||||
cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
|
cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
|
||||||
if (new_item == NULL) {
|
if (new_item == NULL) {
|
||||||
goto fail;
|
goto fail; /* allocation failure */
|
||||||
/* allocation failure */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* attach next item to list */
|
/* attach next item to list */
|
||||||
|
@ -1506,8 +1597,7 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
input_buffer->offset++;
|
input_buffer->offset++;
|
||||||
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;
|
goto fail; /* failed to parse name */
|
||||||
/* faile to parse name */
|
|
||||||
}
|
}
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
|
|
||||||
|
@ -1517,16 +1607,14 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
|
|
||||||
if (cannot_access_at_index(input_buffer, 0)
|
if (cannot_access_at_index(input_buffer, 0)
|
||||||
|| (buffer_at_offset(input_buffer)[0] != ':')) {
|
|| (buffer_at_offset(input_buffer)[0] != ':')) {
|
||||||
goto fail;
|
goto fail; /* invalid object */
|
||||||
/* invalid object */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse the value */
|
/* parse the value */
|
||||||
input_buffer->offset++;
|
input_buffer->offset++;
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
if (!parse_value(current_item, input_buffer)) {
|
if (!parse_value(current_item, input_buffer)) {
|
||||||
goto fail;
|
goto fail; /* failed to parse value */
|
||||||
/* failed to parse value */
|
|
||||||
}
|
}
|
||||||
buffer_skip_whitespace(input_buffer);
|
buffer_skip_whitespace(input_buffer);
|
||||||
} while (can_access_at_index(input_buffer, 0)
|
} while (can_access_at_index(input_buffer, 0)
|
||||||
|
@ -1534,13 +1622,16 @@ parse_object(cJSON *const item, parse_buffer *const input_buffer)
|
||||||
|
|
||||||
if (cannot_access_at_index(input_buffer, 0)
|
if (cannot_access_at_index(input_buffer, 0)
|
||||||
|| (buffer_at_offset(input_buffer)[0] != '}')) {
|
|| (buffer_at_offset(input_buffer)[0] != '}')) {
|
||||||
goto fail;
|
goto fail; /* expected end of object */
|
||||||
/* expected end of object */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -1792,22 +1883,26 @@ 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;
|
||||||
|
@ -1847,7 +1942,8 @@ add_item_to_object(cJSON *const object, const char *const string,
|
||||||
char *new_key = NULL;
|
char *new_key = NULL;
|
||||||
int new_type = cJSON_Invalid;
|
int new_type = cJSON_Invalid;
|
||||||
|
|
||||||
if ((object == NULL) || (string == NULL) || (item == NULL)) {
|
if ((object == NULL) || (string == NULL) || (item == NULL)
|
||||||
|
|| (object == item)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2028,7 +2124,7 @@ cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -2041,6 +2137,11 @@ cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item)
|
||||||
/* 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;
|
||||||
|
@ -2121,7 +2222,8 @@ CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
|
cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
|
||||||
cJSON *replacement)
|
cJSON *replacement)
|
||||||
{
|
{
|
||||||
if ((parent == NULL) || (replacement == NULL) || (item == NULL)) {
|
if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL)
|
||||||
|
|| (item == NULL)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2135,11 +2237,23 @@ cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
|
||||||
if (replacement->next != NULL) {
|
if (replacement->next != NULL) {
|
||||||
replacement->next->prev = replacement;
|
replacement->next->prev = replacement;
|
||||||
}
|
}
|
||||||
|
if (parent->child == item) {
|
||||||
|
if (parent->child->prev == parent->child) {
|
||||||
|
replacement->prev = 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) {
|
if (replacement->prev != NULL) {
|
||||||
replacement->prev->next = replacement;
|
replacement->prev->next = replacement;
|
||||||
}
|
}
|
||||||
if (parent->child == item) {
|
if (replacement->next == NULL) {
|
||||||
parent->child = replacement;
|
parent->child->prev = replacement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item->next = NULL;
|
item->next = NULL;
|
||||||
|
@ -2149,15 +2263,15 @@ cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
|
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),
|
return cJSON_ReplaceItemViaPointer(
|
||||||
newitem);
|
array, get_array_item(array, (size_t)which), newitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cJSON_bool
|
static cJSON_bool
|
||||||
|
@ -2175,25 +2289,27 @@ replace_item_in_object(cJSON *object, const char *string, cJSON *replacement,
|
||||||
}
|
}
|
||||||
replacement->string =
|
replacement->string =
|
||||||
(char *)cJSON_strdup((const unsigned char *)string, &global_hooks);
|
(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(
|
return cJSON_ReplaceItemViaPointer(
|
||||||
object, get_object_item(object, string, case_sensitive), replacement);
|
object, get_object_item(object, string, case_sensitive), replacement);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(void)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
|
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_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
|
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
|
||||||
cJSON *newitem)
|
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: */
|
||||||
|
@ -2227,11 +2343,11 @@ 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;
|
||||||
|
@ -2357,6 +2473,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]);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
|
@ -2372,6 +2489,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2403,6 +2524,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2434,10 +2559,15 @@ 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;
|
||||||
|
@ -2465,6 +2595,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2532,6 +2666,9 @@ 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;
|
||||||
|
|
||||||
|
@ -2543,55 +2680,93 @@ 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]) {
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
json++;
|
json++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
if (json[1] == '/') {
|
||||||
|
skip_oneline_comment(&json);
|
||||||
}
|
}
|
||||||
else if (*json == '\t') {
|
else if (json[1] == '*') {
|
||||||
/* Whitespace characters. */
|
skip_multiline_comment(&json);
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((*json == '/') && (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++;
|
|
||||||
}
|
|
||||||
*into++ = (unsigned char)*json++;
|
|
||||||
}
|
|
||||||
*into++ = (unsigned char)*json++;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* All other characters. */
|
json++;
|
||||||
*into++ = (unsigned char)*json++;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\"':
|
||||||
|
minify_string(&json, (char **)&into);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
into[0] = json[0];
|
||||||
|
json++;
|
||||||
|
into++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2692,8 +2867,7 @@ CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_Compare(const cJSON *const a, const cJSON *const b,
|
cJSON_Compare(const cJSON *const a, const cJSON *const b,
|
||||||
const cJSON_bool case_sensitive)
|
const cJSON_bool case_sensitive)
|
||||||
{
|
{
|
||||||
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))
|
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) {
|
||||||
|| cJSON_IsInvalid(a)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2726,7 +2900,7 @@ cJSON_Compare(const cJSON *const a, const cJSON *const b,
|
||||||
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;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
117
test-tools/host-tool/external/cJSON/cJSON.h
vendored
117
test-tools/host-tool/external/cJSON/cJSON.h
vendored
|
@ -35,30 +35,34 @@ extern "C" {
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
/**
|
/* When compiling for windows, we specify a specific calling convention to avoid
|
||||||
* 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
|
||||||
* issues where we are being called from a project with a different default
|
convention. For windows you have 3 define options:
|
||||||
* calling convention. For windows you have 3 define options:
|
|
||||||
* CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever
|
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever
|
||||||
* dllexport symbols
|
dllexport symbols CJSON_EXPORT_SYMBOLS - Define this on library build when you
|
||||||
* CJSON_EXPORT_SYMBOLS - Define this on library build when you want to
|
want to dllexport symbols (default) CJSON_IMPORT_SYMBOLS - Define this if you
|
||||||
* dllexport symbols (default)
|
want to dllimport symbol
|
||||||
* CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
|
||||||
*
|
For *nix builds that support visibility attribute, you can define similar
|
||||||
* For *nix builds that support visibility attribute, you can define similar
|
behavior by
|
||||||
* behavior by setting default visibility to hidden by adding
|
|
||||||
* -fvisibility=hidden (for gcc)
|
setting default visibility to hidden by adding
|
||||||
* or
|
-fvisibility=hidden (for gcc)
|
||||||
* -xldscope=hidden (for sun cc)
|
or
|
||||||
* to CFLAGS, then using the CJSON_API_VISIBILITY flag to "export" the same
|
-xldscope=hidden (for sun cc)
|
||||||
* symbols the way CJSON_EXPORT_SYMBOLS does
|
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_CDECL __cdecl
|
||||||
#define CJSON_STDCALL __stdcall
|
#define CJSON_STDCALL __stdcall
|
||||||
|
|
||||||
/* export symbols by default, this is necessary for copy pasting the C and
|
/* export symbols by default, this is necessary for copy pasting the C and
|
||||||
header file */
|
* header file */
|
||||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) \
|
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) \
|
||||||
&& !defined(CJSON_EXPORT_SYMBOLS)
|
&& !defined(CJSON_EXPORT_SYMBOLS)
|
||||||
#define CJSON_EXPORT_SYMBOLS
|
#define CJSON_EXPORT_SYMBOLS
|
||||||
|
@ -86,7 +90,7 @@ extern "C" {
|
||||||
/* 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 10
|
#define CJSON_VERSION_PATCH 16
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
@ -107,11 +111,11 @@ extern "C" {
|
||||||
/* The cJSON structure: */
|
/* The cJSON structure: */
|
||||||
typedef struct cJSON {
|
typedef struct cJSON {
|
||||||
/* next/prev allow you to walk array/object chains. Alternatively, use
|
/* next/prev allow you to walk array/object chains. Alternatively, use
|
||||||
GetArraySize/GetArrayItem/GetObjectItem */
|
* GetArraySize/GetArrayItem/GetObjectItem */
|
||||||
struct cJSON *next;
|
struct cJSON *next;
|
||||||
struct cJSON *prev;
|
struct cJSON *prev;
|
||||||
/* An array or object item will have a child pointer pointing to a chain of
|
/* An array or object item will have a child pointer pointing to a chain of
|
||||||
the items in the array/object. */
|
* the items in the array/object. */
|
||||||
struct cJSON *child;
|
struct cJSON *child;
|
||||||
|
|
||||||
/* The type of the item, as above. */
|
/* The type of the item, as above. */
|
||||||
|
@ -125,7 +129,7 @@ typedef struct cJSON {
|
||||||
double valuedouble;
|
double valuedouble;
|
||||||
|
|
||||||
/* The item's name string, if this item is the child of, or is in the list
|
/* The item's name string, if this item is the child of, or is in the list
|
||||||
of subitems of an object. */
|
* of subitems of an object. */
|
||||||
char *string;
|
char *string;
|
||||||
} cJSON;
|
} cJSON;
|
||||||
|
|
||||||
|
@ -140,7 +144,7 @@ typedef struct cJSON_Hooks {
|
||||||
typedef int cJSON_bool;
|
typedef int cJSON_bool;
|
||||||
|
|
||||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse
|
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse
|
||||||
them. This is to prevent stack overflows. */
|
* them. This is to prevent stack overflows. */
|
||||||
#ifndef CJSON_NESTING_LIMIT
|
#ifndef CJSON_NESTING_LIMIT
|
||||||
#define CJSON_NESTING_LIMIT 1000
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
#endif
|
#endif
|
||||||
|
@ -159,6 +163,8 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks *hooks);
|
||||||
/* 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
|
/* ParseWithOpts allows you to require (and check) that the JSON is null
|
||||||
* terminated, and to retrieve the pointer to the final byte parsed. */
|
* terminated, and to retrieve the pointer to the final byte parsed. */
|
||||||
/* If you supply a ptr in return_parse_end and parsing fails, then
|
/* If you supply a ptr in return_parse_end and parsing fails, then
|
||||||
|
@ -167,6 +173,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
CJSON_PUBLIC(cJSON *)
|
CJSON_PUBLIC(cJSON *)
|
||||||
cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
|
cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
|
||||||
cJSON_bool require_null_terminated);
|
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);
|
||||||
|
@ -185,7 +195,7 @@ CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
|
cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length,
|
||||||
const cJSON_bool format);
|
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);
|
||||||
|
@ -205,8 +215,9 @@ cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||||
* when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
* 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);
|
||||||
|
@ -233,18 +244,21 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
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(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
@ -264,7 +278,7 @@ cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
CJSON_PUBLIC(cJSON_bool)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
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_PUBLIC(cJSON *)
|
||||||
cJSON_DetachItemViaPointer(cJSON *parent, cJSON *const item);
|
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);
|
||||||
|
@ -286,32 +300,35 @@ cJSON_InsertItemInArray(
|
||||||
CJSON_PUBLIC(cJSON_bool)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
|
cJSON_ReplaceItemViaPointer(cJSON *const parent, cJSON *const item,
|
||||||
cJSON *replacement);
|
cJSON *replacement);
|
||||||
CJSON_PUBLIC(void)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
CJSON_PUBLIC(void)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
|
cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
|
||||||
CJSON_PUBLIC(void)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
|
cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string,
|
||||||
cJSON *newitem);
|
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
|
/* 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
|
* memory that will need to be released. With recurse!=0, it will duplicate any
|
||||||
children connected to the item. The item->next and ->prev pointers are always
|
* children connected to the item. The item->next and ->prev pointers are always
|
||||||
zero on return from Duplicate. */
|
* zero on return from Duplicate. */
|
||||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or
|
/* Recursively compare two cJSON items for equality. If either a or b is NULL or
|
||||||
* invalid, they will be considered unequal.
|
* invalid, they will be considered unequal. case_sensitive determines if object
|
||||||
* case_sensitive determines if object keys are treated case sensitive (1) or
|
* keys are treated case sensitive (1) or case insensitive (0) */
|
||||||
* case insensitive (0) */
|
|
||||||
CJSON_PUBLIC(cJSON_bool)
|
CJSON_PUBLIC(cJSON_bool)
|
||||||
cJSON_Compare(const cJSON *const a, const cJSON *const b,
|
cJSON_Compare(const cJSON *const a, const cJSON *const b,
|
||||||
const cJSON_bool case_sensitive);
|
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.
|
||||||
They return the added item or NULL on failure. */
|
* They return the added item or NULL on failure. */
|
||||||
CJSON_PUBLIC(cJSON *)
|
CJSON_PUBLIC(cJSON *)
|
||||||
cJSON_AddNullToObject(cJSON *const object, const char *const name);
|
cJSON_AddNullToObject(cJSON *const object, const char *const name);
|
||||||
CJSON_PUBLIC(cJSON *)
|
CJSON_PUBLIC(cJSON *)
|
||||||
|
@ -336,7 +353,7 @@ CJSON_PUBLIC(cJSON *)
|
||||||
cJSON_AddArrayToObject(cJSON *const object, const char *const name);
|
cJSON_AddArrayToObject(cJSON *const object, const char *const name);
|
||||||
|
|
||||||
/* When assigning an integer value, it needs to be propagated to valuedouble
|
/* When assigning an integer value, it needs to be propagated to valuedouble
|
||||||
too. */
|
* too. */
|
||||||
#define cJSON_SetIntValue(object, number) \
|
#define cJSON_SetIntValue(object, number) \
|
||||||
((object) ? (object)->valueint = (object)->valuedouble = (number) \
|
((object) ? (object)->valueint = (object)->valuedouble = (number) \
|
||||||
: (number))
|
: (number))
|
||||||
|
@ -345,6 +362,18 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
#define cJSON_SetNumberValue(object, number) \
|
#define cJSON_SetNumberValue(object, number) \
|
||||||
((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) \
|
((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) \
|
||||||
: (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) \
|
#define cJSON_ArrayForEach(element, array) \
|
||||||
|
@ -352,7 +381,7 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
element = element->next)
|
element = element->next)
|
||||||
|
|
||||||
/* malloc/free objects using the malloc/free functions that have been set with
|
/* malloc/free objects using the malloc/free functions that have been set with
|
||||||
cJSON_InitHooks */
|
* cJSON_InitHooks */
|
||||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user