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
22 /* clang-format off */
25 /* JSON parser in C. */
27 /* disable warnings about old C89 functions in MSVC */
28 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
29 #define _CRT_SECURE_NO_DEPRECATE
33 #pragma GCC visibility push(default)
36 #pragma warning (push)
37 /* disable warning about single line comments in system headers */
38 #pragma warning (disable : 4001)
57 #pragma GCC visibility pop
62 /* define our own boolean type */
66 #define true ((cJSON_bool)1)
71 #define false ((cJSON_bool)0)
73 /* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */
75 #define isinf(d) (isnan((d - d)) && !isnan(d))
78 #define isnan(d) (d != d)
83 #define NAN sqrt (-1.0)
90 const unsigned char *json;
93 static error global_error = { NULL, 0 };
95 CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
97 return (const char*) (global_error.json + global_error.position);
100 CJSON_PUBLIC (char *) cJSON_GetStringValue (const cJSON *const item)
102 if (!cJSON_IsString (item))
107 return item->valuestring;
110 CJSON_PUBLIC (double) cJSON_GetNumberValue (const cJSON *const item)
112 if (!cJSON_IsNumber (item))
117 return item->valuedouble;
120 /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
121 #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || \
122 (CJSON_VERSION_PATCH != 17)
123 #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
126 CJSON_PUBLIC(const char*) cJSON_Version(void)
128 static char version[15];
129 sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
134 /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
135 static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
137 if ((string1 == NULL) || (string2 == NULL))
142 if (string1 == string2)
147 for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
149 if (*string1 == '\0')
155 return tolower(*string1) - tolower(*string2);
158 typedef struct internal_hooks
160 void *(CJSON_CDECL *allocate)(size_t size);
161 void (CJSON_CDECL *deallocate)(void *pointer);
162 void *(CJSON_CDECL *reallocate) (void *pointer, size_t size);
165 #if defined(_MSC_VER)
166 /* work around MSVC error C2322: '...' address of dllimport '...' is not static */
167 static void * CJSON_CDECL internal_malloc(size_t size)
171 static void CJSON_CDECL internal_free(void *pointer)
175 static void *CJSON_CDECL
176 internal_realloc (void *pointer, size_t size)
178 return realloc (pointer, size);
181 #define internal_malloc malloc
182 #define internal_free free
183 #define internal_realloc realloc
186 /* strlen of character literals resolved at compile time */
187 #define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
189 static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
191 static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
194 unsigned char *copy = NULL;
201 length = strlen((const char*)string) + sizeof("");
202 copy = (unsigned char*)hooks->allocate(length);
207 memcpy(copy, string, length);
212 CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
217 global_hooks.allocate = malloc;
218 global_hooks.deallocate = free;
219 global_hooks.reallocate = realloc;
223 global_hooks.allocate = malloc;
224 if (hooks->malloc_fn != NULL)
226 global_hooks.allocate = hooks->malloc_fn;
229 global_hooks.deallocate = free;
230 if (hooks->free_fn != NULL)
232 global_hooks.deallocate = hooks->free_fn;
235 global_hooks.reallocate = realloc;
236 if (hooks->realloc_fn != NULL)
238 global_hooks.reallocate = hooks->realloc_fn;
242 /* Internal constructor. */
243 static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
245 cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
248 memset(node, '\0', sizeof(cJSON));
254 /* Delete a cJSON structure. */
255 CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
261 if (!(item->type & cJSON_IsReference) && (item->child != NULL))
263 cJSON_Delete(item->child);
265 if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
267 global_hooks.deallocate(item->valuestring);
269 if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
271 global_hooks.deallocate(item->string);
273 global_hooks.deallocate(item);
278 /* get the decimal point character of the current locale */
279 static unsigned char get_decimal_point(void)
281 #ifdef ENABLE_LOCALES
282 struct lconv *lconv = localeconv();
283 return (unsigned char) lconv->decimal_point[0];
291 const unsigned char *content;
294 size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
295 internal_hooks hooks;
298 /* check if the given size is left to read in a given parse buffer (starting with 1) */
299 #define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
300 /* check if the buffer can be accessed at the given index (starting with 0) */
301 #define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
302 #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
303 /* get a pointer to the buffer at the position */
304 #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
306 /* Parse the input text to generate a number, and populate the result into item. */
307 static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
310 unsigned char *after_end = NULL;
311 unsigned char number_c_string[64];
312 unsigned char decimal_point = get_decimal_point();
315 if ((input_buffer == NULL) || (input_buffer->content == NULL))
320 /* copy the number into a temporary buffer and replace '.' with the decimal point
321 * of the current locale (for strtod)
322 * This also takes care of '\0' not necessarily being available for marking the end of the input */
323 for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
325 switch (buffer_at_offset(input_buffer)[i])
341 number_c_string[i] = buffer_at_offset(input_buffer)[i];
345 number_c_string[i] = decimal_point;
353 number_c_string[i] = '\0';
355 number = strtod((const char*)number_c_string, (char**)&after_end);
356 if (number_c_string == after_end)
358 return false; /* parse_error */
361 item->valuedouble = number;
363 /* use saturation in case of overflow */
364 if (number >= INT_MAX)
366 item->valueint = INT_MAX;
368 else if (number <= (double)INT_MIN)
370 item->valueint = INT_MIN;
374 item->valueint = (int)number;
377 item->type = cJSON_Number;
379 input_buffer->offset += (size_t)(after_end - number_c_string);
383 /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
384 CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
386 if (number >= INT_MAX)
388 object->valueint = INT_MAX;
390 else if (number <= (double)INT_MIN)
392 object->valueint = INT_MIN;
396 object->valueint = (int)number;
399 return object->valuedouble = number;
402 /* Note: when passing a NULL valuestring, cJSON_SetValuestring treats this as
403 * an error and return NULL */
404 CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
407 /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
408 if ((object == NULL) || !(object->type & cJSON_String) ||
409 (object->type & cJSON_IsReference))
413 /* return NULL if the object is corrupted or valuestring is NULL */
414 if (object->valuestring == NULL || valuestring == NULL)
418 if (strlen(valuestring) <= strlen(object->valuestring))
420 strcpy(object->valuestring, valuestring);
421 return object->valuestring;
423 copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks);
428 if (object->valuestring != NULL)
430 cJSON_free(object->valuestring);
432 object->valuestring = copy;
439 unsigned char *buffer;
442 size_t depth; /* current nesting depth (for formatted printing) */
444 cJSON_bool format; /* is this print a formatted print */
445 internal_hooks hooks;
448 /* realloc printbuffer if necessary to have at least "needed" bytes more */
449 static unsigned char* ensure(printbuffer * const p, size_t needed)
451 unsigned char *newbuffer = NULL;
454 if ((p == NULL) || (p->buffer == NULL))
459 if ((p->length > 0) && (p->offset >= p->length))
461 /* make sure that offset is valid */
465 if (needed > INT_MAX)
467 /* sizes bigger than INT_MAX are currently not supported */
471 needed += p->offset + 1;
472 if (needed <= p->length)
474 return p->buffer + p->offset;
481 /* calculate new buffer size */
482 if (needed > (INT_MAX / 2))
484 /* overflow of int, use INT_MAX if possible */
485 if (needed <= INT_MAX)
496 newsize = needed * 2;
499 if (p->hooks.reallocate != NULL)
501 /* reallocate with realloc if available */
502 newbuffer = (unsigned char *) p->hooks.reallocate (p->buffer, newsize);
503 if (newbuffer == NULL)
505 p->hooks.deallocate (p->buffer);
514 /* otherwise reallocate manually */
515 newbuffer = (unsigned char *) p->hooks.allocate (newsize);
518 p->hooks.deallocate (p->buffer);
525 memcpy (newbuffer, p->buffer, p->offset + 1);
526 p->hooks.deallocate (p->buffer);
529 p->buffer = newbuffer;
531 return newbuffer + p->offset;
534 /* calculate the new length of the string in a printbuffer and update the offset */
535 static void update_offset(printbuffer * const buffer)
537 const unsigned char *buffer_pointer = NULL;
538 if ((buffer == NULL) || (buffer->buffer == NULL))
542 buffer_pointer = buffer->buffer + buffer->offset;
544 buffer->offset += strlen((const char*)buffer_pointer);
547 /* securely comparison of floating-point variables */
548 static cJSON_bool compare_double(double a, double b)
550 double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
551 return (fabs(a - b) <= maxVal * DBL_EPSILON);
554 /* Render the number nicely from the given item into a string. */
555 static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
557 unsigned char *output_pointer = NULL;
558 double d = item->valuedouble;
561 unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */
562 unsigned char decimal_point = get_decimal_point();
565 if (output_buffer == NULL)
570 /* This checks for NaN and Infinity */
571 if (isnan(d) || isinf(d))
573 length = sprintf((char*)number_buffer, "null");
575 else if (d == (double) item->valueint)
577 length = sprintf ((char *) number_buffer, "%d", item->valueint);
581 /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
582 length = sprintf((char*)number_buffer, "%1.15g", d);
584 /* Check whether the original double can be recovered */
585 if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
587 /* If not, print with 17 decimal places of precision */
588 length = sprintf((char*)number_buffer, "%1.17g", d);
592 /* sprintf failed or buffer overrun occurred */
593 if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
598 /* reserve appropriate space in the output */
599 output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
600 if (output_pointer == NULL)
605 /* copy the printed number to the output and replace locale
606 * dependent decimal point with '.' */
607 for (i = 0; i < ((size_t)length); i++)
609 if (number_buffer[i] == decimal_point)
611 output_pointer[i] = '.';
615 output_pointer[i] = number_buffer[i];
617 output_pointer[i] = '\0';
619 output_buffer->offset += (size_t)length;
624 /* parse 4 digit hexadecimal number */
625 static unsigned parse_hex4(const unsigned char * const input)
630 for (i = 0; i < 4; i++)
633 if ((input[i] >= '0') && (input[i] <= '9'))
635 h += (unsigned int) input[i] - '0';
637 else if ((input[i] >= 'A') && (input[i] <= 'F'))
639 h += (unsigned int) 10 + input[i] - 'A';
641 else if ((input[i] >= 'a') && (input[i] <= 'f'))
643 h += (unsigned int) 10 + input[i] - 'a';
652 /* shift left to make place for the next nibble */
660 /* converts a UTF-16 literal to UTF-8
661 * A literal can be one or two sequences of the form \uXXXX */
662 static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
664 long unsigned int codepoint = 0;
665 unsigned int first_code = 0;
666 const unsigned char *first_sequence = input_pointer;
667 unsigned char utf8_length = 0;
668 unsigned char utf8_position = 0;
669 unsigned char sequence_length = 0;
670 unsigned char first_byte_mark = 0;
672 if ((input_end - first_sequence) < 6)
674 /* input ends unexpectedly */
678 /* get the first utf16 sequence */
679 first_code = parse_hex4(first_sequence + 2);
681 /* check that the code is valid */
682 if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
687 /* UTF16 surrogate pair */
688 if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
690 const unsigned char *second_sequence = first_sequence + 6;
691 unsigned int second_code = 0;
692 sequence_length = 12; /* \uXXXX\uXXXX */
694 if ((input_end - second_sequence) < 6)
696 /* input ends unexpectedly */
700 if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
702 /* missing second half of the surrogate pair */
706 /* get the second utf16 sequence */
707 second_code = parse_hex4(second_sequence + 2);
708 /* check that the code is valid */
709 if ((second_code < 0xDC00) || (second_code > 0xDFFF))
711 /* invalid second half of the surrogate pair */
716 /* calculate the unicode codepoint from the surrogate pair */
717 codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
721 sequence_length = 6; /* \uXXXX */
722 codepoint = first_code;
726 * takes at maximum 4 bytes to encode:
727 * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
728 if (codepoint < 0x80)
730 /* normal ascii, encoding 0xxxxxxx */
733 else if (codepoint < 0x800)
735 /* two bytes, encoding 110xxxxx 10xxxxxx */
737 first_byte_mark = 0xC0; /* 11000000 */
739 else if (codepoint < 0x10000)
741 /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
743 first_byte_mark = 0xE0; /* 11100000 */
745 else if (codepoint <= 0x10FFFF)
747 /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
749 first_byte_mark = 0xF0; /* 11110000 */
753 /* invalid unicode codepoint */
758 for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
761 (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
764 /* encode first byte */
767 (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
771 (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
774 *output_pointer += utf8_length;
776 return sequence_length;
782 /* Parse the input text into an unescaped cinput, and populate item. */
783 static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
785 const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
786 const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
787 unsigned char *output_pointer = NULL;
788 unsigned char *output = NULL;
791 if (buffer_at_offset(input_buffer)[0] != '\"')
797 /* calculate approximate size of the output (overestimate) */
798 size_t allocation_length = 0;
799 size_t skipped_bytes = 0;
800 while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
802 /* is escape sequence */
803 if (input_end[0] == '\\')
805 if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
807 /* prevent buffer overflow when last input character is a backslash */
815 if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
817 goto fail; /* string ended unexpectedly */
820 /* This is at most how much we need for the output */
821 allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
822 output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
825 goto fail; /* allocation failure */
829 output_pointer = output;
830 /* loop through the string literal */
831 while (input_pointer < input_end)
833 if (*input_pointer != '\\')
835 *output_pointer++ = *input_pointer++;
837 /* escape sequence */
840 unsigned char sequence_length = 2;
841 if ((input_end - input_pointer) < 1)
846 switch (input_pointer[1])
849 *output_pointer++ = '\b';
852 *output_pointer++ = '\f';
855 *output_pointer++ = '\n';
858 *output_pointer++ = '\r';
861 *output_pointer++ = '\t';
866 *output_pointer++ = input_pointer[1];
871 sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
872 if (sequence_length == 0)
874 /* failed to convert UTF16-literal to UTF-8 */
882 input_pointer += sequence_length;
886 /* zero terminate the output */
887 *output_pointer = '\0';
889 item->type = cJSON_String;
890 item->valuestring = (char*)output;
892 input_buffer->offset = (size_t) (input_end - input_buffer->content);
893 input_buffer->offset++;
900 input_buffer->hooks.deallocate(output);
903 if (input_pointer != NULL)
905 input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
911 /* Render the cstring provided to an escaped version that can be printed. */
912 static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
914 const unsigned char *input_pointer = NULL;
915 unsigned char *output = NULL;
916 unsigned char *output_pointer = NULL;
917 size_t output_length = 0;
918 /* numbers of additional characters needed for escaping */
919 size_t escape_characters = 0;
921 if (output_buffer == NULL)
929 output = ensure(output_buffer, sizeof("\"\""));
934 strcpy((char*)output, "\"\"");
939 /* set "flag" to 1 if something needs to be escaped */
940 for (input_pointer = input; *input_pointer; input_pointer++)
942 switch (*input_pointer)
951 /* one character escape sequence */
955 if (*input_pointer < 32)
957 /* UTF-16 escape sequence uXXXX */
958 escape_characters += 5;
963 output_length = (size_t)(input_pointer - input) + escape_characters;
965 output = ensure(output_buffer, output_length + sizeof("\"\""));
971 /* no characters have to be escaped */
972 if (escape_characters == 0)
975 memcpy(output + 1, input, output_length);
976 output[output_length + 1] = '\"';
977 output[output_length + 2] = '\0';
983 output_pointer = output + 1;
984 /* copy the string */
985 for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
987 if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
989 /* normal character, copy */
990 *output_pointer = *input_pointer;
994 /* character needs to be escaped */
995 *output_pointer++ = '\\';
996 switch (*input_pointer)
999 *output_pointer = '\\';
1002 *output_pointer = '\"';
1005 *output_pointer = 'b';
1008 *output_pointer = 'f';
1011 *output_pointer = 'n';
1014 *output_pointer = 'r';
1017 *output_pointer = 't';
1020 /* escape and print as unicode codepoint */
1021 sprintf((char*)output_pointer, "u%04x", *input_pointer);
1022 output_pointer += 4;
1027 output[output_length + 1] = '\"';
1028 output[output_length + 2] = '\0';
1033 /* Invoke print_string_ptr (which is useful) on an item. */
1034 static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
1036 return print_string_ptr((unsigned char*)item->valuestring, p);
1039 /* Predeclare these prototypes. */
1040 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
1041 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
1042 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
1043 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
1044 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
1045 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
1047 /* Utility to jump whitespace and cr/lf */
1048 static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
1050 if ((buffer == NULL) || (buffer->content == NULL))
1055 if (cannot_access_at_index(buffer, 0))
1060 while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
1065 if (buffer->offset == buffer->length)
1073 /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
1074 static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
1076 if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
1081 if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
1083 buffer->offset += 3;
1089 CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
1091 size_t buffer_length;
1098 /* Adding null character size due to require_null_terminated. */
1099 buffer_length = strlen(value) + sizeof("");
1101 return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated);
1104 /* Parse an object - create a new root, and populate. */
1105 CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)
1107 parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
1110 /* reset error position */
1111 global_error.json = NULL;
1112 global_error.position = 0;
1114 if (value == NULL || 0 == buffer_length)
1119 buffer.content = (const unsigned char*)value;
1120 buffer.length = buffer_length;
1122 buffer.hooks = global_hooks;
1124 item = cJSON_New_Item(&global_hooks);
1125 if (item == NULL) /* memory fail */
1130 if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
1132 /* parse failure. ep is set. */
1136 /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
1137 if (require_null_terminated)
1139 buffer_skip_whitespace(&buffer);
1140 if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
1145 if (return_parse_end)
1147 *return_parse_end = (const char*)buffer_at_offset(&buffer);
1161 local_error.json = (const unsigned char*)value;
1162 local_error.position = 0;
1164 if (buffer.offset < buffer.length)
1166 local_error.position = buffer.offset;
1168 else if (buffer.length > 0)
1170 local_error.position = buffer.length - 1;
1173 if (return_parse_end != NULL)
1175 *return_parse_end = (const char*)local_error.json + local_error.position;
1178 global_error = local_error;
1184 /* Default options for cJSON_Parse */
1185 CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
1187 return cJSON_ParseWithOpts(value, 0, 0);
1190 CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length)
1192 return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0);
1195 #define cjson_min(a, b) (((a) < (b)) ? (a) : (b))
1197 static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
1199 static const size_t default_buffer_size = 256;
1200 printbuffer buffer[1];
1201 unsigned char *printed = NULL;
1203 memset(buffer, 0, sizeof(buffer));
1206 buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
1207 buffer->length = default_buffer_size;
1208 buffer->format = format;
1209 buffer->hooks = *hooks;
1210 if (buffer->buffer == NULL)
1215 /* print the value */
1216 if (!print_value(item, buffer))
1220 update_offset(buffer);
1222 /* check if reallocate is available */
1223 if (hooks->reallocate != NULL)
1225 printed = (unsigned char *) hooks->reallocate (buffer->buffer,
1226 buffer->offset + 1);
1227 if (printed == NULL)
1231 buffer->buffer = NULL;
1233 else /* otherwise copy the JSON over to a new buffer */
1235 printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
1236 if (printed == NULL)
1240 memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
1241 printed[buffer->offset] = '\0'; /* just to be sure */
1243 /* free the buffer */
1244 hooks->deallocate(buffer->buffer);
1250 if (buffer->buffer != NULL)
1252 hooks->deallocate(buffer->buffer);
1255 if (printed != NULL)
1257 hooks->deallocate(printed);
1263 /* Render a cJSON item/entity/structure to text. */
1264 CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
1266 return (char*)print(item, true, &global_hooks);
1269 CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
1271 return (char*)print(item, false, &global_hooks);
1274 CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
1276 printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1283 p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
1289 p.length = (size_t)prebuffer;
1293 p.hooks = global_hooks;
1295 if (!print_value(item, &p))
1297 global_hooks.deallocate(p.buffer);
1301 return (char*)p.buffer;
1304 CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)
1306 printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1308 if ((length < 0) || (buffer == NULL))
1313 p.buffer = (unsigned char*)buffer;
1314 p.length = (size_t)length;
1318 p.hooks = global_hooks;
1320 return print_value(item, &p);
1323 /* Parser core - when encountering text, process appropriately. */
1324 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
1326 if ((input_buffer == NULL) || (input_buffer->content == NULL))
1328 return false; /* no input */
1331 /* parse the different types of values */
1333 if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
1335 item->type = cJSON_NULL;
1336 input_buffer->offset += 4;
1340 if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
1342 item->type = cJSON_False;
1343 input_buffer->offset += 5;
1347 if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
1349 item->type = cJSON_True;
1351 input_buffer->offset += 4;
1355 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
1357 return parse_string(item, input_buffer);
1360 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'))))
1362 return parse_number(item, input_buffer);
1365 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
1367 return parse_array(item, input_buffer);
1370 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
1372 return parse_object(item, input_buffer);
1378 /* Render a value to text. */
1379 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
1381 unsigned char *output = NULL;
1383 if ((item == NULL) || (output_buffer == NULL))
1388 switch ((item->type) & 0xFF)
1391 output = ensure(output_buffer, 5);
1396 strcpy((char*)output, "null");
1400 output = ensure(output_buffer, 6);
1405 strcpy((char*)output, "false");
1409 output = ensure(output_buffer, 5);
1414 strcpy((char*)output, "true");
1418 return print_number(item, output_buffer);
1422 size_t raw_length = 0;
1423 if (item->valuestring == NULL)
1428 raw_length = strlen(item->valuestring) + sizeof("");
1429 output = ensure(output_buffer, raw_length);
1434 memcpy(output, item->valuestring, raw_length);
1439 return print_string(item, output_buffer);
1442 return print_array(item, output_buffer);
1445 return print_object(item, output_buffer);
1452 /* Build an array from input text. */
1453 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
1455 cJSON *head = NULL; /* head of the linked list */
1456 cJSON *current_item = NULL;
1458 if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1460 return false; /* to deeply nested */
1462 input_buffer->depth++;
1464 if (buffer_at_offset(input_buffer)[0] != '[')
1470 input_buffer->offset++;
1471 buffer_skip_whitespace(input_buffer);
1472 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
1478 /* check if we skipped to the end of the buffer */
1479 if (cannot_access_at_index(input_buffer, 0))
1481 input_buffer->offset--;
1485 /* step back to character in front of the first element */
1486 input_buffer->offset--;
1487 /* loop through the comma separated array elements */
1490 /* allocate next item */
1491 cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1492 if (new_item == NULL)
1494 goto fail; /* allocation failure */
1497 /* attach next item to list */
1500 /* start the linked list */
1501 current_item = head = new_item;
1505 /* add to the end and advance */
1506 current_item->next = new_item;
1507 new_item->prev = current_item;
1508 current_item = new_item;
1511 /* parse next value */
1512 input_buffer->offset++;
1513 buffer_skip_whitespace(input_buffer);
1514 if (!parse_value(current_item, input_buffer))
1516 goto fail; /* failed to parse value */
1518 buffer_skip_whitespace(input_buffer);
1520 while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1522 if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
1524 goto fail; /* expected end of array */
1528 input_buffer->depth--;
1531 head->prev = current_item;
1534 item->type = cJSON_Array;
1537 input_buffer->offset++;
1550 /* Render an array to text */
1551 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
1553 unsigned char *output_pointer = NULL;
1555 cJSON *current_element = item->child;
1557 if (output_buffer == NULL)
1562 /* Compose the output array. */
1563 /* opening square bracket */
1564 output_pointer = ensure(output_buffer, 1);
1565 if (output_pointer == NULL)
1570 *output_pointer = '[';
1571 output_buffer->offset++;
1572 output_buffer->depth++;
1574 while (current_element != NULL)
1576 if (!print_value(current_element, output_buffer))
1580 update_offset(output_buffer);
1581 if (current_element->next)
1583 length = (size_t) (output_buffer->format ? 2 : 1);
1584 output_pointer = ensure(output_buffer, length + 1);
1585 if (output_pointer == NULL)
1589 *output_pointer++ = ',';
1590 if(output_buffer->format)
1592 *output_pointer++ = ' ';
1594 *output_pointer = '\0';
1595 output_buffer->offset += length;
1597 current_element = current_element->next;
1600 output_pointer = ensure(output_buffer, 2);
1601 if (output_pointer == NULL)
1605 *output_pointer++ = ']';
1606 *output_pointer = '\0';
1607 output_buffer->depth--;
1612 /* Build an object from the text. */
1613 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
1615 cJSON *head = NULL; /* linked list head */
1616 cJSON *current_item = NULL;
1618 if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1620 return false; /* to deeply nested */
1622 input_buffer->depth++;
1624 if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
1626 goto fail; /* not an object */
1629 input_buffer->offset++;
1630 buffer_skip_whitespace(input_buffer);
1631 if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
1633 goto success; /* empty object */
1636 /* check if we skipped to the end of the buffer */
1637 if (cannot_access_at_index(input_buffer, 0))
1639 input_buffer->offset--;
1643 /* step back to character in front of the first element */
1644 input_buffer->offset--;
1645 /* loop through the comma separated array elements */
1648 /* allocate next item */
1649 cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1650 if (new_item == NULL)
1652 goto fail; /* allocation failure */
1655 /* attach next item to list */
1658 /* start the linked list */
1659 current_item = head = new_item;
1663 /* add to the end and advance */
1664 current_item->next = new_item;
1665 new_item->prev = current_item;
1666 current_item = new_item;
1669 if (cannot_access_at_index (input_buffer, 1))
1671 goto fail; /* nothing comes after the comma */
1674 /* parse the name of the child */
1675 input_buffer->offset++;
1676 buffer_skip_whitespace(input_buffer);
1677 if (!parse_string(current_item, input_buffer))
1679 goto fail; /* failed to parse name */
1681 buffer_skip_whitespace(input_buffer);
1683 /* swap valuestring and string, because we parsed the name */
1684 current_item->string = current_item->valuestring;
1685 current_item->valuestring = NULL;
1687 if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
1689 goto fail; /* invalid object */
1692 /* parse the value */
1693 input_buffer->offset++;
1694 buffer_skip_whitespace(input_buffer);
1695 if (!parse_value(current_item, input_buffer))
1697 goto fail; /* failed to parse value */
1699 buffer_skip_whitespace(input_buffer);
1701 while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1703 if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
1705 goto fail; /* expected end of object */
1709 input_buffer->depth--;
1712 head->prev = current_item;
1715 item->type = cJSON_Object;
1718 input_buffer->offset++;
1730 /* Render an object to text. */
1731 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
1733 unsigned char *output_pointer = NULL;
1735 cJSON *current_item = item->child;
1737 if (output_buffer == NULL)
1742 /* Compose the output: */
1743 length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
1744 output_pointer = ensure(output_buffer, length + 1);
1745 if (output_pointer == NULL)
1750 *output_pointer++ = '{';
1751 output_buffer->depth++;
1752 if (output_buffer->format)
1754 *output_pointer++ = '\n';
1756 output_buffer->offset += length;
1758 while (current_item)
1760 if (output_buffer->format)
1763 output_pointer = ensure(output_buffer, output_buffer->depth);
1764 if (output_pointer == NULL)
1768 for (i = 0; i < output_buffer->depth; i++)
1770 *output_pointer++ = '\t';
1772 output_buffer->offset += output_buffer->depth;
1776 if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
1780 update_offset(output_buffer);
1782 length = (size_t) (output_buffer->format ? 2 : 1);
1783 output_pointer = ensure(output_buffer, length);
1784 if (output_pointer == NULL)
1788 *output_pointer++ = ':';
1789 if (output_buffer->format)
1791 *output_pointer++ = '\t';
1793 output_buffer->offset += length;
1796 if (!print_value(current_item, output_buffer))
1800 update_offset(output_buffer);
1802 /* print comma if not last */
1803 length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
1804 output_pointer = ensure(output_buffer, length + 1);
1805 if (output_pointer == NULL)
1809 if (current_item->next)
1811 *output_pointer++ = ',';
1814 if (output_buffer->format)
1816 *output_pointer++ = '\n';
1818 *output_pointer = '\0';
1819 output_buffer->offset += length;
1821 current_item = current_item->next;
1824 output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
1825 if (output_pointer == NULL)
1829 if (output_buffer->format)
1832 for (i = 0; i < (output_buffer->depth - 1); i++)
1834 *output_pointer++ = '\t';
1837 *output_pointer++ = '}';
1838 *output_pointer = '\0';
1839 output_buffer->depth--;
1844 /* Get Array size/item / object item. */
1845 CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
1847 cJSON *child = NULL;
1855 child = array->child;
1857 while(child != NULL)
1860 child = child->next;
1863 /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
1868 static cJSON* get_array_item(const cJSON *array, size_t index)
1870 cJSON *current_child = NULL;
1877 current_child = array->child;
1878 while ((current_child != NULL) && (index > 0))
1881 current_child = current_child->next;
1884 return current_child;
1887 CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
1894 return get_array_item(array, (size_t)index);
1897 static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
1899 cJSON *current_element = NULL;
1901 if ((object == NULL) || (name == NULL))
1906 current_element = object->child;
1909 while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
1911 current_element = current_element->next;
1916 while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
1918 current_element = current_element->next;
1922 if ((current_element == NULL) || (current_element->string == NULL)) {
1926 return current_element;
1929 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
1931 return get_object_item(object, string, false);
1934 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
1936 return get_object_item(object, string, true);
1939 CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
1941 return cJSON_GetObjectItem(object, string) ? 1 : 0;
1944 /* Utility for array list handling. */
1945 static void suffix_object(cJSON *prev, cJSON *item)
1951 /* Utility for handling references. */
1952 static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
1954 cJSON *reference = NULL;
1960 reference = cJSON_New_Item(hooks);
1961 if (reference == NULL)
1966 memcpy(reference, item, sizeof(cJSON));
1967 reference->string = NULL;
1968 reference->type |= cJSON_IsReference;
1969 reference->next = reference->prev = NULL;
1973 static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
1975 cJSON *child = NULL;
1977 if ((item == NULL) || (array == NULL) || (array == item))
1982 child = array->child;
1984 * To find the last item in array quickly, we use prev in array
1988 /* list is empty, start new one */
1989 array->child = item;
1995 /* append to the end */
1998 suffix_object(child->prev, item);
1999 array->child->prev = item;
2006 /* Add item to array/object. */
2007 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
2009 return add_item_to_array(array, item);
2012 #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
2013 #pragma GCC diagnostic push
2016 #pragma GCC diagnostic ignored "-Wcast-qual"
2018 /* helper function to cast away const */
2019 static void* cast_away_const(const void* string)
2021 return (void*)string;
2023 #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
2024 #pragma GCC diagnostic pop
2028 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)
2030 char *new_key = NULL;
2031 int new_type = cJSON_Invalid;
2033 if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item))
2040 new_key = (char*)cast_away_const(string);
2041 new_type = item->type | cJSON_StringIsConst;
2045 new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
2046 if (new_key == NULL)
2051 new_type = item->type & ~cJSON_StringIsConst;
2054 if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
2056 hooks->deallocate(item->string);
2059 item->string = new_key;
2060 item->type = new_type;
2062 return add_item_to_array(object, item);
2065 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
2067 return add_item_to_object(object, string, item, &global_hooks, false);
2070 /* Add an item to an object with constant string as key */
2071 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
2073 return add_item_to_object(object, string, item, &global_hooks, true);
2076 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
2083 return add_item_to_array(array, create_reference(item, &global_hooks));
2086 CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
2088 if ((object == NULL) || (string == NULL))
2093 return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
2096 CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
2098 cJSON *null = cJSON_CreateNull();
2099 if (add_item_to_object(object, name, null, &global_hooks, false))
2108 CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
2110 cJSON *true_item = cJSON_CreateTrue();
2111 if (add_item_to_object(object, name, true_item, &global_hooks, false))
2116 cJSON_Delete(true_item);
2120 CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
2122 cJSON *false_item = cJSON_CreateFalse();
2123 if (add_item_to_object(object, name, false_item, &global_hooks, false))
2128 cJSON_Delete(false_item);
2132 CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
2134 cJSON *bool_item = cJSON_CreateBool(boolean);
2135 if (add_item_to_object(object, name, bool_item, &global_hooks, false))
2140 cJSON_Delete(bool_item);
2144 CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
2146 cJSON *number_item = cJSON_CreateNumber(number);
2147 if (add_item_to_object(object, name, number_item, &global_hooks, false))
2152 cJSON_Delete(number_item);
2156 CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
2158 cJSON *string_item = cJSON_CreateString(string);
2159 if (add_item_to_object(object, name, string_item, &global_hooks, false))
2164 cJSON_Delete(string_item);
2168 CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
2170 cJSON *raw_item = cJSON_CreateRaw(raw);
2171 if (add_item_to_object(object, name, raw_item, &global_hooks, false))
2176 cJSON_Delete(raw_item);
2180 CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
2182 cJSON *object_item = cJSON_CreateObject();
2183 if (add_item_to_object(object, name, object_item, &global_hooks, false))
2188 cJSON_Delete(object_item);
2192 CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
2194 cJSON *array = cJSON_CreateArray();
2195 if (add_item_to_object(object, name, array, &global_hooks, false))
2200 cJSON_Delete(array);
2204 CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
2206 if ((parent == NULL) || (item == NULL))
2211 if (item != parent->child)
2213 /* not the first element */
2214 item->prev->next = item->next;
2216 if (item->next != NULL)
2218 /* not the last element */
2219 item->next->prev = item->prev;
2222 if (item == parent->child)
2225 parent->child = item->next;
2227 else if (item->next == NULL)
2230 parent->child->prev = item->prev;
2233 /* make sure the detached item doesn't point anywhere anymore */
2240 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
2247 return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
2250 CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
2252 cJSON_Delete(cJSON_DetachItemFromArray(array, which));
2255 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
2257 cJSON *to_detach = cJSON_GetObjectItem(object, string);
2259 return cJSON_DetachItemViaPointer(object, to_detach);
2262 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
2264 cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
2266 return cJSON_DetachItemViaPointer(object, to_detach);
2269 CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
2271 cJSON_Delete(cJSON_DetachItemFromObject(object, string));
2274 CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
2276 cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
2279 /* Replace array/object items with new ones. */
2280 CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
2282 cJSON *after_inserted = NULL;
2284 if (which < 0 || newitem == NULL)
2289 after_inserted = get_array_item(array, (size_t)which);
2290 if (after_inserted == NULL)
2292 return add_item_to_array(array, newitem);
2295 if (after_inserted != array->child && after_inserted->prev == NULL)
2297 /* return false if after_inserted is a corrupted array item */
2301 newitem->next = after_inserted;
2302 newitem->prev = after_inserted->prev;
2303 after_inserted->prev = newitem;
2304 if (after_inserted == array->child)
2306 array->child = newitem;
2310 newitem->prev->next = newitem;
2315 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2317 if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) ||
2323 if (replacement == item)
2328 replacement->next = item->next;
2329 replacement->prev = item->prev;
2331 if (replacement->next != NULL)
2333 replacement->next->prev = replacement;
2335 if (parent->child == item)
2337 if (parent->child->prev == parent->child)
2339 replacement->prev = replacement;
2341 parent->child = replacement;
2345 * To find the last item in array quickly, we use prev in array.
2346 * We can't modify the last item's next pointer where this item was the parent's child
2348 if (replacement->prev != NULL)
2350 replacement->prev->next = replacement;
2352 if (replacement->next == NULL)
2354 parent->child->prev = replacement;
2365 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
2372 return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
2375 static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
2377 if ((replacement == NULL) || (string == NULL))
2382 /* replace the name in the replacement */
2383 if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
2385 cJSON_free(replacement->string);
2387 replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2388 if (replacement->string == NULL)
2393 replacement->type &= ~cJSON_StringIsConst;
2395 return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
2398 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
2400 return replace_item_in_object(object, string, newitem, false);
2403 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
2405 return replace_item_in_object(object, string, newitem, true);
2408 /* Create basic types: */
2409 CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
2411 cJSON *item = cJSON_New_Item(&global_hooks);
2414 item->type = cJSON_NULL;
2420 CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
2422 cJSON *item = cJSON_New_Item(&global_hooks);
2425 item->type = cJSON_True;
2431 CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
2433 cJSON *item = cJSON_New_Item(&global_hooks);
2436 item->type = cJSON_False;
2442 CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean)
2444 cJSON *item = cJSON_New_Item(&global_hooks);
2447 item->type = boolean ? cJSON_True : cJSON_False;
2453 CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
2455 cJSON *item = cJSON_New_Item(&global_hooks);
2458 item->type = cJSON_Number;
2459 item->valuedouble = num;
2461 /* use saturation in case of overflow */
2464 item->valueint = INT_MAX;
2466 else if (num <= (double)INT_MIN)
2468 item->valueint = INT_MIN;
2472 item->valueint = (int)num;
2479 CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
2481 cJSON *item = cJSON_New_Item(&global_hooks);
2484 item->type = cJSON_String;
2485 item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2486 if(!item->valuestring)
2496 CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
2498 cJSON *item = cJSON_New_Item(&global_hooks);
2501 item->type = cJSON_String | cJSON_IsReference;
2502 item->valuestring = (char*)cast_away_const(string);
2508 CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
2510 cJSON *item = cJSON_New_Item(&global_hooks);
2512 item->type = cJSON_Object | cJSON_IsReference;
2513 item->child = (cJSON*)cast_away_const(child);
2519 CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
2520 cJSON *item = cJSON_New_Item(&global_hooks);
2522 item->type = cJSON_Array | cJSON_IsReference;
2523 item->child = (cJSON*)cast_away_const(child);
2529 CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
2531 cJSON *item = cJSON_New_Item(&global_hooks);
2534 item->type = cJSON_Raw;
2535 item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
2536 if(!item->valuestring)
2546 CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
2548 cJSON *item = cJSON_New_Item(&global_hooks);
2551 item->type=cJSON_Array;
2557 CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
2559 cJSON *item = cJSON_New_Item(&global_hooks);
2562 item->type = cJSON_Object;
2568 /* Create Arrays: */
2569 CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
2576 if ((count < 0) || (numbers == NULL))
2581 a = cJSON_CreateArray();
2583 for(i = 0; a && (i < (size_t)count); i++)
2585 n = cJSON_CreateNumber(numbers[i]);
2597 suffix_object(p, n);
2610 CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
2617 if ((count < 0) || (numbers == NULL))
2622 a = cJSON_CreateArray();
2624 for(i = 0; a && (i < (size_t)count); i++)
2626 n = cJSON_CreateNumber((double)numbers[i]);
2638 suffix_object(p, n);
2651 CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
2658 if ((count < 0) || (numbers == NULL))
2663 a = cJSON_CreateArray();
2665 for (i = 0; a && (i < (size_t) count); i++)
2667 n = cJSON_CreateNumber (numbers[i]);
2679 suffix_object(p, n);
2692 CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count)
2699 if ((count < 0) || (strings == NULL))
2704 a = cJSON_CreateArray();
2706 for (i = 0; a && (i < (size_t)count); i++)
2708 n = cJSON_CreateString(strings[i]);
2734 CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
2736 cJSON *newitem = NULL;
2737 cJSON *child = NULL;
2739 cJSON *newchild = NULL;
2741 /* Bail on bad ptr */
2746 /* Create new item */
2747 newitem = cJSON_New_Item(&global_hooks);
2752 /* Copy over all vars */
2753 newitem->type = item->type & (~cJSON_IsReference);
2754 newitem->valueint = item->valueint;
2755 newitem->valuedouble = item->valuedouble;
2756 if (item->valuestring)
2758 newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
2759 if (!newitem->valuestring)
2766 newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
2767 if (!newitem->string)
2772 /* If non-recursive, then we're done! */
2777 /* Walk the ->next chain for the child. */
2778 child = item->child;
2779 while (child != NULL)
2781 newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
2788 /* If newitem->child already set, then crosswire ->prev and ->next and move on */
2789 next->next = newchild;
2790 newchild->prev = next;
2795 /* Set newitem->child and move to it */
2796 newitem->child = newchild;
2799 child = child->next;
2801 if (newitem && newitem->child)
2803 newitem->child->prev = newchild;
2809 if (newitem != NULL)
2811 cJSON_Delete(newitem);
2817 static void skip_oneline_comment(char **input)
2819 *input += static_strlen("//");
2821 for (; (*input)[0] != '\0'; ++(*input))
2823 if ((*input)[0] == '\n') {
2824 *input += static_strlen("\n");
2830 static void skip_multiline_comment(char **input)
2832 *input += static_strlen("/*");
2834 for (; (*input)[0] != '\0'; ++(*input))
2836 if (((*input)[0] == '*') && ((*input)[1] == '/'))
2838 *input += static_strlen("*/");
2844 static void minify_string(char **input, char **output) {
2845 (*output)[0] = (*input)[0];
2846 *input += static_strlen("\"");
2847 *output += static_strlen("\"");
2850 for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
2851 (*output)[0] = (*input)[0];
2853 if ((*input)[0] == '\"') {
2854 (*output)[0] = '\"';
2855 *input += static_strlen("\"");
2856 *output += static_strlen("\"");
2858 } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
2859 (*output)[1] = (*input)[1];
2860 *input += static_strlen("\"");
2861 *output += static_strlen("\"");
2866 CJSON_PUBLIC(void) cJSON_Minify(char *json)
2875 while (json[0] != '\0')
2889 skip_oneline_comment(&json);
2891 else if (json[1] == '*')
2893 skip_multiline_comment(&json);
2900 minify_string(&json, (char**)&into);
2910 /* and null-terminate. */
2914 CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
2921 return (item->type & 0xFF) == cJSON_Invalid;
2924 CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
2931 return (item->type & 0xFF) == cJSON_False;
2934 CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
2941 return (item->type & 0xff) == cJSON_True;
2945 CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
2952 return (item->type & (cJSON_True | cJSON_False)) != 0;
2954 CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
2961 return (item->type & 0xFF) == cJSON_NULL;
2964 CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
2971 return (item->type & 0xFF) == cJSON_Number;
2974 CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
2981 return (item->type & 0xFF) == cJSON_String;
2984 CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
2991 return (item->type & 0xFF) == cJSON_Array;
2994 CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
3001 return (item->type & 0xFF) == cJSON_Object;
3004 CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
3011 return (item->type & 0xFF) == cJSON_Raw;
3014 CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
3016 if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
3021 /* check if type is valid */
3022 switch (a->type & 0xFF)
3038 /* identical objects are equal */
3044 switch (a->type & 0xFF)
3046 /* in these cases and equal type is enough */
3053 if (compare_double(a->valuedouble, b->valuedouble))
3061 if ((a->valuestring == NULL) || (b->valuestring == NULL))
3065 if (strcmp(a->valuestring, b->valuestring) == 0)
3074 cJSON *a_element = a->child;
3075 cJSON *b_element = b->child;
3077 for (; (a_element != NULL) && (b_element != NULL);)
3079 if (!cJSON_Compare(a_element, b_element, case_sensitive))
3084 a_element = a_element->next;
3085 b_element = b_element->next;
3088 /* one of the arrays is longer than the other */
3089 if (a_element != b_element) {
3098 cJSON *a_element = NULL;
3099 cJSON *b_element = NULL;
3100 cJSON_ArrayForEach(a_element, a)
3102 /* TODO This has O(n^2) runtime, which is horrible! */
3103 b_element = get_object_item(b, a_element->string, case_sensitive);
3104 if (b_element == NULL)
3109 if (!cJSON_Compare(a_element, b_element, case_sensitive))
3115 /* doing this twice, once on a and b to prevent true comparison if a subset of b
3116 * TODO: Do this the proper way, this is just a fix for now */
3117 cJSON_ArrayForEach(b_element, b)
3119 a_element = get_object_item(a, b_element->string, case_sensitive);
3120 if (a_element == NULL)
3125 if (!cJSON_Compare(b_element, a_element, case_sensitive))
3139 CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
3141 return global_hooks.allocate(size);
3144 CJSON_PUBLIC(void) cJSON_free(void *object)
3146 global_hooks.deallocate(object);
3149 CJSON_PUBLIC (void *) cJSON_realloc (void *object, size_t size)
3151 return global_hooks.reallocate (object, size);