27#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
28#define _CRT_SECURE_NO_DEPRECATE
32#pragma GCC visibility push(default)
37#pragma warning (disable : 4001)
56#pragma GCC visibility pop
65#define true ((cJSON_bool)1)
70#define false ((cJSON_bool)0)
74#define isinf(d) (isnan((d - d)) && !isnan(d))
77#define isnan(d) (d != d)
102 if (!cJSON_IsString(
item))
112 if (!cJSON_IsNumber(
item))
121#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15)
122#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
127 static char version[15];
136 if ((string1 ==
NULL) || (string2 ==
NULL))
141 if (string1 == string2)
146 for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
148 if (*string1 ==
'\0')
154 return tolower(*string1) - tolower(*string2);
176 return realloc(pointer, size);
179#define internal_malloc malloc
180#define internal_free free
181#define internal_realloc realloc
185#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
199 length = strlen((
const char*)
string) +
sizeof(
"");
247 memset(node,
'\0',
sizeof(
cJSON));
281 struct lconv *lconv = localeconv();
282 return (
unsigned char) lconv->decimal_point[0];
298#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
300#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
301#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
303#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
309 unsigned char *after_end =
NULL;
310 unsigned char number_c_string[64];
322 for (i = 0; (i < (
sizeof(number_c_string) - 1)) &&
can_access_at_index(input_buffer, i); i++)
344 number_c_string[i] = decimal_point;
352 number_c_string[i] =
'\0';
354 number =
strtod((
const char*)number_c_string, (
char**)&after_end);
355 if (number_c_string == after_end)
367 else if (
number <= (
double)INT_MIN)
378 input_buffer->
offset += (size_t)(after_end - number_c_string);
387 object->valueint = INT_MAX;
389 else if (
number <= (
double)INT_MIN)
391 object->valueint = INT_MIN;
395 object->valueint = (int)
number;
398 return object->valuedouble =
number;
412 return object->valuestring;
423 object->valuestring =
copy;
442 unsigned char *newbuffer =
NULL;
450 if ((
p->length > 0) && (
p->offset >=
p->length))
456 if (needed > INT_MAX)
462 needed +=
p->offset + 1;
465 return p->buffer +
p->offset;
474 if (needed > (INT_MAX / 2))
477 if (needed <= INT_MAX)
488 newsize = needed * 2;
491 if (
p->hooks.reallocate !=
NULL)
494 newbuffer = (
unsigned char*)
p->hooks.reallocate(
p->buffer, newsize);
495 if (newbuffer ==
NULL)
497 p->hooks.deallocate(
p->buffer);
507 newbuffer = (
unsigned char*)
p->hooks.allocate(newsize);
510 p->hooks.deallocate(
p->buffer);
517 memcpy(newbuffer,
p->buffer,
p->offset + 1);
518 p->hooks.deallocate(
p->buffer);
521 p->buffer = newbuffer;
523 return newbuffer +
p->offset;
529 const unsigned char *buffer_pointer =
NULL;
536 buffer->offset += strlen((
const char*)buffer_pointer);
542 double maxVal = fabs(
a) > fabs(
b) ? fabs(
a) : fabs(
b);
543 return (fabs(
a -
b) <= maxVal * DBL_EPSILON);
549 unsigned char *output_pointer =
NULL;
553 unsigned char number_buffer[26] = {0};
557 if (output_buffer ==
NULL)
565 length = snprintf((
char*)number_buffer,
sizeof(number_buffer),
"null");
574 length = snprintf((
char*)number_buffer,
sizeof(number_buffer),
"%1.15g", d);
577 if ((sscanf((
char*)number_buffer,
"%lg", &test) != 1) || !
compare_double((
double)test, d))
580 length = snprintf((
char*)number_buffer,
sizeof(number_buffer),
"%1.17g", d);
585 if ((
length < 0) || (
length > (
int)(
sizeof(number_buffer) - 1)))
591 output_pointer =
ensure(output_buffer, (
size_t)
length +
sizeof(
""));
592 if (output_pointer ==
NULL)
599 for (i = 0; i < ((size_t)
length); i++)
601 if (number_buffer[i] == decimal_point)
603 output_pointer[i] =
'.';
607 output_pointer[i] = number_buffer[i];
609 output_pointer[i] =
'\0';
622 for (i = 0; i < 4; i++)
625 if ((input[i] >=
'0') && (input[i] <=
'9'))
627 h += (
unsigned int) input[i] -
'0';
629 else if ((input[i] >=
'A') && (input[i] <=
'F'))
631 h += (
unsigned int) 10 + input[i] -
'A';
633 else if ((input[i] >=
'a') && (input[i] <=
'f'))
635 h += (
unsigned int) 10 + input[i] -
'a';
654static unsigned char utf16_literal_to_utf8(
const unsigned char *
const input_pointer,
const unsigned char *
const input_end,
unsigned char **output_pointer)
656 long unsigned int codepoint = 0;
657 unsigned int first_code = 0;
658 const unsigned char *first_sequence = input_pointer;
659 unsigned char utf8_length = 0;
660 unsigned char utf8_position = 0;
661 unsigned char sequence_length = 0;
662 unsigned char first_byte_mark = 0;
664 if ((input_end - first_sequence) < 6)
674 if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
680 if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
682 const unsigned char *second_sequence = first_sequence + 6;
683 unsigned int second_code = 0;
684 sequence_length = 12;
686 if ((input_end - second_sequence) < 6)
692 if ((second_sequence[0] !=
'\\') || (second_sequence[1] !=
'u'))
699 second_code =
parse_hex4(second_sequence + 2);
701 if ((second_code < 0xDC00) || (second_code > 0xDFFF))
709 codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
714 codepoint = first_code;
720 if (codepoint < 0x80)
725 else if (codepoint < 0x800)
729 first_byte_mark = 0xC0;
731 else if (codepoint < 0x10000)
735 first_byte_mark = 0xE0;
737 else if (codepoint <= 0x10FFFF)
741 first_byte_mark = 0xF0;
750 for (utf8_position = (
unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
753 (*output_pointer)[utf8_position] = (
unsigned char)((codepoint | 0x80) & 0xBF);
759 (*output_pointer)[0] = (
unsigned char)((codepoint | first_byte_mark) & 0xFF);
763 (*output_pointer)[0] = (
unsigned char)(codepoint & 0x7F);
766 *output_pointer += utf8_length;
768 return sequence_length;
779 unsigned char *output_pointer =
NULL;
780 unsigned char *output =
NULL;
790 size_t allocation_length = 0;
791 size_t skipped_bytes = 0;
792 while (((
size_t)(input_end - input_buffer->
content) < input_buffer->
length) && (*input_end !=
'\"'))
795 if (input_end[0] ==
'\\')
797 if ((
size_t)(input_end + 1 - input_buffer->
content) >= input_buffer->
length)
807 if (((
size_t)(input_end - input_buffer->
content) >= input_buffer->
length) || (*input_end !=
'\"'))
813 allocation_length = (size_t) (input_end -
buffer_at_offset(input_buffer)) - skipped_bytes;
814 output = (
unsigned char*)input_buffer->
hooks.
allocate(allocation_length +
sizeof(
""));
821 output_pointer = output;
823 while (input_pointer < input_end)
825 if (*input_pointer !=
'\\')
827 *output_pointer++ = *input_pointer++;
832 unsigned char sequence_length = 2;
833 if ((input_end - input_pointer) < 1)
838 switch (input_pointer[1])
841 *output_pointer++ =
'\b';
844 *output_pointer++ =
'\f';
847 *output_pointer++ =
'\n';
850 *output_pointer++ =
'\r';
853 *output_pointer++ =
'\t';
858 *output_pointer++ = input_pointer[1];
864 if (sequence_length == 0)
874 input_pointer += sequence_length;
879 *output_pointer =
'\0';
884 input_buffer->
offset = (size_t) (input_end - input_buffer->
content);
892 input_buffer->
hooks.deallocate(output);
895 if (input_pointer !=
NULL)
897 input_buffer->
offset = (size_t)(input_pointer - input_buffer->
content);
906 const unsigned char *input_pointer =
NULL;
907 unsigned char *output =
NULL;
908 unsigned char *output_pointer =
NULL;
909 size_t output_length = 0;
911 size_t escape_characters = 0;
913 if (output_buffer ==
NULL)
921 output =
ensure(output_buffer,
sizeof(
"\"\""));
926 strcpy((
char*)output,
"\"\"");
932 for (input_pointer = input; *input_pointer; input_pointer++)
934 switch (*input_pointer)
947 if (*input_pointer < 32)
950 escape_characters += 5;
955 output_length = (size_t)(input_pointer - input) + escape_characters;
957 output =
ensure(output_buffer, output_length +
sizeof(
"\"\""));
964 if (escape_characters == 0)
967 memcpy(output + 1, input, output_length);
968 output[output_length + 1] =
'\"';
969 output[output_length + 2] =
'\0';
975 output_pointer = output + 1;
977 for (input_pointer = input; *input_pointer !=
'\0'; (void)input_pointer++, output_pointer++)
979 if ((*input_pointer > 31) && (*input_pointer !=
'\"') && (*input_pointer !=
'\\'))
982 *output_pointer = *input_pointer;
987 *output_pointer++ =
'\\';
988 switch (*input_pointer)
991 *output_pointer =
'\\';
994 *output_pointer =
'\"';
997 *output_pointer =
'b';
1000 *output_pointer =
'f';
1003 *output_pointer =
'n';
1006 *output_pointer =
'r';
1009 *output_pointer =
't';
1013 snprintf((
char*)output_pointer,
sizeof(output_pointer),
"u%04x", *input_pointer);
1014 output_pointer += 4;
1019 output[output_length + 1] =
'\"';
1020 output[output_length + 2] =
'\0';
1111 buffer.content = (
const unsigned char*)value;
1153 local_error.
json = (
const unsigned char*)value;
1160 else if (
buffer.length > 0)
1179 return cJSON_ParseWithOpts(value, 0, 0);
1187#define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
1191 static const size_t default_buffer_size = 256;
1193 unsigned char *printed =
NULL;
1198 buffer->buffer = (
unsigned char*)
hooks->allocate(default_buffer_size);
1199 buffer->length = default_buffer_size;
1217 printed = (
unsigned char*)
hooks->reallocate(
buffer->buffer,
buffer->offset + 1);
1218 if (printed ==
NULL)
1226 printed = (
unsigned char*)
hooks->allocate(
buffer->offset + 1);
1227 if (printed ==
NULL)
1232 printed[
buffer->offset] =
'\0';
1246 if (printed !=
NULL)
1248 hooks->deallocate(printed);
1292 return (
char*)
p.buffer;
1304 p.buffer = (
unsigned char*)
buffer;
1327 input_buffer->
offset += 4;
1334 input_buffer->
offset += 5;
1342 input_buffer->
offset += 4;
1372 unsigned char *output =
NULL;
1382 output =
ensure(output_buffer, 5);
1387 strcpy((
char*)output,
"null");
1391 output =
ensure(output_buffer, 6);
1396 strcpy((
char*)output,
"false");
1400 output =
ensure(output_buffer, 5);
1405 strcpy((
char*)output,
"true");
1413 size_t raw_length = 0;
1420 output =
ensure(output_buffer, raw_length);
1453 input_buffer->
depth++;
1483 if (new_item ==
NULL)
1492 current_item = head = new_item;
1497 current_item->
next = new_item;
1498 new_item->
prev = current_item;
1499 current_item = new_item;
1519 input_buffer->
depth--;
1523 head->
prev = current_item;
1545 unsigned char *output_pointer =
NULL;
1549 if (output_buffer ==
NULL)
1556 output_pointer =
ensure(output_buffer, 1);
1557 if (output_pointer ==
NULL)
1562 *output_pointer =
'[';
1564 output_buffer->
depth++;
1566 while (current_element !=
NULL)
1573 if (current_element->
next)
1577 if (output_pointer ==
NULL)
1581 *output_pointer++ =
',';
1582 if(output_buffer->
format)
1584 *output_pointer++ =
' ';
1586 *output_pointer =
'\0';
1589 current_element = current_element->
next;
1592 output_pointer =
ensure(output_buffer, 2);
1593 if (output_pointer ==
NULL)
1597 *output_pointer++ =
']';
1598 *output_pointer =
'\0';
1599 output_buffer->
depth--;
1614 input_buffer->
depth++;
1642 if (new_item ==
NULL)
1651 current_item = head = new_item;
1656 current_item->
next = new_item;
1657 new_item->
prev = current_item;
1658 current_item = new_item;
1696 input_buffer->
depth--;
1700 head->
prev = current_item;
1721 unsigned char *output_pointer =
NULL;
1725 if (output_buffer ==
NULL)
1733 if (output_pointer ==
NULL)
1738 *output_pointer++ =
'{';
1739 output_buffer->
depth++;
1740 if (output_buffer->
format)
1742 *output_pointer++ =
'\n';
1746 while (current_item)
1748 if (output_buffer->
format)
1751 output_pointer =
ensure(output_buffer, output_buffer->
depth);
1752 if (output_pointer ==
NULL)
1756 for (i = 0; i < output_buffer->
depth; i++)
1758 *output_pointer++ =
'\t';
1772 if (output_pointer ==
NULL)
1776 *output_pointer++ =
':';
1777 if (output_buffer->
format)
1779 *output_pointer++ =
'\t';
1791 length = ((size_t)(output_buffer->
format ? 1 : 0) + (
size_t)(current_item->
next ? 1 : 0));
1793 if (output_pointer ==
NULL)
1797 if (current_item->
next)
1799 *output_pointer++ =
',';
1802 if (output_buffer->
format)
1804 *output_pointer++ =
'\n';
1806 *output_pointer =
'\0';
1809 current_item = current_item->
next;
1812 output_pointer =
ensure(output_buffer, output_buffer->
format ? (output_buffer->
depth + 1) : 2);
1813 if (output_pointer ==
NULL)
1817 if (output_buffer->
format)
1820 for (i = 0; i < (output_buffer->
depth - 1); i++)
1822 *output_pointer++ =
'\t';
1825 *output_pointer++ =
'}';
1826 *output_pointer =
'\0';
1827 output_buffer->
depth--;
1865 current_child = array->
child;
1866 while ((current_child !=
NULL) && (
index > 0))
1869 current_child = current_child->
next;
1872 return current_child;
1894 current_element =
object->
child;
1897 while ((current_element !=
NULL) && (current_element->
string !=
NULL) && (strcmp(
name, current_element->
string) != 0))
1899 current_element = current_element->
next;
1906 current_element = current_element->
next;
1910 if ((current_element ==
NULL) || (current_element->
string ==
NULL))
1915 return current_element;
1923CJSON_PUBLIC(
cJSON *) cJSON_GetObjectItemCaseSensitive(
const cJSON *
const object,
const char *
const string)
1930 return cJSON_GetObjectItem(
object,
string) ? 1 : 0;
1950 if (reference ==
NULL)
2001#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
2002#pragma GCC diagnostic push
2005#pragma GCC diagnostic ignored "-Wcast-qual"
2012#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
2013#pragma GCC diagnostic pop
2019 char *new_key =
NULL;
2035 if (new_key ==
NULL)
2040 new_type =
item->
type & ~cJSON_StringIsConst;
2077 if ((
object ==
NULL) || (
string ==
NULL))
2087 cJSON *null = cJSON_CreateNull();
2099 cJSON *true_item = cJSON_CreateTrue();
2111 cJSON *false_item = cJSON_CreateFalse();
2123 cJSON *bool_item = cJSON_CreateBool(
boolean);
2147 cJSON *string_item = cJSON_CreateString(
string);
2159 cJSON *raw_item = cJSON_CreateRaw(
raw);
2171 cJSON *object_item = cJSON_CreateObject();
2183 cJSON *array = cJSON_CreateArray();
2246 cJSON *to_detach = cJSON_GetObjectItem(
object,
string);
2253 cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(
object,
string);
2260 cJSON_Delete(cJSON_DetachItemFromObject(
object,
string));
2263CJSON_PUBLIC(
void) cJSON_DeleteItemFromObjectCaseSensitive(
cJSON *
object,
const char *
string)
2265 cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(
object,
string));
2449 else if (num <= (
double)INT_MIN)
2567 a = cJSON_CreateArray();
2571 n = cJSON_CreateNumber(numbers[i]);
2608 a = cJSON_CreateArray();
2610 for(i = 0;
a && (i < (size_t)
count); i++)
2612 n = cJSON_CreateNumber((
double)numbers[i]);
2649 a = cJSON_CreateArray();
2651 for(i = 0;
a && (i < (size_t)
count); i++)
2653 n = cJSON_CreateNumber(numbers[i]);
2690 a = cJSON_CreateArray();
2692 for (i = 0;
a && (i < (size_t)
count); i++)
2694 n = cJSON_CreateString(strings[i]);
2807 for (; (*input)[0] !=
'\0'; ++(*input))
2809 if ((*input)[0] ==
'\n')
2821 for (; (*input)[0] !=
'\0'; ++(*input))
2823 if (((*input)[0] ==
'*') && ((*input)[1] ==
'/'))
2833 (*output)[0] = (*input)[0];
2838 for (; (*input)[0] !=
'\0'; (void)++(*input), ++(*output))
2840 (*output)[0] = (*input)[0];
2842 if ((*input)[0] ==
'\"')
2844 (*output)[0] =
'\"';
2849 else if (((*input)[0] ==
'\\') && ((*input)[1] ==
'\"'))
2851 (*output)[1] = (*input)[1];
2867 while (
json[0] !=
'\0')
2883 else if (
json[1] ==
'*')
3016 switch (
a->
type & 0xFF)
3038 switch (
a->
type & 0xFF)
3071 for (; (a_element !=
NULL) && (b_element !=
NULL);)
3078 a_element = a_element->
next;
3079 b_element = b_element->
next;
3083 if (a_element != b_element)
3099 if (b_element ==
NULL)
3115 if (a_element ==
NULL)
static parse_buffer * buffer_skip_whitespace(parse_buffer *const buffer)
static unsigned char utf16_literal_to_utf8(const unsigned char *const input_pointer, const unsigned char *const input_end, unsigned char **output_pointer)
cJSON *const cJSON * replacement
static cJSON_bool parse_object(cJSON *const item, parse_buffer *const input_buffer)
static unsigned char * cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
const char ** return_parse_end
static unsigned parse_hex4(const unsigned char *const input)
#define can_read(buffer, size)
static cJSON * create_reference(const cJSON *item, const internal_hooks *const hooks)
static cJSON_bool parse_array(cJSON *const item, parse_buffer *const input_buffer)
static unsigned char * print(const cJSON *const item, cJSON_bool format, const internal_hooks *const hooks)
return cJSON_DetachItemViaPointer(object, to_detach)
static parse_buffer * skip_utf8_bom(parse_buffer *const buffer)
static cJSON_bool print_object(const cJSON *const item, printbuffer *const output_buffer)
static cJSON * get_array_item(const cJSON *array, size_t index)
static void skip_multiline_comment(char **input)
static void minify_string(char **input, char **output)
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks *hooks)
#define static_strlen(string_literal)
static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer)
#define cannot_access_at_index(buffer, index)
static void suffix_object(cJSON *prev, cJSON *item)
const char cJSON_bool require_null_terminated
static cJSON_bool parse_number(cJSON *const item, parse_buffer *const input_buffer)
static error global_error
const char *const const char *const raw
static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
static internal_hooks global_hooks
static void skip_oneline_comment(char **input)
static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
static cJSON * cJSON_New_Item(const internal_hooks *const hooks)
static cJSON * get_object_item(const cJSON *const object, const char *const name, const cJSON_bool case_sensitive)
static cJSON_bool compare_double(double a, double b)
static unsigned char get_decimal_point(void)
return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated)
#define buffer_at_offset(buffer)
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 print_string(const cJSON *const item, printbuffer *const p)
static cJSON_bool print_number(const cJSON *const item, printbuffer *const output_buffer)
static unsigned char * ensure(printbuffer *const p, size_t needed)
static cJSON_bool parse_string(cJSON *const item, parse_buffer *const input_buffer)
#define can_access_at_index(buffer, index)
static cJSON_bool print_array(const cJSON *const item, printbuffer *const output_buffer)
static cJSON_bool print_string_ptr(const unsigned char *const input, printbuffer *const output_buffer)
static void update_offset(printbuffer *const buffer)
static cJSON_bool parse_value(cJSON *const item, parse_buffer *const input_buffer)
static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
static void * cast_away_const(const void *string)
const cJSON *const const cJSON_bool case_sensitive
#define cJSON_StringIsConst
#define CJSON_VERSION_MINOR
#define CJSON_VERSION_PATCH
#define CJSON_VERSION_MAJOR
#define CJSON_NESTING_LIMIT
#define cJSON_ArrayForEach(element, array)
#define cJSON_IsReference
double strtod(const char *str, char **endptr)
const unsigned char * json
void(CJSON_CDECL *deallocate)(void *pointer)
void *CJSON_CDECL * reallocate(void *pointer, size_t size)
void *CJSON_CDECL * allocate(size_t size)
const unsigned char * content