2 Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 /* JSON parser in C. */
26 /* disable warnings about old C89 functions in MSVC */
27 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
28 #define _CRT_SECURE_NO_DEPRECATE
32 #pragma GCC visibility push(default)
35 #pragma warning (push)
36 /* disable warning about single line comments in system headers */
37 #pragma warning (disable : 4001)
56 #pragma GCC visibility pop
61 /* define our own boolean type */
65 #define true ((cJSON_bool)1)
70 #define false ((cJSON_bool)0)
72 /* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */
74 #define isinf(d) (isnan((d - d)) && !isnan(d))
77 #define isnan(d) (d != d)
85 const unsigned char *json;
88 static error global_error = { NULL, 0 };
90 CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
92 return (const char*) (global_error.json + global_error.position);
95 CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
97 if (!cJSON_IsString(item))
102 return item->valuestring;
105 CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
107 if (!cJSON_IsNumber(item))
112 return item->valuedouble;
115 /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
116 #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 14)
117 #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
120 CJSON_PUBLIC(const char*) cJSON_Version(void)
122 static char version[15];
123 sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
128 /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
129 static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
131 if ((string1 == NULL) || (string2 == NULL))
136 if (string1 == string2)
141 for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
143 if (*string1 == '\0')
149 return tolower(*string1) - tolower(*string2);
152 typedef struct internal_hooks
154 void *(CJSON_CDECL *allocate)(size_t size);
155 void (CJSON_CDECL *deallocate)(void *pointer);
156 void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
159 #if defined(_MSC_VER)
160 /* work around MSVC error C2322: '...' address of dllimport '...' is not static */
161 static void * CJSON_CDECL internal_malloc(size_t size)
165 static void CJSON_CDECL internal_free(void *pointer)
169 static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
171 return realloc(pointer, size);
174 #define internal_malloc malloc
175 #define internal_free free
176 #define internal_realloc realloc
179 /* strlen of character literals resolved at compile time */
180 #define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
182 static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
184 static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
187 unsigned char *copy = NULL;
194 length = strlen((const char*)string) + sizeof("");
195 copy = (unsigned char*)hooks->allocate(length);
200 memcpy(copy, string, length);
205 CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
210 global_hooks.allocate = malloc;
211 global_hooks.deallocate = free;
212 global_hooks.reallocate = realloc;
216 global_hooks.allocate = malloc;
217 if (hooks->malloc_fn != NULL)
219 global_hooks.allocate = hooks->malloc_fn;
222 global_hooks.deallocate = free;
223 if (hooks->free_fn != NULL)
225 global_hooks.deallocate = hooks->free_fn;
228 /* use realloc only if both free and malloc are used */
229 global_hooks.reallocate = NULL;
230 if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
232 global_hooks.reallocate = realloc;
236 /* Internal constructor. */
237 static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
239 cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
242 memset(node, '\0', sizeof(cJSON));
248 /* Delete a cJSON structure. */
249 CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
255 if (!(item->type & cJSON_IsReference) && (item->child != NULL))
257 cJSON_Delete(item->child);
259 if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
261 global_hooks.deallocate(item->valuestring);
263 if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
265 global_hooks.deallocate(item->string);
267 global_hooks.deallocate(item);
272 /* get the decimal point character of the current locale */
273 static unsigned char get_decimal_point(void)
275 #ifdef ENABLE_LOCALES
276 struct lconv *lconv = localeconv();
277 return (unsigned char) lconv->decimal_point[0];
285 const unsigned char *content;
288 size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
289 internal_hooks hooks;
292 /* check if the given size is left to read in a given parse buffer (starting with 1) */
293 #define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
294 /* check if the buffer can be accessed at the given index (starting with 0) */
295 #define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
296 #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
297 /* get a pointer to the buffer at the position */
298 #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
300 /* Parse the input text to generate a number, and populate the result into item. */
301 static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
304 unsigned char *after_end = NULL;
305 unsigned char number_c_string[64];
306 unsigned char decimal_point = get_decimal_point();
309 if ((input_buffer == NULL) || (input_buffer->content == NULL))
314 /* copy the number into a temporary buffer and replace '.' with the decimal point
315 * of the current locale (for strtod)
316 * This also takes care of '\0' not necessarily being available for marking the end of the input */
317 for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
319 switch (buffer_at_offset(input_buffer)[i])
335 number_c_string[i] = buffer_at_offset(input_buffer)[i];
339 number_c_string[i] = decimal_point;
347 number_c_string[i] = '\0';
349 number = strtod((const char*)number_c_string, (char**)&after_end);
350 if (number_c_string == after_end)
352 return false; /* parse_error */
355 item->valuedouble = number;
357 /* use saturation in case of overflow */
358 if (number >= INT_MAX)
360 item->valueint = INT_MAX;
362 else if (number <= (double)INT_MIN)
364 item->valueint = INT_MIN;
368 item->valueint = (int)number;
371 item->type = cJSON_Number;
373 input_buffer->offset += (size_t)(after_end - number_c_string);
377 /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
378 CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
380 if (number >= INT_MAX)
382 object->valueint = INT_MAX;
384 else if (number <= (double)INT_MIN)
386 object->valueint = INT_MIN;
390 object->valueint = (int)number;
393 return object->valuedouble = number;
396 CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
399 /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
400 if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
404 if (strlen(valuestring) <= strlen(object->valuestring))
406 strcpy(object->valuestring, valuestring);
407 return object->valuestring;
409 copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks);
414 if (object->valuestring != NULL)
416 cJSON_free(object->valuestring);
418 object->valuestring = copy;
425 unsigned char *buffer;
428 size_t depth; /* current nesting depth (for formatted printing) */
430 cJSON_bool format; /* is this print a formatted print */
431 internal_hooks hooks;
434 /* realloc printbuffer if necessary to have at least "needed" bytes more */
435 static unsigned char* ensure(printbuffer * const p, size_t needed)
437 unsigned char *newbuffer = NULL;
440 if ((p == NULL) || (p->buffer == NULL))
445 if ((p->length > 0) && (p->offset >= p->length))
447 /* make sure that offset is valid */
451 if (needed > INT_MAX)
453 /* sizes bigger than INT_MAX are currently not supported */
457 needed += p->offset + 1;
458 if (needed <= p->length)
460 return p->buffer + p->offset;
467 /* calculate new buffer size */
468 if (needed > (INT_MAX / 2))
470 /* overflow of int, use INT_MAX if possible */
471 if (needed <= INT_MAX)
482 newsize = needed * 2;
485 if (p->hooks.reallocate != NULL)
487 /* reallocate with realloc if available */
488 newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
489 if (newbuffer == NULL)
491 p->hooks.deallocate(p->buffer);
500 /* otherwise reallocate manually */
501 newbuffer = (unsigned char*)p->hooks.allocate(newsize);
504 p->hooks.deallocate(p->buffer);
512 memcpy(newbuffer, p->buffer, p->offset + 1);
514 p->hooks.deallocate(p->buffer);
517 p->buffer = newbuffer;
519 return newbuffer + p->offset;
522 /* calculate the new length of the string in a printbuffer and update the offset */
523 static void update_offset(printbuffer * const buffer)
525 const unsigned char *buffer_pointer = NULL;
526 if ((buffer == NULL) || (buffer->buffer == NULL))
530 buffer_pointer = buffer->buffer + buffer->offset;
532 buffer->offset += strlen((const char*)buffer_pointer);
535 /* securely comparison of floating-point variables */
536 static cJSON_bool compare_double(double a, double b)
538 double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
539 return (fabs(a - b) <= maxVal * DBL_EPSILON);
542 /* Render the number nicely from the given item into a string. */
543 static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
545 unsigned char *output_pointer = NULL;
546 double d = item->valuedouble;
549 unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */
550 unsigned char decimal_point = get_decimal_point();
553 if (output_buffer == NULL)
558 /* This checks for NaN and Infinity */
559 if (isnan(d) || isinf(d))
561 length = sprintf((char*)number_buffer, "null");
565 /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
566 length = sprintf((char*)number_buffer, "%1.15g", d);
568 /* Check whether the original double can be recovered */
569 if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
571 /* If not, print with 17 decimal places of precision */
572 length = sprintf((char*)number_buffer, "%1.17g", d);
576 /* sprintf failed or buffer overrun occurred */
577 if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
582 /* reserve appropriate space in the output */
583 output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
584 if (output_pointer == NULL)
589 /* copy the printed number to the output and replace locale
590 * dependent decimal point with '.' */
591 for (i = 0; i < ((size_t)length); i++)
593 if (number_buffer[i] == decimal_point)
595 output_pointer[i] = '.';
599 output_pointer[i] = number_buffer[i];
601 output_pointer[i] = '\0';
603 output_buffer->offset += (size_t)length;
608 /* parse 4 digit hexadecimal number */
609 static unsigned parse_hex4(const unsigned char * const input)
614 for (i = 0; i < 4; i++)
617 if ((input[i] >= '0') && (input[i] <= '9'))
619 h += (unsigned int) input[i] - '0';
621 else if ((input[i] >= 'A') && (input[i] <= 'F'))
623 h += (unsigned int) 10 + input[i] - 'A';
625 else if ((input[i] >= 'a') && (input[i] <= 'f'))
627 h += (unsigned int) 10 + input[i] - 'a';
636 /* shift left to make place for the next nibble */
644 /* converts a UTF-16 literal to UTF-8
645 * A literal can be one or two sequences of the form \uXXXX */
646 static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
648 long unsigned int codepoint = 0;
649 unsigned int first_code = 0;
650 const unsigned char *first_sequence = input_pointer;
651 unsigned char utf8_length = 0;
652 unsigned char utf8_position = 0;
653 unsigned char sequence_length = 0;
654 unsigned char first_byte_mark = 0;
656 if ((input_end - first_sequence) < 6)
658 /* input ends unexpectedly */
662 /* get the first utf16 sequence */
663 first_code = parse_hex4(first_sequence + 2);
665 /* check that the code is valid */
666 if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
671 /* UTF16 surrogate pair */
672 if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
674 const unsigned char *second_sequence = first_sequence + 6;
675 unsigned int second_code = 0;
676 sequence_length = 12; /* \uXXXX\uXXXX */
678 if ((input_end - second_sequence) < 6)
680 /* input ends unexpectedly */
684 if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
686 /* missing second half of the surrogate pair */
690 /* get the second utf16 sequence */
691 second_code = parse_hex4(second_sequence + 2);
692 /* check that the code is valid */
693 if ((second_code < 0xDC00) || (second_code > 0xDFFF))
695 /* invalid second half of the surrogate pair */
700 /* calculate the unicode codepoint from the surrogate pair */
701 codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
705 sequence_length = 6; /* \uXXXX */
706 codepoint = first_code;
710 * takes at maximum 4 bytes to encode:
711 * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
712 if (codepoint < 0x80)
714 /* normal ascii, encoding 0xxxxxxx */
717 else if (codepoint < 0x800)
719 /* two bytes, encoding 110xxxxx 10xxxxxx */
721 first_byte_mark = 0xC0; /* 11000000 */
723 else if (codepoint < 0x10000)
725 /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
727 first_byte_mark = 0xE0; /* 11100000 */
729 else if (codepoint <= 0x10FFFF)
731 /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
733 first_byte_mark = 0xF0; /* 11110000 */
737 /* invalid unicode codepoint */
742 for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
745 (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
748 /* encode first byte */
751 (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
755 (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
758 *output_pointer += utf8_length;
760 return sequence_length;
766 /* Parse the input text into an unescaped cinput, and populate item. */
767 static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
769 const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
770 const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
771 unsigned char *output_pointer = NULL;
772 unsigned char *output = NULL;
775 if (buffer_at_offset(input_buffer)[0] != '\"')
781 /* calculate approximate size of the output (overestimate) */
782 size_t allocation_length = 0;
783 size_t skipped_bytes = 0;
784 while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
786 /* is escape sequence */
787 if (input_end[0] == '\\')
789 if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
791 /* prevent buffer overflow when last input character is a backslash */
799 if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
801 goto fail; /* string ended unexpectedly */
804 /* This is at most how much we need for the output */
805 allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
806 output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
809 goto fail; /* allocation failure */
813 output_pointer = output;
814 /* loop through the string literal */
815 while (input_pointer < input_end)
817 if (*input_pointer != '\\')
819 *output_pointer++ = *input_pointer++;
821 /* escape sequence */
824 unsigned char sequence_length = 2;
825 if ((input_end - input_pointer) < 1)
830 switch (input_pointer[1])
833 *output_pointer++ = '\b';
836 *output_pointer++ = '\f';
839 *output_pointer++ = '\n';
842 *output_pointer++ = '\r';
845 *output_pointer++ = '\t';
850 *output_pointer++ = input_pointer[1];
855 sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
856 if (sequence_length == 0)
858 /* failed to convert UTF16-literal to UTF-8 */
866 input_pointer += sequence_length;
870 /* zero terminate the output */
871 *output_pointer = '\0';
873 item->type = cJSON_String;
874 item->valuestring = (char*)output;
876 input_buffer->offset = (size_t) (input_end - input_buffer->content);
877 input_buffer->offset++;
884 input_buffer->hooks.deallocate(output);
887 if (input_pointer != NULL)
889 input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
895 /* Render the cstring provided to an escaped version that can be printed. */
896 static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
898 const unsigned char *input_pointer = NULL;
899 unsigned char *output = NULL;
900 unsigned char *output_pointer = NULL;
901 size_t output_length = 0;
902 /* numbers of additional characters needed for escaping */
903 size_t escape_characters = 0;
905 if (output_buffer == NULL)
913 output = ensure(output_buffer, sizeof("\"\""));
918 strcpy((char*)output, "\"\"");
923 /* set "flag" to 1 if something needs to be escaped */
924 for (input_pointer = input; *input_pointer; input_pointer++)
926 switch (*input_pointer)
935 /* one character escape sequence */
939 if (*input_pointer < 32)
941 /* UTF-16 escape sequence uXXXX */
942 escape_characters += 5;
947 output_length = (size_t)(input_pointer - input) + escape_characters;
949 output = ensure(output_buffer, output_length + sizeof("\"\""));
955 /* no characters have to be escaped */
956 if (escape_characters == 0)
959 memcpy(output + 1, input, output_length);
960 output[output_length + 1] = '\"';
961 output[output_length + 2] = '\0';
967 output_pointer = output + 1;
968 /* copy the string */
969 for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
971 if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
973 /* normal character, copy */
974 *output_pointer = *input_pointer;
978 /* character needs to be escaped */
979 *output_pointer++ = '\\';
980 switch (*input_pointer)
983 *output_pointer = '\\';
986 *output_pointer = '\"';
989 *output_pointer = 'b';
992 *output_pointer = 'f';
995 *output_pointer = 'n';
998 *output_pointer = 'r';
1001 *output_pointer = 't';
1004 /* escape and print as unicode codepoint */
1005 sprintf((char*)output_pointer, "u%04x", *input_pointer);
1006 output_pointer += 4;
1011 output[output_length + 1] = '\"';
1012 output[output_length + 2] = '\0';
1017 /* Invoke print_string_ptr (which is useful) on an item. */
1018 static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
1020 return print_string_ptr((unsigned char*)item->valuestring, p);
1023 /* Predeclare these prototypes. */
1024 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
1025 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
1026 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
1027 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
1028 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
1029 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
1031 /* Utility to jump whitespace and cr/lf */
1032 static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
1034 if ((buffer == NULL) || (buffer->content == NULL))
1039 if (cannot_access_at_index(buffer, 0))
1044 while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
1049 if (buffer->offset == buffer->length)
1057 /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
1058 static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
1060 if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
1065 if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
1067 buffer->offset += 3;
1073 CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
1075 size_t buffer_length;
1082 /* Adding null character size due to require_null_terminated. */
1083 buffer_length = strlen(value) + sizeof("");
1085 return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated);
1088 /* Parse an object - create a new root, and populate. */
1089 CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)
1091 parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
1094 /* reset error position */
1095 global_error.json = NULL;
1096 global_error.position = 0;
1098 if (value == NULL || 0 == buffer_length)
1103 buffer.content = (const unsigned char*)value;
1104 buffer.length = buffer_length;
1106 buffer.hooks = global_hooks;
1108 item = cJSON_New_Item(&global_hooks);
1109 if (item == NULL) /* memory fail */
1114 if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
1116 /* parse failure. ep is set. */
1120 /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
1121 if (require_null_terminated)
1123 buffer_skip_whitespace(&buffer);
1124 if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
1129 if (return_parse_end)
1131 *return_parse_end = (const char*)buffer_at_offset(&buffer);
1145 local_error.json = (const unsigned char*)value;
1146 local_error.position = 0;
1148 if (buffer.offset < buffer.length)
1150 local_error.position = buffer.offset;
1152 else if (buffer.length > 0)
1154 local_error.position = buffer.length - 1;
1157 if (return_parse_end != NULL)
1159 *return_parse_end = (const char*)local_error.json + local_error.position;
1162 global_error = local_error;
1168 /* Default options for cJSON_Parse */
1169 CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
1171 return cJSON_ParseWithOpts(value, 0, 0);
1174 CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length)
1176 return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0);
1179 #define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
1181 static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
1183 static const size_t default_buffer_size = 256;
1184 printbuffer buffer[1];
1185 unsigned char *printed = NULL;
1187 memset(buffer, 0, sizeof(buffer));
1190 buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
1191 buffer->length = default_buffer_size;
1192 buffer->format = format;
1193 buffer->hooks = *hooks;
1194 if (buffer->buffer == NULL)
1199 /* print the value */
1200 if (!print_value(item, buffer))
1204 update_offset(buffer);
1206 /* check if reallocate is available */
1207 if (hooks->reallocate != NULL)
1209 printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
1210 if (printed == NULL) {
1213 buffer->buffer = NULL;
1215 else /* otherwise copy the JSON over to a new buffer */
1217 printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
1218 if (printed == NULL)
1222 memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
1223 printed[buffer->offset] = '\0'; /* just to be sure */
1225 /* free the buffer */
1226 hooks->deallocate(buffer->buffer);
1232 if (buffer->buffer != NULL)
1234 hooks->deallocate(buffer->buffer);
1237 if (printed != NULL)
1239 hooks->deallocate(printed);
1245 /* Render a cJSON item/entity/structure to text. */
1246 CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
1248 return (char*)print(item, true, &global_hooks);
1251 CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
1253 return (char*)print(item, false, &global_hooks);
1256 CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
1258 printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1265 p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
1271 p.length = (size_t)prebuffer;
1275 p.hooks = global_hooks;
1277 if (!print_value(item, &p))
1279 global_hooks.deallocate(p.buffer);
1283 return (char*)p.buffer;
1286 CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)
1288 printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1290 if ((length < 0) || (buffer == NULL))
1295 p.buffer = (unsigned char*)buffer;
1296 p.length = (size_t)length;
1300 p.hooks = global_hooks;
1302 return print_value(item, &p);
1305 /* Parser core - when encountering text, process appropriately. */
1306 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
1308 if ((input_buffer == NULL) || (input_buffer->content == NULL))
1310 return false; /* no input */
1313 /* parse the different types of values */
1315 if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
1317 item->type = cJSON_NULL;
1318 input_buffer->offset += 4;
1322 if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
1324 item->type = cJSON_False;
1325 input_buffer->offset += 5;
1329 if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
1331 item->type = cJSON_True;
1333 input_buffer->offset += 4;
1337 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
1339 return parse_string(item, input_buffer);
1342 if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9'))))
1344 return parse_number(item, input_buffer);
1347 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
1349 return parse_array(item, input_buffer);
1352 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
1354 return parse_object(item, input_buffer);
1360 /* Render a value to text. */
1361 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
1363 unsigned char *output = NULL;
1365 if ((item == NULL) || (output_buffer == NULL))
1370 switch ((item->type) & 0xFF)
1373 output = ensure(output_buffer, 5);
1378 strcpy((char*)output, "null");
1382 output = ensure(output_buffer, 6);
1387 strcpy((char*)output, "false");
1391 output = ensure(output_buffer, 5);
1396 strcpy((char*)output, "true");
1400 return print_number(item, output_buffer);
1404 size_t raw_length = 0;
1405 if (item->valuestring == NULL)
1410 raw_length = strlen(item->valuestring) + sizeof("");
1411 output = ensure(output_buffer, raw_length);
1416 memcpy(output, item->valuestring, raw_length);
1421 return print_string(item, output_buffer);
1424 return print_array(item, output_buffer);
1427 return print_object(item, output_buffer);
1434 /* Build an array from input text. */
1435 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
1437 cJSON *head = NULL; /* head of the linked list */
1438 cJSON *current_item = NULL;
1440 if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1442 return false; /* to deeply nested */
1444 input_buffer->depth++;
1446 if (buffer_at_offset(input_buffer)[0] != '[')
1452 input_buffer->offset++;
1453 buffer_skip_whitespace(input_buffer);
1454 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
1460 /* check if we skipped to the end of the buffer */
1461 if (cannot_access_at_index(input_buffer, 0))
1463 input_buffer->offset--;
1467 /* step back to character in front of the first element */
1468 input_buffer->offset--;
1469 /* loop through the comma separated array elements */
1472 /* allocate next item */
1473 cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1474 if (new_item == NULL)
1476 goto fail; /* allocation failure */
1479 /* attach next item to list */
1482 /* start the linked list */
1483 current_item = head = new_item;
1487 /* add to the end and advance */
1488 current_item->next = new_item;
1489 new_item->prev = current_item;
1490 current_item = new_item;
1493 /* parse next value */
1494 input_buffer->offset++;
1495 buffer_skip_whitespace(input_buffer);
1496 if (!parse_value(current_item, input_buffer))
1498 goto fail; /* failed to parse value */
1500 buffer_skip_whitespace(input_buffer);
1502 while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1504 if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
1506 goto fail; /* expected end of array */
1510 input_buffer->depth--;
1513 head->prev = current_item;
1516 item->type = cJSON_Array;
1519 input_buffer->offset++;
1532 /* Render an array to text */
1533 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
1535 unsigned char *output_pointer = NULL;
1537 cJSON *current_element = item->child;
1539 if (output_buffer == NULL)
1544 /* Compose the output array. */
1545 /* opening square bracket */
1546 output_pointer = ensure(output_buffer, 1);
1547 if (output_pointer == NULL)
1552 *output_pointer = '[';
1553 output_buffer->offset++;
1554 output_buffer->depth++;
1556 while (current_element != NULL)
1558 if (!print_value(current_element, output_buffer))
1562 update_offset(output_buffer);
1563 if (current_element->next)
1565 length = (size_t) (output_buffer->format ? 2 : 1);
1566 output_pointer = ensure(output_buffer, length + 1);
1567 if (output_pointer == NULL)
1571 *output_pointer++ = ',';
1572 if(output_buffer->format)
1574 *output_pointer++ = ' ';
1576 *output_pointer = '\0';
1577 output_buffer->offset += length;
1579 current_element = current_element->next;
1582 output_pointer = ensure(output_buffer, 2);
1583 if (output_pointer == NULL)
1587 *output_pointer++ = ']';
1588 *output_pointer = '\0';
1589 output_buffer->depth--;
1594 /* Build an object from the text. */
1595 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
1597 cJSON *head = NULL; /* linked list head */
1598 cJSON *current_item = NULL;
1600 if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1602 return false; /* to deeply nested */
1604 input_buffer->depth++;
1606 if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
1608 goto fail; /* not an object */
1611 input_buffer->offset++;
1612 buffer_skip_whitespace(input_buffer);
1613 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
1615 goto success; /* empty object */
1618 /* check if we skipped to the end of the buffer */
1619 if (cannot_access_at_index(input_buffer, 0))
1621 input_buffer->offset--;
1625 /* step back to character in front of the first element */
1626 input_buffer->offset--;
1627 /* loop through the comma separated array elements */
1630 /* allocate next item */
1631 cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1632 if (new_item == NULL)
1634 goto fail; /* allocation failure */
1637 /* attach next item to list */
1640 /* start the linked list */
1641 current_item = head = new_item;
1645 /* add to the end and advance */
1646 current_item->next = new_item;
1647 new_item->prev = current_item;
1648 current_item = new_item;
1651 /* parse the name of the child */
1652 input_buffer->offset++;
1653 buffer_skip_whitespace(input_buffer);
1654 if (!parse_string(current_item, input_buffer))
1656 goto fail; /* failed to parse name */
1658 buffer_skip_whitespace(input_buffer);
1660 /* swap valuestring and string, because we parsed the name */
1661 current_item->string = current_item->valuestring;
1662 current_item->valuestring = NULL;
1664 if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
1666 goto fail; /* invalid object */
1669 /* parse the value */
1670 input_buffer->offset++;
1671 buffer_skip_whitespace(input_buffer);
1672 if (!parse_value(current_item, input_buffer))
1674 goto fail; /* failed to parse value */
1676 buffer_skip_whitespace(input_buffer);
1678 while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1680 if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
1682 goto fail; /* expected end of object */
1686 input_buffer->depth--;
1689 head->prev = current_item;
1692 item->type = cJSON_Object;
1695 input_buffer->offset++;
1707 /* Render an object to text. */
1708 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
1710 unsigned char *output_pointer = NULL;
1712 cJSON *current_item = item->child;
1714 if (output_buffer == NULL)
1719 /* Compose the output: */
1720 length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
1721 output_pointer = ensure(output_buffer, length + 1);
1722 if (output_pointer == NULL)
1727 *output_pointer++ = '{';
1728 output_buffer->depth++;
1729 if (output_buffer->format)
1731 *output_pointer++ = '\n';
1733 output_buffer->offset += length;
1735 while (current_item)
1737 if (output_buffer->format)
1740 output_pointer = ensure(output_buffer, output_buffer->depth);
1741 if (output_pointer == NULL)
1745 for (i = 0; i < output_buffer->depth; i++)
1747 *output_pointer++ = '\t';
1749 output_buffer->offset += output_buffer->depth;
1753 if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
1757 update_offset(output_buffer);
1759 length = (size_t) (output_buffer->format ? 2 : 1);
1760 output_pointer = ensure(output_buffer, length);
1761 if (output_pointer == NULL)
1765 *output_pointer++ = ':';
1766 if (output_buffer->format)
1768 *output_pointer++ = '\t';
1770 output_buffer->offset += length;
1773 if (!print_value(current_item, output_buffer))
1777 update_offset(output_buffer);
1779 /* print comma if not last */
1780 length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
1781 output_pointer = ensure(output_buffer, length + 1);
1782 if (output_pointer == NULL)
1786 if (current_item->next)
1788 *output_pointer++ = ',';
1791 if (output_buffer->format)
1793 *output_pointer++ = '\n';
1795 *output_pointer = '\0';
1796 output_buffer->offset += length;
1798 current_item = current_item->next;
1801 output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
1802 if (output_pointer == NULL)
1806 if (output_buffer->format)
1809 for (i = 0; i < (output_buffer->depth - 1); i++)
1811 *output_pointer++ = '\t';
1814 *output_pointer++ = '}';
1815 *output_pointer = '\0';
1816 output_buffer->depth--;
1821 /* Get Array size/item / object item. */
1822 CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
1824 cJSON *child = NULL;
1832 child = array->child;
1834 while(child != NULL)
1837 child = child->next;
1840 /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
1845 static cJSON* get_array_item(const cJSON *array, size_t index)
1847 cJSON *current_child = NULL;
1854 current_child = array->child;
1855 while ((current_child != NULL) && (index > 0))
1858 current_child = current_child->next;
1861 return current_child;
1864 CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
1871 return get_array_item(array, (size_t)index);
1874 static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
1876 cJSON *current_element = NULL;
1878 if ((object == NULL) || (name == NULL))
1883 current_element = object->child;
1886 while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
1888 current_element = current_element->next;
1893 while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
1895 current_element = current_element->next;
1899 if ((current_element == NULL) || (current_element->string == NULL)) {
1903 return current_element;
1906 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
1908 return get_object_item(object, string, false);
1911 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
1913 return get_object_item(object, string, true);
1916 CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
1918 return cJSON_GetObjectItem(object, string) ? 1 : 0;
1921 /* Utility for array list handling. */
1922 static void suffix_object(cJSON *prev, cJSON *item)
1928 /* Utility for handling references. */
1929 static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
1931 cJSON *reference = NULL;
1937 reference = cJSON_New_Item(hooks);
1938 if (reference == NULL)
1943 memcpy(reference, item, sizeof(cJSON));
1944 reference->string = NULL;
1945 reference->type |= cJSON_IsReference;
1946 reference->next = reference->prev = NULL;
1950 static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
1952 cJSON *child = NULL;
1954 if ((item == NULL) || (array == NULL) || (array == item))
1959 child = array->child;
1961 * To find the last item in array quickly, we use prev in array
1965 /* list is empty, start new one */
1966 array->child = item;
1972 /* append to the end */
1975 suffix_object(child->prev, item);
1976 array->child->prev = item;
1983 /* Add item to array/object. */
1984 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
1986 return add_item_to_array(array, item);
1989 #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
1990 #pragma GCC diagnostic push
1993 #pragma GCC diagnostic ignored "-Wcast-qual"
1995 /* helper function to cast away const */
1996 static void* cast_away_const(const void* string)
1998 return (void*)string;
2000 #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
2001 #pragma GCC diagnostic pop
2005 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)
2007 char *new_key = NULL;
2008 int new_type = cJSON_Invalid;
2010 if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item))
2017 new_key = (char*)cast_away_const(string);
2018 new_type = item->type | cJSON_StringIsConst;
2022 new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
2023 if (new_key == NULL)
2028 new_type = item->type & ~cJSON_StringIsConst;
2031 if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
2033 hooks->deallocate(item->string);
2036 item->string = new_key;
2037 item->type = new_type;
2039 return add_item_to_array(object, item);
2042 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
2044 return add_item_to_object(object, string, item, &global_hooks, false);
2047 /* Add an item to an object with constant string as key */
2048 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
2050 return add_item_to_object(object, string, item, &global_hooks, true);
2053 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
2060 return add_item_to_array(array, create_reference(item, &global_hooks));
2063 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
2065 if ((object == NULL) || (string == NULL))
2070 return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
2073 CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
2075 cJSON *null = cJSON_CreateNull();
2076 if (add_item_to_object(object, name, null, &global_hooks, false))
2085 CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
2087 cJSON *true_item = cJSON_CreateTrue();
2088 if (add_item_to_object(object, name, true_item, &global_hooks, false))
2093 cJSON_Delete(true_item);
2097 CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
2099 cJSON *false_item = cJSON_CreateFalse();
2100 if (add_item_to_object(object, name, false_item, &global_hooks, false))
2105 cJSON_Delete(false_item);
2109 CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
2111 cJSON *bool_item = cJSON_CreateBool(boolean);
2112 if (add_item_to_object(object, name, bool_item, &global_hooks, false))
2117 cJSON_Delete(bool_item);
2121 CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
2123 cJSON *number_item = cJSON_CreateNumber(number);
2124 if (add_item_to_object(object, name, number_item, &global_hooks, false))
2129 cJSON_Delete(number_item);
2133 CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
2135 cJSON *string_item = cJSON_CreateString(string);
2136 if (add_item_to_object(object, name, string_item, &global_hooks, false))
2141 cJSON_Delete(string_item);
2145 CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
2147 cJSON *raw_item = cJSON_CreateRaw(raw);
2148 if (add_item_to_object(object, name, raw_item, &global_hooks, false))
2153 cJSON_Delete(raw_item);
2157 CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
2159 cJSON *object_item = cJSON_CreateObject();
2160 if (add_item_to_object(object, name, object_item, &global_hooks, false))
2165 cJSON_Delete(object_item);
2169 CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
2171 cJSON *array = cJSON_CreateArray();
2172 if (add_item_to_object(object, name, array, &global_hooks, false))
2177 cJSON_Delete(array);
2181 CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
2183 if ((parent == NULL) || (item == NULL))
2188 if (item != parent->child)
2190 /* not the first element */
2191 item->prev->next = item->next;
2193 if (item->next != NULL)
2195 /* not the last element */
2196 item->next->prev = item->prev;
2199 if (item == parent->child)
2202 parent->child = item->next;
2204 else if (item->next == NULL)
2207 parent->child->prev = item->prev;
2210 /* make sure the detached item doesn't point anywhere anymore */
2217 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
2224 return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
2227 CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
2229 cJSON_Delete(cJSON_DetachItemFromArray(array, which));
2232 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
2234 cJSON *to_detach = cJSON_GetObjectItem(object, string);
2236 return cJSON_DetachItemViaPointer(object, to_detach);
2239 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
2241 cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
2243 return cJSON_DetachItemViaPointer(object, to_detach);
2246 CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
2248 cJSON_Delete(cJSON_DetachItemFromObject(object, string));
2251 CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
2253 cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
2256 /* Replace array/object items with new ones. */
2257 CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
2259 cJSON *after_inserted = NULL;
2266 after_inserted = get_array_item(array, (size_t)which);
2267 if (after_inserted == NULL)
2269 return add_item_to_array(array, newitem);
2272 newitem->next = after_inserted;
2273 newitem->prev = after_inserted->prev;
2274 after_inserted->prev = newitem;
2275 if (after_inserted == array->child)
2277 array->child = newitem;
2281 newitem->prev->next = newitem;
2286 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2288 if ((parent == NULL) || (replacement == NULL) || (item == NULL))
2293 if (replacement == item)
2298 replacement->next = item->next;
2299 replacement->prev = item->prev;
2301 if (replacement->next != NULL)
2303 replacement->next->prev = replacement;
2305 if (parent->child == item)
2307 if (parent->child->prev == parent->child)
2309 replacement->prev = replacement;
2311 parent->child = replacement;
2315 * To find the last item in array quickly, we use prev in array.
2316 * We can't modify the last item's next pointer where this item was the parent's child
2318 if (replacement->prev != NULL)
2320 replacement->prev->next = replacement;
2322 if (replacement->next == NULL)
2324 parent->child->prev = replacement;
2335 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
2342 return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
2345 static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
2347 if ((replacement == NULL) || (string == NULL))
2352 /* replace the name in the replacement */
2353 if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
2355 cJSON_free(replacement->string);
2357 replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2358 replacement->type &= ~cJSON_StringIsConst;
2360 return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
2363 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
2365 return replace_item_in_object(object, string, newitem, false);
2368 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
2370 return replace_item_in_object(object, string, newitem, true);
2373 /* Create basic types: */
2374 CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
2376 cJSON *item = cJSON_New_Item(&global_hooks);
2379 item->type = cJSON_NULL;
2385 CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
2387 cJSON *item = cJSON_New_Item(&global_hooks);
2390 item->type = cJSON_True;
2396 CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
2398 cJSON *item = cJSON_New_Item(&global_hooks);
2401 item->type = cJSON_False;
2407 CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
2409 cJSON *item = cJSON_New_Item(&global_hooks);
2412 item->type = boolean ? cJSON_True : cJSON_False;
2418 CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
2420 cJSON *item = cJSON_New_Item(&global_hooks);
2423 item->type = cJSON_Number;
2424 item->valuedouble = num;
2426 /* use saturation in case of overflow */
2429 item->valueint = INT_MAX;
2431 else if (num <= (double)INT_MIN)
2433 item->valueint = INT_MIN;
2437 item->valueint = (int)num;
2444 CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
2446 cJSON *item = cJSON_New_Item(&global_hooks);
2449 item->type = cJSON_String;
2450 item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2451 if(!item->valuestring)
2461 CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
2463 cJSON *item = cJSON_New_Item(&global_hooks);
2466 item->type = cJSON_String | cJSON_IsReference;
2467 item->valuestring = (char*)cast_away_const(string);
2473 CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
2475 cJSON *item = cJSON_New_Item(&global_hooks);
2477 item->type = cJSON_Object | cJSON_IsReference;
2478 item->child = (cJSON*)cast_away_const(child);
2484 CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
2485 cJSON *item = cJSON_New_Item(&global_hooks);
2487 item->type = cJSON_Array | cJSON_IsReference;
2488 item->child = (cJSON*)cast_away_const(child);
2494 CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
2496 cJSON *item = cJSON_New_Item(&global_hooks);
2499 item->type = cJSON_Raw;
2500 item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
2501 if(!item->valuestring)
2511 CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
2513 cJSON *item = cJSON_New_Item(&global_hooks);
2516 item->type=cJSON_Array;
2522 CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
2524 cJSON *item = cJSON_New_Item(&global_hooks);
2527 item->type = cJSON_Object;
2533 /* Create Arrays: */
2534 CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
2541 if ((count < 0) || (numbers == NULL))
2546 a = cJSON_CreateArray();
2547 for(i = 0; a && (i < (size_t)count); i++)
2549 n = cJSON_CreateNumber(numbers[i]);
2561 suffix_object(p, n);
2570 CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
2577 if ((count < 0) || (numbers == NULL))
2582 a = cJSON_CreateArray();
2584 for(i = 0; a && (i < (size_t)count); i++)
2586 n = cJSON_CreateNumber((double)numbers[i]);
2598 suffix_object(p, n);
2607 CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
2614 if ((count < 0) || (numbers == NULL))
2619 a = cJSON_CreateArray();
2621 for(i = 0;a && (i < (size_t)count); i++)
2623 n = cJSON_CreateNumber(numbers[i]);
2635 suffix_object(p, n);
2644 CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count)
2651 if ((count < 0) || (strings == NULL))
2656 a = cJSON_CreateArray();
2658 for (i = 0; a && (i < (size_t)count); i++)
2660 n = cJSON_CreateString(strings[i]);
2682 CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
2684 cJSON *newitem = NULL;
2685 cJSON *child = NULL;
2687 cJSON *newchild = NULL;
2689 /* Bail on bad ptr */
2694 /* Create new item */
2695 newitem = cJSON_New_Item(&global_hooks);
2700 /* Copy over all vars */
2701 newitem->type = item->type & (~cJSON_IsReference);
2702 newitem->valueint = item->valueint;
2703 newitem->valuedouble = item->valuedouble;
2704 if (item->valuestring)
2706 newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
2707 if (!newitem->valuestring)
2714 newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
2715 if (!newitem->string)
2720 /* If non-recursive, then we're done! */
2725 /* Walk the ->next chain for the child. */
2726 child = item->child;
2727 while (child != NULL)
2729 newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
2736 /* If newitem->child already set, then crosswire ->prev and ->next and move on */
2737 next->next = newchild;
2738 newchild->prev = next;
2743 /* Set newitem->child and move to it */
2744 newitem->child = newchild;
2747 child = child->next;
2749 if (newitem && newitem->child)
2751 newitem->child->prev = newchild;
2757 if (newitem != NULL)
2759 cJSON_Delete(newitem);
2765 static void skip_oneline_comment(char **input)
2767 *input += static_strlen("//");
2769 for (; (*input)[0] != '\0'; ++(*input))
2771 if ((*input)[0] == '\n') {
2772 *input += static_strlen("\n");
2778 static void skip_multiline_comment(char **input)
2780 *input += static_strlen("/*");
2782 for (; (*input)[0] != '\0'; ++(*input))
2784 if (((*input)[0] == '*') && ((*input)[1] == '/'))
2786 *input += static_strlen("*/");
2792 static void minify_string(char **input, char **output) {
2793 (*output)[0] = (*input)[0];
2794 *input += static_strlen("\"");
2795 *output += static_strlen("\"");
2798 for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
2799 (*output)[0] = (*input)[0];
2801 if ((*input)[0] == '\"') {
2802 (*output)[0] = '\"';
2803 *input += static_strlen("\"");
2804 *output += static_strlen("\"");
2806 } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
2807 (*output)[1] = (*input)[1];
2808 *input += static_strlen("\"");
2809 *output += static_strlen("\"");
2814 CJSON_PUBLIC(void) cJSON_Minify(char *json)
2823 while (json[0] != '\0')
2837 skip_oneline_comment(&json);
2839 else if (json[1] == '*')
2841 skip_multiline_comment(&json);
2848 minify_string(&json, (char**)&into);
2858 /* and null-terminate. */
2862 CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
2869 return (item->type & 0xFF) == cJSON_Invalid;
2872 CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
2879 return (item->type & 0xFF) == cJSON_False;
2882 CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
2889 return (item->type & 0xff) == cJSON_True;
2893 CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
2900 return (item->type & (cJSON_True | cJSON_False)) != 0;
2902 CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
2909 return (item->type & 0xFF) == cJSON_NULL;
2912 CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
2919 return (item->type & 0xFF) == cJSON_Number;
2922 CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
2929 return (item->type & 0xFF) == cJSON_String;
2932 CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
2939 return (item->type & 0xFF) == cJSON_Array;
2942 CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
2949 return (item->type & 0xFF) == cJSON_Object;
2952 CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
2959 return (item->type & 0xFF) == cJSON_Raw;
2962 CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
2964 if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
2969 /* check if type is valid */
2970 switch (a->type & 0xFF)
2986 /* identical objects are equal */
2992 switch (a->type & 0xFF)
2994 /* in these cases and equal type is enough */
3001 if (compare_double(a->valuedouble, b->valuedouble))
3009 if ((a->valuestring == NULL) || (b->valuestring == NULL))
3013 if (strcmp(a->valuestring, b->valuestring) == 0)
3022 cJSON *a_element = a->child;
3023 cJSON *b_element = b->child;
3025 for (; (a_element != NULL) && (b_element != NULL);)
3027 if (!cJSON_Compare(a_element, b_element, case_sensitive))
3032 a_element = a_element->next;
3033 b_element = b_element->next;
3036 /* one of the arrays is longer than the other */
3037 if (a_element != b_element) {
3046 cJSON *a_element = NULL;
3047 cJSON *b_element = NULL;
3048 cJSON_ArrayForEach(a_element, a)
3050 /* TODO This has O(n^2) runtime, which is horrible! */
3051 b_element = get_object_item(b, a_element->string, case_sensitive);
3052 if (b_element == NULL)
3057 if (!cJSON_Compare(a_element, b_element, case_sensitive))
3063 /* doing this twice, once on a and b to prevent true comparison if a subset of b
3064 * TODO: Do this the proper way, this is just a fix for now */
3065 cJSON_ArrayForEach(b_element, b)
3067 a_element = get_object_item(a, b_element->string, case_sensitive);
3068 if (a_element == NULL)
3073 if (!cJSON_Compare(b_element, a_element, case_sensitive))
3087 CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
3089 return global_hooks.allocate(size);
3092 CJSON_PUBLIC(void) cJSON_free(void *object)
3094 global_hooks.deallocate(object);