RTS API Documentation  1.10.11
cJSON.c
Go to the documentation of this file.
1 /*
2  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
3  Permission is hereby granted, free of charge, to any person obtaining a copy
4  of this software and associated documentation files (the "Software"), to deal
5  in the Software without restriction, including without limitation the rights
6  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  copies of the Software, and to permit persons to whom the Software is
8  furnished to do so, subject to the following conditions:
9  The above copyright notice and this permission notice shall be included in
10  all copies or substantial portions of the Software.
11  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17  THE SOFTWARE.
18 */
19 
20 /* cJSON */
21 /* JSON parser in C. */
22 
23 /* disable warnings about old C89 functions in MSVC */
24 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
25 #define _CRT_SECURE_NO_DEPRECATE
26 #endif
27 
28 #ifdef __GNUC__
29 #pragma GCC visibility push(default)
30 #endif
31 #if defined(_MSC_VER)
32 #pragma warning (push)
33 /* disable warning about single line comments in system headers */
34 #pragma warning (disable : 4001)
35 #endif
36 
37 #include <string.h>
38 #include <stdio.h>
39 #include <math.h>
40 #include <stdlib.h>
41 #include <limits.h>
42 #include <ctype.h>
43 
44 #ifdef ENABLE_LOCALES
45 #include <locale.h>
46 #endif
47 
48 #if defined(_MSC_VER)
49 #pragma warning (pop)
50 #endif
51 #ifdef __GNUC__
52 #pragma GCC visibility pop
53 #endif
54 
55 #include "switch_cJSON.h"
56 
57 /* define our own boolean type */
58 #ifdef true
59 #undef true
60 #endif
61 #define true ((cJSON_bool)1)
62 
63 #ifdef false
64 #undef false
65 #endif
66 #define false ((cJSON_bool)0)
67 
68 typedef struct {
69  const unsigned char *json;
70  size_t position;
71 } error;
72 static error global_error = { NULL, 0 };
73 
74 CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
75 {
76  return (const char*) (global_error.json + global_error.position);
77 }
78 
79 CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) {
80  if (!cJSON_IsString(item)) {
81  return NULL;
82  }
83 
84  return item->valuestring;
85 }
86 
87 /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
88 #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 12)
89  #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
90 #endif
91 
92 CJSON_PUBLIC(const char*) cJSON_Version(void)
93 {
94  static char version[15];
95  sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
96 
97  return version;
98 }
99 
100 /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */
101 static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
102 {
103  if ((string1 == NULL) || (string2 == NULL))
104  {
105  return 1;
106  }
107 
108  if (string1 == string2)
109  {
110  return 0;
111  }
112 
113  for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
114  {
115  if (*string1 == '\0')
116  {
117  return 0;
118  }
119  }
120 
121  return tolower(*string1) - tolower(*string2);
122 }
123 
124 typedef struct internal_hooks
125 {
126  void *(CJSON_CDECL *allocate)(size_t size);
127  void (CJSON_CDECL *deallocate)(void *pointer);
128  void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
130 
131 #if defined(_MSC_VER)
132 /* work around MSVC error C2322: '...' address of dillimport '...' is not static */
133 static void * CJSON_CDECL internal_malloc(size_t size)
134 {
135  return malloc(size);
136 }
137 static void CJSON_CDECL internal_free(void *pointer)
138 {
139  free(pointer);
140 }
141 static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
142 {
143  return realloc(pointer, size);
144 }
145 #else
146 #define internal_malloc malloc
147 #define internal_free free
148 #define internal_realloc realloc
149 #endif
150 
151 /* strlen of character literals resolved at compile time */
152 #define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
153 
155 
156 static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
157 {
158  size_t length = 0;
159  unsigned char *copy = NULL;
160 
161  if (string == NULL)
162  {
163  return NULL;
164  }
165 
166  length = strlen((const char*)string) + sizeof("");
167  copy = (unsigned char*)hooks->allocate(length);
168  if (copy == NULL)
169  {
170  return NULL;
171  }
172  memcpy(copy, string, length);
173 
174  return copy;
175 }
176 
177 CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
178 {
179  if (hooks == NULL)
180  {
181  /* Reset hooks */
182  global_hooks.allocate = malloc;
183  global_hooks.deallocate = free;
184  global_hooks.reallocate = realloc;
185  return;
186  }
187 
188  global_hooks.allocate = malloc;
189  if (hooks->malloc_fn != NULL)
190  {
191  global_hooks.allocate = hooks->malloc_fn;
192  }
193 
194  global_hooks.deallocate = free;
195  if (hooks->free_fn != NULL)
196  {
197  global_hooks.deallocate = hooks->free_fn;
198  }
199 
200  /* use realloc only if both free and malloc are used */
201  global_hooks.reallocate = NULL;
202  if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
203  {
204  global_hooks.reallocate = realloc;
205  }
206 }
207 
208 /* Internal constructor. */
209 static cJSON *cJSON_New_Item(const internal_hooks * const hooks)
210 {
211  cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON));
212  if (node)
213  {
214  memset(node, '\0', sizeof(cJSON));
215  }
216 
217  return node;
218 }
219 
220 /* Delete a cJSON structure. */
221 CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
222 {
223  cJSON *next = NULL;
224  while (item != NULL)
225  {
226  next = item->next;
227  if (!(item->type & cJSON_IsReference) && (item->child != NULL))
228  {
229  cJSON_Delete(item->child);
230  }
231  if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
232  {
233  global_hooks.deallocate(item->valuestring);
234  }
235  if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
236  {
237  global_hooks.deallocate(item->string);
238  }
239  global_hooks.deallocate(item);
240  item = next;
241  }
242 }
243 
244 /* get the decimal point character of the current locale */
245 static unsigned char get_decimal_point(void)
246 {
247 #ifdef ENABLE_LOCALES
248  struct lconv *lconv = localeconv();
249  return (unsigned char) lconv->decimal_point[0];
250 #else
251  return '.';
252 #endif
253 }
254 
255 typedef struct
256 {
257  const unsigned char *content;
258  size_t length;
259  size_t offset;
260  size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
262 } parse_buffer;
263 
264 /* check if the given size is left to read in a given parse buffer (starting with 1) */
265 #define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
266 /* check if the buffer can be accessed at the given index (starting with 0) */
267 #define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
268 #define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
269 /* get a pointer to the buffer at the position */
270 #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
271 
272 /* Parse the input text to generate a number, and populate the result into item. */
273 static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer)
274 {
275  double number = 0;
276  unsigned char *after_end = NULL;
277  unsigned char number_c_string[64];
278  unsigned char decimal_point = get_decimal_point();
279  size_t i = 0;
280 
281  if ((input_buffer == NULL) || (input_buffer->content == NULL))
282  {
283  return false;
284  }
285 
286  /* copy the number into a temporary buffer and replace '.' with the decimal point
287  * of the current locale (for strtod)
288  * This also takes care of '\0' not necessarily being available for marking the end of the input */
289  for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++)
290  {
291  switch (buffer_at_offset(input_buffer)[i])
292  {
293  case '0':
294  case '1':
295  case '2':
296  case '3':
297  case '4':
298  case '5':
299  case '6':
300  case '7':
301  case '8':
302  case '9':
303  case '+':
304  case '-':
305  case 'e':
306  case 'E':
307  number_c_string[i] = buffer_at_offset(input_buffer)[i];
308  break;
309 
310  case '.':
311  number_c_string[i] = decimal_point;
312  break;
313 
314  default:
315  goto loop_end;
316  }
317  }
318 loop_end:
319  number_c_string[i] = '\0';
320 
321  number = strtod((const char*)number_c_string, (char**)&after_end);
322  if (number_c_string == after_end)
323  {
324  return false; /* parse_error */
325  }
326 
327  item->valuedouble = number;
328 
329  /* use saturation in case of overflow */
330  if (number >= INT_MAX)
331  {
332  item->valueint = INT_MAX;
333  }
334  else if (number <= (double)INT_MIN)
335  {
336  item->valueint = INT_MIN;
337  }
338  else
339  {
340  item->valueint = (int)number;
341  }
342 
343  item->type = cJSON_Number;
344 
345  input_buffer->offset += (size_t)(after_end - number_c_string);
346  return true;
347 }
348 
349 /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */
350 CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
351 {
352  if (number >= INT_MAX)
353  {
354  object->valueint = INT_MAX;
355  }
356  else if (number <= (double)INT_MIN)
357  {
358  object->valueint = INT_MIN;
359  }
360  else
361  {
362  object->valueint = (int)number;
363  }
364 
365  return object->valuedouble = number;
366 }
367 
368 typedef struct
369 {
370  unsigned char *buffer;
371  size_t length;
372  size_t offset;
373  size_t depth; /* current nesting depth (for formatted printing) */
375  cJSON_bool format; /* is this print a formatted print */
377 } printbuffer;
378 
379 /* realloc printbuffer if necessary to have at least "needed" bytes more */
380 static unsigned char* ensure(printbuffer * const p, size_t needed)
381 {
382  unsigned char *newbuffer = NULL;
383  size_t newsize = 0;
384 
385  if ((p == NULL) || (p->buffer == NULL))
386  {
387  return NULL;
388  }
389 
390  if ((p->length > 0) && (p->offset >= p->length))
391  {
392  /* make sure that offset is valid */
393  return NULL;
394  }
395 
396  if (needed > INT_MAX)
397  {
398  /* sizes bigger than INT_MAX are currently not supported */
399  return NULL;
400  }
401 
402  needed += p->offset + 1;
403  if (needed <= p->length)
404  {
405  return p->buffer + p->offset;
406  }
407 
408  if (p->noalloc) {
409  return NULL;
410  }
411 
412  /* calculate new buffer size */
413  if (needed > (INT_MAX / 2))
414  {
415  /* overflow of int, use INT_MAX if possible */
416  if (needed <= INT_MAX)
417  {
418  newsize = INT_MAX;
419  }
420  else
421  {
422  return NULL;
423  }
424  }
425  else
426  {
427  newsize = needed * 2;
428  }
429 
430  if (p->hooks.reallocate != NULL)
431  {
432  /* reallocate with realloc if available */
433  newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
434  if (newbuffer == NULL)
435  {
436  p->hooks.deallocate(p->buffer);
437  p->length = 0;
438  p->buffer = NULL;
439 
440  return NULL;
441  }
442  }
443  else
444  {
445  /* otherwise reallocate manually */
446  newbuffer = (unsigned char*)p->hooks.allocate(newsize);
447  if (!newbuffer)
448  {
449  p->hooks.deallocate(p->buffer);
450  p->length = 0;
451  p->buffer = NULL;
452 
453  return NULL;
454  }
455  if (newbuffer)
456  {
457  memcpy(newbuffer, p->buffer, p->offset + 1);
458  }
459  p->hooks.deallocate(p->buffer);
460  }
461  p->length = newsize;
462  p->buffer = newbuffer;
463 
464  return newbuffer + p->offset;
465 }
466 
467 /* calculate the new length of the string in a printbuffer and update the offset */
468 static void update_offset(printbuffer * const buffer)
469 {
470  const unsigned char *buffer_pointer = NULL;
471  if ((buffer == NULL) || (buffer->buffer == NULL))
472  {
473  return;
474  }
475  buffer_pointer = buffer->buffer + buffer->offset;
476 
477  buffer->offset += strlen((const char*)buffer_pointer);
478 }
479 
480 /* Render the number nicely from the given item into a string. */
481 static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer)
482 {
483  unsigned char *output_pointer = NULL;
484  double d = item->valuedouble;
485  int length = 0;
486  size_t i = 0;
487  unsigned char number_buffer[26]; /* temporary buffer to print the number into */
488  unsigned char decimal_point = get_decimal_point();
489  double test;
490 
491  if (output_buffer == NULL)
492  {
493  return false;
494  }
495 
496  /* This checks for NaN and Infinity */
497  if ((d * 0) != 0)
498  {
499  length = sprintf((char*)number_buffer, "null");
500  }
501  else
502  {
503  /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
504  length = sprintf((char*)number_buffer, "%1.15g", d);
505 
506  /* Check whether the original double can be recovered */
507  if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d))
508  {
509  /* If not, print with 17 decimal places of precision */
510  length = sprintf((char*)number_buffer, "%1.17g", d);
511  }
512  }
513 
514  /* sprintf failed or buffer overrun occurred */
515  if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1)))
516  {
517  return false;
518  }
519 
520  /* reserve appropriate space in the output */
521  output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
522  if (output_pointer == NULL)
523  {
524  return false;
525  }
526 
527  /* copy the printed number to the output and replace locale
528  * dependent decimal point with '.' */
529  for (i = 0; i < ((size_t)length); i++)
530  {
531  if (number_buffer[i] == decimal_point)
532  {
533  output_pointer[i] = '.';
534  continue;
535  }
536 
537  output_pointer[i] = number_buffer[i];
538  }
539  output_pointer[i] = '\0';
540 
541  output_buffer->offset += (size_t)length;
542 
543  return true;
544 }
545 
546 /* parse 4 digit hexadecimal number */
547 static unsigned parse_hex4(const unsigned char * const input)
548 {
549  unsigned int h = 0;
550  size_t i = 0;
551 
552  for (i = 0; i < 4; i++)
553  {
554  /* parse digit */
555  if ((input[i] >= '0') && (input[i] <= '9'))
556  {
557  h += (unsigned int) input[i] - '0';
558  }
559  else if ((input[i] >= 'A') && (input[i] <= 'F'))
560  {
561  h += (unsigned int) 10 + input[i] - 'A';
562  }
563  else if ((input[i] >= 'a') && (input[i] <= 'f'))
564  {
565  h += (unsigned int) 10 + input[i] - 'a';
566  }
567  else /* invalid */
568  {
569  return 0;
570  }
571 
572  if (i < 3)
573  {
574  /* shift left to make place for the next nibble */
575  h = h << 4;
576  }
577  }
578 
579  return h;
580 }
581 
582 /* converts a UTF-16 literal to UTF-8
583  * A literal can be one or two sequences of the form \uXXXX */
584 static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer)
585 {
586  long unsigned int codepoint = 0;
587  unsigned int first_code = 0;
588  const unsigned char *first_sequence = input_pointer;
589  unsigned char utf8_length = 0;
590  unsigned char utf8_position = 0;
591  unsigned char sequence_length = 0;
592  unsigned char first_byte_mark = 0;
593 
594  if ((input_end - first_sequence) < 6)
595  {
596  /* input ends unexpectedly */
597  goto fail;
598  }
599 
600  /* get the first utf16 sequence */
601  first_code = parse_hex4(first_sequence + 2);
602 
603  /* check that the code is valid */
604  if (((first_code >= 0xDC00) && (first_code <= 0xDFFF)))
605  {
606  goto fail;
607  }
608 
609  /* UTF16 surrogate pair */
610  if ((first_code >= 0xD800) && (first_code <= 0xDBFF))
611  {
612  const unsigned char *second_sequence = first_sequence + 6;
613  unsigned int second_code = 0;
614  sequence_length = 12; /* \uXXXX\uXXXX */
615 
616  if ((input_end - second_sequence) < 6)
617  {
618  /* input ends unexpectedly */
619  goto fail;
620  }
621 
622  if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u'))
623  {
624  /* missing second half of the surrogate pair */
625  goto fail;
626  }
627 
628  /* get the second utf16 sequence */
629  second_code = parse_hex4(second_sequence + 2);
630  /* check that the code is valid */
631  if ((second_code < 0xDC00) || (second_code > 0xDFFF))
632  {
633  /* invalid second half of the surrogate pair */
634  goto fail;
635  }
636 
637 
638  /* calculate the unicode codepoint from the surrogate pair */
639  codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF));
640  }
641  else
642  {
643  sequence_length = 6; /* \uXXXX */
644  codepoint = first_code;
645  }
646 
647  /* encode as UTF-8
648  * takes at maximum 4 bytes to encode:
649  * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
650  if (codepoint < 0x80)
651  {
652  /* normal ascii, encoding 0xxxxxxx */
653  utf8_length = 1;
654  }
655  else if (codepoint < 0x800)
656  {
657  /* two bytes, encoding 110xxxxx 10xxxxxx */
658  utf8_length = 2;
659  first_byte_mark = 0xC0; /* 11000000 */
660  }
661  else if (codepoint < 0x10000)
662  {
663  /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */
664  utf8_length = 3;
665  first_byte_mark = 0xE0; /* 11100000 */
666  }
667  else if (codepoint <= 0x10FFFF)
668  {
669  /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */
670  utf8_length = 4;
671  first_byte_mark = 0xF0; /* 11110000 */
672  }
673  else
674  {
675  /* invalid unicode codepoint */
676  goto fail;
677  }
678 
679  /* encode as utf8 */
680  for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--)
681  {
682  /* 10xxxxxx */
683  (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF);
684  codepoint >>= 6;
685  }
686  /* encode first byte */
687  if (utf8_length > 1)
688  {
689  (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF);
690  }
691  else
692  {
693  (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F);
694  }
695 
696  *output_pointer += utf8_length;
697 
698  return sequence_length;
699 
700 fail:
701  return 0;
702 }
703 
704 /* Parse the input text into an unescaped cinput, and populate item. */
705 static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer)
706 {
707  const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
708  const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
709  unsigned char *output_pointer = NULL;
710  unsigned char *output = NULL;
711 
712  /* not a string */
713  if (buffer_at_offset(input_buffer)[0] != '\"')
714  {
715  goto fail;
716  }
717 
718  {
719  /* calculate approximate size of the output (overestimate) */
720  size_t allocation_length = 0;
721  size_t skipped_bytes = 0;
722  while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"'))
723  {
724  /* is escape sequence */
725  if (input_end[0] == '\\')
726  {
727  if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length)
728  {
729  /* prevent buffer overflow when last input character is a backslash */
730  goto fail;
731  }
732  skipped_bytes++;
733  input_end++;
734  }
735  input_end++;
736  }
737  if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"'))
738  {
739  goto fail; /* string ended unexpectedly */
740  }
741 
742  /* This is at most how much we need for the output */
743  allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
744  output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof(""));
745  if (output == NULL)
746  {
747  goto fail; /* allocation failure */
748  }
749  }
750 
751  output_pointer = output;
752  /* loop through the string literal */
753  while (input_pointer < input_end)
754  {
755  if (*input_pointer != '\\')
756  {
757  *output_pointer++ = *input_pointer++;
758  }
759  /* escape sequence */
760  else
761  {
762  unsigned char sequence_length = 2;
763  if ((input_end - input_pointer) < 1)
764  {
765  goto fail;
766  }
767 
768  switch (input_pointer[1])
769  {
770  case 'b':
771  *output_pointer++ = '\b';
772  break;
773  case 'f':
774  *output_pointer++ = '\f';
775  break;
776  case 'n':
777  *output_pointer++ = '\n';
778  break;
779  case 'r':
780  *output_pointer++ = '\r';
781  break;
782  case 't':
783  *output_pointer++ = '\t';
784  break;
785  case '\"':
786  case '\\':
787  case '/':
788  *output_pointer++ = input_pointer[1];
789  break;
790 
791  /* UTF-16 literal */
792  case 'u':
793  sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
794  if (sequence_length == 0)
795  {
796  /* failed to convert UTF16-literal to UTF-8 */
797  goto fail;
798  }
799  break;
800 
801  default:
802  goto fail;
803  }
804  input_pointer += sequence_length;
805  }
806  }
807 
808  /* zero terminate the output */
809  *output_pointer = '\0';
810 
811  item->type = cJSON_String;
812  item->valuestring = (char*)output;
813 
814  input_buffer->offset = (size_t) (input_end - input_buffer->content);
815  input_buffer->offset++;
816 
817  return true;
818 
819 fail:
820  if (output != NULL)
821  {
822  input_buffer->hooks.deallocate(output);
823  }
824 
825  if (input_pointer != NULL)
826  {
827  input_buffer->offset = (size_t)(input_pointer - input_buffer->content);
828  }
829 
830  return false;
831 }
832 
833 /* Render the cstring provided to an escaped version that can be printed. */
834 static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer)
835 {
836  const unsigned char *input_pointer = NULL;
837  unsigned char *output = NULL;
838  unsigned char *output_pointer = NULL;
839  size_t output_length = 0;
840  /* numbers of additional characters needed for escaping */
841  size_t escape_characters = 0;
842 
843  if (output_buffer == NULL)
844  {
845  return false;
846  }
847 
848  /* empty string */
849  if (input == NULL)
850  {
851  output = ensure(output_buffer, sizeof("\"\""));
852  if (output == NULL)
853  {
854  return false;
855  }
856  strcpy((char*)output, "\"\"");
857 
858  return true;
859  }
860 
861  /* set "flag" to 1 if something needs to be escaped */
862  for (input_pointer = input; *input_pointer; input_pointer++)
863  {
864  switch (*input_pointer)
865  {
866  case '\"':
867  case '\\':
868  case '\b':
869  case '\f':
870  case '\n':
871  case '\r':
872  case '\t':
873  /* one character escape sequence */
874  escape_characters++;
875  break;
876  default:
877  if (*input_pointer < 32)
878  {
879  /* UTF-16 escape sequence uXXXX */
880  escape_characters += 5;
881  }
882  break;
883  }
884  }
885  output_length = (size_t)(input_pointer - input) + escape_characters;
886 
887  output = ensure(output_buffer, output_length + sizeof("\"\""));
888  if (output == NULL)
889  {
890  return false;
891  }
892 
893  /* no characters have to be escaped */
894  if (escape_characters == 0)
895  {
896  output[0] = '\"';
897  memcpy(output + 1, input, output_length);
898  output[output_length + 1] = '\"';
899  output[output_length + 2] = '\0';
900 
901  return true;
902  }
903 
904  output[0] = '\"';
905  output_pointer = output + 1;
906  /* copy the string */
907  for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++)
908  {
909  if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\'))
910  {
911  /* normal character, copy */
912  *output_pointer = *input_pointer;
913  }
914  else
915  {
916  /* character needs to be escaped */
917  *output_pointer++ = '\\';
918  switch (*input_pointer)
919  {
920  case '\\':
921  *output_pointer = '\\';
922  break;
923  case '\"':
924  *output_pointer = '\"';
925  break;
926  case '\b':
927  *output_pointer = 'b';
928  break;
929  case '\f':
930  *output_pointer = 'f';
931  break;
932  case '\n':
933  *output_pointer = 'n';
934  break;
935  case '\r':
936  *output_pointer = 'r';
937  break;
938  case '\t':
939  *output_pointer = 't';
940  break;
941  default:
942  /* escape and print as unicode codepoint */
943  sprintf((char*)output_pointer, "u%04x", *input_pointer);
944  output_pointer += 4;
945  break;
946  }
947  }
948  }
949  output[output_length + 1] = '\"';
950  output[output_length + 2] = '\0';
951 
952  return true;
953 }
954 
955 /* Invoke print_string_ptr (which is useful) on an item. */
956 static cJSON_bool print_string(const cJSON * const item, printbuffer * const p)
957 {
958  return print_string_ptr((unsigned char*)item->valuestring, p);
959 }
960 
961 /* Predeclare these prototypes. */
962 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer);
963 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer);
964 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer);
965 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer);
966 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer);
967 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer);
968 
969 /* Utility to jump whitespace and cr/lf */
971 {
972  if ((buffer == NULL) || (buffer->content == NULL))
973  {
974  return NULL;
975  }
976 
977  while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32))
978  {
979  buffer->offset++;
980  }
981 
982  if (buffer->offset == buffer->length)
983  {
984  buffer->offset--;
985  }
986 
987  return buffer;
988 }
989 
990 /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
992 {
993  if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
994  {
995  return NULL;
996  }
997 
998  if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
999  {
1000  buffer->offset += 3;
1001  }
1002 
1003  return buffer;
1004 }
1005 
1006 /* Parse an object - create a new root, and populate. */
1007 CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
1008 {
1009  parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
1010  cJSON *item = NULL;
1011 
1012  /* reset error position */
1013  global_error.json = NULL;
1014  global_error.position = 0;
1015 
1016  if (value == NULL)
1017  {
1018  goto fail;
1019  }
1020 
1021  buffer.content = (const unsigned char*)value;
1022  buffer.length = strlen((const char*)value) + sizeof("");
1023  buffer.offset = 0;
1024  buffer.hooks = global_hooks;
1025 
1026  item = cJSON_New_Item(&global_hooks);
1027  if (item == NULL) /* memory fail */
1028  {
1029  goto fail;
1030  }
1031 
1032  if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
1033  {
1034  /* parse failure. ep is set. */
1035  goto fail;
1036  }
1037 
1038  /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
1039  if (require_null_terminated)
1040  {
1041  buffer_skip_whitespace(&buffer);
1042  if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0')
1043  {
1044  goto fail;
1045  }
1046  }
1047  if (return_parse_end)
1048  {
1049  *return_parse_end = (const char*)buffer_at_offset(&buffer);
1050  }
1051 
1052  return item;
1053 
1054 fail:
1055  if (item != NULL)
1056  {
1057  cJSON_Delete(item);
1058  }
1059 
1060  if (value != NULL)
1061  {
1062  error local_error;
1063  local_error.json = (const unsigned char*)value;
1064  local_error.position = 0;
1065 
1066  if (buffer.offset < buffer.length)
1067  {
1068  local_error.position = buffer.offset;
1069  }
1070  else if (buffer.length > 0)
1071  {
1072  local_error.position = buffer.length - 1;
1073  }
1074 
1075  if (return_parse_end != NULL)
1076  {
1077  *return_parse_end = (const char*)local_error.json + local_error.position;
1078  }
1079 
1080  global_error = local_error;
1081  }
1082 
1083  return NULL;
1084 }
1085 
1086 /* Default options for cJSON_Parse */
1087 CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
1088 {
1089  return cJSON_ParseWithOpts(value, 0, 0);
1090 }
1091 
1092 #define cjson_min(a, b) ((a < b) ? a : b)
1093 
1094 static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks)
1095 {
1096  static const size_t default_buffer_size = 256;
1097  printbuffer buffer[1];
1098  unsigned char *printed = NULL;
1099 
1100  memset(buffer, 0, sizeof(buffer));
1101 
1102  /* create buffer */
1103  buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size);
1104  buffer->length = default_buffer_size;
1105  buffer->format = format;
1106  buffer->hooks = *hooks;
1107 
1108  if (buffer->buffer == NULL) {
1109  goto fail;
1110  }
1111 
1112  /* print the value */
1113  if (!print_value(item, buffer)) {
1114  goto fail;
1115  }
1116 
1117  update_offset(buffer);
1118 
1119  /* check if reallocate is available */
1120  if (hooks->reallocate != NULL) {
1121  printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
1122  if (printed == NULL) {
1123  goto fail;
1124  }
1125 
1126  buffer->buffer = NULL;
1127  } else { /* otherwise copy the JSON over to a new buffer */
1128  printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
1129  if (printed == NULL) {
1130  goto fail;
1131  }
1132 
1133  memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
1134  printed[buffer->offset] = '\0'; /* just to be sure */
1135 
1136  /* free the buffer */
1137  hooks->deallocate(buffer->buffer);
1138  }
1139 
1140  return printed;
1141 
1142 fail:
1143  if (buffer->buffer != NULL) {
1144  hooks->deallocate(buffer->buffer);
1145  }
1146 
1147  return NULL;
1148 }
1149 
1150 /* Render a cJSON item/entity/structure to text. */
1151 CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
1152 {
1153  return (char*)print(item, true, &global_hooks);
1154 }
1155 
1156 CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item)
1157 {
1158  return (char*)print(item, false, &global_hooks);
1159 }
1160 
1161 CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)
1162 {
1163  printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1164 
1165  if (prebuffer < 0)
1166  {
1167  return NULL;
1168  }
1169 
1170  p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer);
1171  if (!p.buffer)
1172  {
1173  return NULL;
1174  }
1175 
1176  p.length = (size_t)prebuffer;
1177  p.offset = 0;
1178  p.noalloc = false;
1179  p.format = fmt;
1180  p.hooks = global_hooks;
1181 
1182  if (!print_value(item, &p))
1183  {
1184  global_hooks.deallocate(p.buffer);
1185  return NULL;
1186  }
1187 
1188  return (char*)p.buffer;
1189 }
1190 
1191 CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt)
1192 {
1193  printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
1194 
1195  if ((len < 0) || (buf == NULL))
1196  {
1197  return false;
1198  }
1199 
1200  p.buffer = (unsigned char*)buf;
1201  p.length = (size_t)len;
1202  p.offset = 0;
1203  p.noalloc = true;
1204  p.format = fmt;
1205  p.hooks = global_hooks;
1206 
1207  return print_value(item, &p);
1208 }
1209 
1210 /* Parser core - when encountering text, process appropriately. */
1211 static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer)
1212 {
1213  if ((input_buffer == NULL) || (input_buffer->content == NULL))
1214  {
1215  return false; /* no input */
1216  }
1217 
1218  /* parse the different types of values */
1219  /* null */
1220  if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0))
1221  {
1222  item->type = cJSON_NULL;
1223  input_buffer->offset += 4;
1224  return true;
1225  }
1226  /* false */
1227  if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0))
1228  {
1229  item->type = cJSON_False;
1230  input_buffer->offset += 5;
1231  return true;
1232  }
1233  /* true */
1234  if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0))
1235  {
1236  item->type = cJSON_True;
1237  item->valueint = 1;
1238  input_buffer->offset += 4;
1239  return true;
1240  }
1241  /* string */
1242  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"'))
1243  {
1244  return parse_string(item, input_buffer);
1245  }
1246  /* number */
1247  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'))))
1248  {
1249  return parse_number(item, input_buffer);
1250  }
1251  /* array */
1252  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '['))
1253  {
1254  return parse_array(item, input_buffer);
1255  }
1256  /* object */
1257  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{'))
1258  {
1259  return parse_object(item, input_buffer);
1260  }
1261 
1262  return false;
1263 }
1264 
1265 /* Render a value to text. */
1266 static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer)
1267 {
1268  unsigned char *output = NULL;
1269 
1270  if ((item == NULL) || (output_buffer == NULL))
1271  {
1272  return false;
1273  }
1274 
1275  switch ((item->type) & 0xFF)
1276  {
1277  case cJSON_NULL:
1278  output = ensure(output_buffer, 5);
1279  if (output == NULL)
1280  {
1281  return false;
1282  }
1283  strcpy((char*)output, "null");
1284  return true;
1285 
1286  case cJSON_False:
1287  output = ensure(output_buffer, 6);
1288  if (output == NULL)
1289  {
1290  return false;
1291  }
1292  strcpy((char*)output, "false");
1293  return true;
1294 
1295  case cJSON_True:
1296  output = ensure(output_buffer, 5);
1297  if (output == NULL)
1298  {
1299  return false;
1300  }
1301  strcpy((char*)output, "true");
1302  return true;
1303 
1304  case cJSON_Number:
1305  return print_number(item, output_buffer);
1306 
1307  case cJSON_Raw:
1308  {
1309  size_t raw_length = 0;
1310  if (item->valuestring == NULL)
1311  {
1312  return false;
1313  }
1314 
1315  raw_length = strlen(item->valuestring) + sizeof("");
1316  output = ensure(output_buffer, raw_length);
1317  if (output == NULL)
1318  {
1319  return false;
1320  }
1321  memcpy(output, item->valuestring, raw_length);
1322  return true;
1323  }
1324 
1325  case cJSON_String:
1326  return print_string(item, output_buffer);
1327 
1328  case cJSON_Array:
1329  return print_array(item, output_buffer);
1330 
1331  case cJSON_Object:
1332  return print_object(item, output_buffer);
1333 
1334  default:
1335  return false;
1336  }
1337 }
1338 
1339 /* Build an array from input text. */
1340 static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer)
1341 {
1342  cJSON *head = NULL; /* head of the linked list */
1343  cJSON *current_item = NULL;
1344 
1345  if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1346  {
1347  return false; /* to deeply nested */
1348  }
1349  input_buffer->depth++;
1350 
1351  if (buffer_at_offset(input_buffer)[0] != '[')
1352  {
1353  /* not an array */
1354  goto fail;
1355  }
1356 
1357  input_buffer->offset++;
1358  buffer_skip_whitespace(input_buffer);
1359  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']'))
1360  {
1361  /* empty array */
1362  goto success;
1363  }
1364 
1365  /* check if we skipped to the end of the buffer */
1366  if (cannot_access_at_index(input_buffer, 0))
1367  {
1368  input_buffer->offset--;
1369  goto fail;
1370  }
1371 
1372  /* step back to character in front of the first element */
1373  input_buffer->offset--;
1374  /* loop through the comma separated array elements */
1375  do
1376  {
1377  /* allocate next item */
1378  cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1379  if (new_item == NULL)
1380  {
1381  goto fail; /* allocation failure */
1382  }
1383 
1384  /* attach next item to list */
1385  if (head == NULL)
1386  {
1387  /* start the linked list */
1388  current_item = head = new_item;
1389  }
1390  else
1391  {
1392  /* add to the end and advance */
1393  current_item->next = new_item;
1394  new_item->prev = current_item;
1395  current_item = new_item;
1396  }
1397 
1398  /* parse next value */
1399  input_buffer->offset++;
1400  buffer_skip_whitespace(input_buffer);
1401  if (!parse_value(current_item, input_buffer))
1402  {
1403  goto fail; /* failed to parse value */
1404  }
1405  buffer_skip_whitespace(input_buffer);
1406  }
1407  while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1408 
1409  if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']')
1410  {
1411  goto fail; /* expected end of array */
1412  }
1413 
1414 success:
1415  input_buffer->depth--;
1416 
1417  item->type = cJSON_Array;
1418  item->child = head;
1419 
1420  input_buffer->offset++;
1421 
1422  return true;
1423 
1424 fail:
1425  if (head != NULL)
1426  {
1427  cJSON_Delete(head);
1428  }
1429 
1430  return false;
1431 }
1432 
1433 /* Render an array to text */
1434 static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer)
1435 {
1436  unsigned char *output_pointer = NULL;
1437  size_t length = 0;
1438  cJSON *current_element = item->child;
1439 
1440  if (output_buffer == NULL)
1441  {
1442  return false;
1443  }
1444 
1445  /* Compose the output array. */
1446  /* opening square bracket */
1447  output_pointer = ensure(output_buffer, 1);
1448  if (output_pointer == NULL)
1449  {
1450  return false;
1451  }
1452 
1453  *output_pointer = '[';
1454  output_buffer->offset++;
1455  output_buffer->depth++;
1456 
1457  while (current_element != NULL)
1458  {
1459  if (!print_value(current_element, output_buffer))
1460  {
1461  return false;
1462  }
1463  update_offset(output_buffer);
1464  if (current_element->next)
1465  {
1466  length = (size_t) (output_buffer->format ? 2 : 1);
1467  output_pointer = ensure(output_buffer, length + 1);
1468  if (output_pointer == NULL)
1469  {
1470  return false;
1471  }
1472  *output_pointer++ = ',';
1473  if(output_buffer->format)
1474  {
1475  *output_pointer++ = ' ';
1476  }
1477  *output_pointer = '\0';
1478  output_buffer->offset += length;
1479  }
1480  current_element = current_element->next;
1481  }
1482 
1483  output_pointer = ensure(output_buffer, 2);
1484  if (output_pointer == NULL)
1485  {
1486  return false;
1487  }
1488  *output_pointer++ = ']';
1489  *output_pointer = '\0';
1490  output_buffer->depth--;
1491 
1492  return true;
1493 }
1494 
1495 /* Build an object from the text. */
1496 static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer)
1497 {
1498  cJSON *head = NULL; /* linked list head */
1499  cJSON *current_item = NULL;
1500 
1501  if (input_buffer->depth >= CJSON_NESTING_LIMIT)
1502  {
1503  return false; /* to deeply nested */
1504  }
1505  input_buffer->depth++;
1506 
1507  if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{'))
1508  {
1509  goto fail; /* not an object */
1510  }
1511 
1512  input_buffer->offset++;
1513  buffer_skip_whitespace(input_buffer);
1514  if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}'))
1515  {
1516  goto success; /* empty object */
1517  }
1518 
1519  /* check if we skipped to the end of the buffer */
1520  if (cannot_access_at_index(input_buffer, 0))
1521  {
1522  input_buffer->offset--;
1523  goto fail;
1524  }
1525 
1526  /* step back to character in front of the first element */
1527  input_buffer->offset--;
1528  /* loop through the comma separated array elements */
1529  do
1530  {
1531  /* allocate next item */
1532  cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks));
1533  if (new_item == NULL)
1534  {
1535  goto fail; /* allocation failure */
1536  }
1537 
1538  /* attach next item to list */
1539  if (head == NULL)
1540  {
1541  /* start the linked list */
1542  current_item = head = new_item;
1543  }
1544  else
1545  {
1546  /* add to the end and advance */
1547  current_item->next = new_item;
1548  new_item->prev = current_item;
1549  current_item = new_item;
1550  }
1551 
1552  /* parse the name of the child */
1553  input_buffer->offset++;
1554  buffer_skip_whitespace(input_buffer);
1555  if (!parse_string(current_item, input_buffer))
1556  {
1557  goto fail; /* failed to parse name */
1558  }
1559  buffer_skip_whitespace(input_buffer);
1560 
1561  /* swap valuestring and string, because we parsed the name */
1562  current_item->string = current_item->valuestring;
1563  current_item->valuestring = NULL;
1564 
1565  if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':'))
1566  {
1567  goto fail; /* invalid object */
1568  }
1569 
1570  /* parse the value */
1571  input_buffer->offset++;
1572  buffer_skip_whitespace(input_buffer);
1573  if (!parse_value(current_item, input_buffer))
1574  {
1575  goto fail; /* failed to parse value */
1576  }
1577  buffer_skip_whitespace(input_buffer);
1578  }
1579  while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
1580 
1581  if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}'))
1582  {
1583  goto fail; /* expected end of object */
1584  }
1585 
1586 success:
1587  input_buffer->depth--;
1588 
1589  item->type = cJSON_Object;
1590  item->child = head;
1591 
1592  input_buffer->offset++;
1593  return true;
1594 
1595 fail:
1596  if (head != NULL)
1597  {
1598  cJSON_Delete(head);
1599  }
1600 
1601  return false;
1602 }
1603 
1604 /* Render an object to text. */
1605 static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer)
1606 {
1607  unsigned char *output_pointer = NULL;
1608  size_t length = 0;
1609  cJSON *current_item = item->child;
1610 
1611  if (output_buffer == NULL)
1612  {
1613  return false;
1614  }
1615 
1616  /* Compose the output: */
1617  length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */
1618  output_pointer = ensure(output_buffer, length + 1);
1619  if (output_pointer == NULL)
1620  {
1621  return false;
1622  }
1623 
1624  *output_pointer++ = '{';
1625  output_buffer->depth++;
1626  if (output_buffer->format)
1627  {
1628  *output_pointer++ = '\n';
1629  }
1630  output_buffer->offset += length;
1631 
1632  while (current_item)
1633  {
1634  if (output_buffer->format)
1635  {
1636  size_t i;
1637  output_pointer = ensure(output_buffer, output_buffer->depth);
1638  if (output_pointer == NULL)
1639  {
1640  return false;
1641  }
1642  for (i = 0; i < output_buffer->depth; i++)
1643  {
1644  *output_pointer++ = '\t';
1645  }
1646  output_buffer->offset += output_buffer->depth;
1647  }
1648 
1649  /* print key */
1650  if (!print_string_ptr((unsigned char*)current_item->string, output_buffer))
1651  {
1652  return false;
1653  }
1654  update_offset(output_buffer);
1655 
1656  length = (size_t) (output_buffer->format ? 2 : 1);
1657  output_pointer = ensure(output_buffer, length);
1658  if (output_pointer == NULL)
1659  {
1660  return false;
1661  }
1662  *output_pointer++ = ':';
1663  if (output_buffer->format)
1664  {
1665  *output_pointer++ = '\t';
1666  }
1667  output_buffer->offset += length;
1668 
1669  /* print value */
1670  if (!print_value(current_item, output_buffer))
1671  {
1672  return false;
1673  }
1674  update_offset(output_buffer);
1675 
1676  /* print comma if not last */
1677  length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0));
1678  output_pointer = ensure(output_buffer, length + 1);
1679  if (output_pointer == NULL)
1680  {
1681  return false;
1682  }
1683  if (current_item->next)
1684  {
1685  *output_pointer++ = ',';
1686  }
1687 
1688  if (output_buffer->format)
1689  {
1690  *output_pointer++ = '\n';
1691  }
1692  *output_pointer = '\0';
1693  output_buffer->offset += length;
1694 
1695  current_item = current_item->next;
1696  }
1697 
1698  output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
1699  if (output_pointer == NULL)
1700  {
1701  return false;
1702  }
1703  if (output_buffer->format)
1704  {
1705  size_t i;
1706  for (i = 0; i < (output_buffer->depth - 1); i++)
1707  {
1708  *output_pointer++ = '\t';
1709  }
1710  }
1711  *output_pointer++ = '}';
1712  *output_pointer = '\0';
1713  output_buffer->depth--;
1714 
1715  return true;
1716 }
1717 
1718 /* Get Array size/item / object item. */
1719 CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
1720 {
1721  cJSON *child = NULL;
1722  size_t size = 0;
1723 
1724  if (array == NULL)
1725  {
1726  return 0;
1727  }
1728 
1729  child = array->child;
1730 
1731  while(child != NULL)
1732  {
1733  size++;
1734  child = child->next;
1735  }
1736 
1737  /* FIXME: Can overflow here. Cannot be fixed without breaking the API */
1738 
1739  return (int)size;
1740 }
1741 
1742 static cJSON* get_array_item(const cJSON *array, size_t index)
1743 {
1744  cJSON *current_child = NULL;
1745 
1746  if (array == NULL)
1747  {
1748  return NULL;
1749  }
1750 
1751  current_child = array->child;
1752  while ((current_child != NULL) && (index > 0))
1753  {
1754  index--;
1755  current_child = current_child->next;
1756  }
1757 
1758  return current_child;
1759 }
1760 
1761 CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
1762 {
1763  if (index < 0)
1764  {
1765  return NULL;
1766  }
1767 
1768  return get_array_item(array, (size_t)index);
1769 }
1770 
1771 static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
1772 {
1773  cJSON *current_element = NULL;
1774 
1775  if ((object == NULL) || (name == NULL))
1776  {
1777  return NULL;
1778  }
1779 
1780  current_element = object->child;
1781  if (case_sensitive)
1782  {
1783  while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0))
1784  {
1785  current_element = current_element->next;
1786  }
1787  }
1788  else
1789  {
1790  while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0))
1791  {
1792  current_element = current_element->next;
1793  }
1794  }
1795 
1796  if ((current_element == NULL) || (current_element->string == NULL)) {
1797  return NULL;
1798  }
1799 
1800  return current_element;
1801 }
1802 
1803 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)
1804 {
1805  return get_object_item(object, string, false);
1806 }
1807 
1808 CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
1809 {
1810  return get_object_item(object, string, true);
1811 }
1812 
1813 CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string)
1814 {
1815  return cJSON_GetObjectItem(object, string) ? 1 : 0;
1816 }
1817 
1818 /* Utility for array list handling. */
1819 static void suffix_object(cJSON *prev, cJSON *item)
1820 {
1821  prev->next = item;
1822  item->prev = prev;
1823 }
1824 
1825 /* Utility for handling references. */
1826 static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
1827 {
1828  cJSON *reference = NULL;
1829  if (item == NULL)
1830  {
1831  return NULL;
1832  }
1833 
1834  reference = cJSON_New_Item(hooks);
1835  if (reference == NULL)
1836  {
1837  return NULL;
1838  }
1839 
1840  memcpy(reference, item, sizeof(cJSON));
1841  reference->string = NULL;
1842  reference->type |= cJSON_IsReference;
1843  reference->next = reference->prev = NULL;
1844  return reference;
1845 }
1846 
1848 {
1849  cJSON *child = NULL;
1850 
1851  if ((item == NULL) || (array == NULL))
1852  {
1853  return false;
1854  }
1855 
1856  child = array->child;
1857 
1858  if (child == NULL)
1859  {
1860  /* list is empty, start new one */
1861  array->child = item;
1862  }
1863  else
1864  {
1865  /* append to the end */
1866  while (child->next)
1867  {
1868  child = child->next;
1869  }
1870  suffix_object(child, item);
1871  }
1872 
1873  return true;
1874 }
1875 
1876 /* Add item to array/object. */
1877 CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
1878 {
1879  add_item_to_array(array, item);
1880 }
1881 
1882 #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
1883  #pragma GCC diagnostic push
1884 #endif
1885 #ifdef __GNUC__
1886 #pragma GCC diagnostic ignored "-Wcast-qual"
1887 #endif
1888 /* helper function to cast away const */
1889 static void* cast_away_const(const void* string)
1890 {
1891  return (void*)string;
1892 }
1893 #if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
1894  #pragma GCC diagnostic pop
1895 #endif
1896 
1897 
1898 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)
1899 {
1900  char *new_key = NULL;
1901  int new_type = cJSON_Invalid;
1902 
1903  if ((object == NULL) || (string == NULL) || (item == NULL))
1904  {
1905  return false;
1906  }
1907 
1908  if (constant_key)
1909  {
1910  new_key = (char*)cast_away_const(string);
1911  new_type = item->type | cJSON_StringIsConst;
1912  }
1913  else
1914  {
1915  new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks);
1916  if (new_key == NULL)
1917  {
1918  return false;
1919  }
1920 
1921  new_type = item->type & ~cJSON_StringIsConst;
1922  }
1923 
1924  if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
1925  {
1926  hooks->deallocate(item->string);
1927  }
1928 
1929  item->string = new_key;
1930  item->type = new_type;
1931 
1932  return add_item_to_array(object, item);
1933 }
1934 
1935 CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
1936 {
1937  cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, false);
1938  (void)res;
1939 }
1940 
1941 /* Add an item to an object with constant string as key */
1942 CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
1943 {
1944  cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, true);
1945  (void)res;
1946 }
1947 
1948 CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
1949 {
1950  cJSON_bool res;
1951 
1952  if (array == NULL)
1953  {
1954  return;
1955  }
1956 
1957  res = add_item_to_array(array, create_reference(item, &global_hooks));
1958  (void)res;
1959 }
1960 
1961 CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
1962 {
1963  cJSON_bool res;
1964 
1965  if ((object == NULL) || (string == NULL))
1966  {
1967  return;
1968  }
1969 
1970  res = add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
1971  (void)res;
1972 }
1973 
1974 CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)
1975 {
1976  cJSON *null = cJSON_CreateNull();
1977  if (add_item_to_object(object, name, null, &global_hooks, false))
1978  {
1979  return null;
1980  }
1981 
1982  cJSON_Delete(null);
1983  return NULL;
1984 }
1985 
1986 CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name)
1987 {
1988  cJSON *true_item = cJSON_CreateTrue();
1989  if (add_item_to_object(object, name, true_item, &global_hooks, false))
1990  {
1991  return true_item;
1992  }
1993 
1994  cJSON_Delete(true_item);
1995  return NULL;
1996 }
1997 
1998 CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name)
1999 {
2000  cJSON *false_item = cJSON_CreateFalse();
2001  if (add_item_to_object(object, name, false_item, &global_hooks, false))
2002  {
2003  return false_item;
2004  }
2005 
2006  cJSON_Delete(false_item);
2007  return NULL;
2008 }
2009 
2010 CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean)
2011 {
2012  cJSON *bool_item = cJSON_CreateBool(boolean);
2013  if (add_item_to_object(object, name, bool_item, &global_hooks, false))
2014  {
2015  return bool_item;
2016  }
2017 
2018  cJSON_Delete(bool_item);
2019  return NULL;
2020 }
2021 
2022 CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number)
2023 {
2024  cJSON *number_item = cJSON_CreateNumber(number);
2025  if (add_item_to_object(object, name, number_item, &global_hooks, false))
2026  {
2027  return number_item;
2028  }
2029 
2030  cJSON_Delete(number_item);
2031  return NULL;
2032 }
2033 
2034 CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
2035 {
2036  cJSON *string_item = cJSON_CreateString(string);
2037  if (add_item_to_object(object, name, string_item, &global_hooks, false))
2038  {
2039  return string_item;
2040  }
2041 
2042  cJSON_Delete(string_item);
2043  return NULL;
2044 }
2045 
2046 CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw)
2047 {
2048  cJSON *raw_item = cJSON_CreateRaw(raw);
2049  if (add_item_to_object(object, name, raw_item, &global_hooks, false))
2050  {
2051  return raw_item;
2052  }
2053 
2054  cJSON_Delete(raw_item);
2055  return NULL;
2056 }
2057 
2058 CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name)
2059 {
2060  cJSON *object_item = cJSON_CreateObject();
2061  if (add_item_to_object(object, name, object_item, &global_hooks, false))
2062  {
2063  return object_item;
2064  }
2065 
2066  cJSON_Delete(object_item);
2067  return NULL;
2068 }
2069 
2070 CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name)
2071 {
2072  cJSON *array = cJSON_CreateArray();
2073  if (add_item_to_object(object, name, array, &global_hooks, false))
2074  {
2075  return array;
2076  }
2077 
2078  cJSON_Delete(array);
2079  return NULL;
2080 }
2081 
2082 CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
2083 {
2084  if ((parent == NULL) || (item == NULL))
2085  {
2086  return NULL;
2087  }
2088 
2089  if (item->prev != NULL)
2090  {
2091  /* not the first element */
2092  item->prev->next = item->next;
2093  }
2094  if (item->next != NULL)
2095  {
2096  /* not the last element */
2097  item->next->prev = item->prev;
2098  }
2099 
2100  if (item == parent->child)
2101  {
2102  /* first element */
2103  parent->child = item->next;
2104  }
2105  /* make sure the detached item doesn't point anywhere anymore */
2106  item->prev = NULL;
2107  item->next = NULL;
2108 
2109  return item;
2110 }
2111 
2112 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
2113 {
2114  if (which < 0)
2115  {
2116  return NULL;
2117  }
2118 
2119  return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
2120 }
2121 
2122 CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
2123 {
2124  cJSON_Delete(cJSON_DetachItemFromArray(array, which));
2125 }
2126 
2127 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
2128 {
2129  cJSON *to_detach = cJSON_GetObjectItem(object, string);
2130 
2131  return cJSON_DetachItemViaPointer(object, to_detach);
2132 }
2133 
2134 CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
2135 {
2136  cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
2137 
2138  return cJSON_DetachItemViaPointer(object, to_detach);
2139 }
2140 
2141 CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
2142 {
2143  cJSON_Delete(cJSON_DetachItemFromObject(object, string));
2144 }
2145 
2146 CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
2147 {
2148  cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
2149 }
2150 
2151 /* Replace array/object items with new ones. */
2152 CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
2153 {
2154  cJSON *after_inserted = NULL;
2155 
2156  if (which < 0)
2157  {
2158  return;
2159  }
2160 
2161  after_inserted = get_array_item(array, (size_t)which);
2162  if (after_inserted == NULL)
2163  {
2164  add_item_to_array(array, newitem);
2165  return;
2166  }
2167 
2168  newitem->next = after_inserted;
2169  newitem->prev = after_inserted->prev;
2170  after_inserted->prev = newitem;
2171  if (after_inserted == array->child)
2172  {
2173  array->child = newitem;
2174  }
2175  else
2176  {
2177  newitem->prev->next = newitem;
2178  }
2179 }
2180 
2181 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
2182 {
2183  if ((parent == NULL) || (replacement == NULL) || (item == NULL))
2184  {
2185  return false;
2186  }
2187 
2188  if (replacement == item)
2189  {
2190  return true;
2191  }
2192 
2193  replacement->next = item->next;
2194  replacement->prev = item->prev;
2195 
2196  if (replacement->next != NULL)
2197  {
2198  replacement->next->prev = replacement;
2199  }
2200  if (replacement->prev != NULL)
2201  {
2202  replacement->prev->next = replacement;
2203  }
2204  if (parent->child == item)
2205  {
2206  parent->child = replacement;
2207  }
2208 
2209  item->next = NULL;
2210  item->prev = NULL;
2211  cJSON_Delete(item);
2212 
2213  return true;
2214 }
2215 
2216 CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
2217 {
2218  if (which < 0)
2219  {
2220  return;
2221  }
2222 
2223  cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
2224 }
2225 
2226 static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
2227 {
2228  if ((replacement == NULL) || (string == NULL))
2229  {
2230  return false;
2231  }
2232 
2233  /* replace the name in the replacement */
2234  if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
2235  {
2236  cJSON_free(replacement->string);
2237  }
2238  replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2239  replacement->type &= ~cJSON_StringIsConst;
2240 
2241  cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
2242 
2243  return true;
2244 }
2245 
2246 CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
2247 {
2248  replace_item_in_object(object, string, newitem, false);
2249 }
2250 
2251 CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
2252 {
2253  replace_item_in_object(object, string, newitem, true);
2254 }
2255 
2256 /* Create basic types: */
2257 CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void)
2258 {
2259  cJSON *item = cJSON_New_Item(&global_hooks);
2260  if(item)
2261  {
2262  item->type = cJSON_NULL;
2263  }
2264 
2265  return item;
2266 }
2267 
2268 CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void)
2269 {
2270  cJSON *item = cJSON_New_Item(&global_hooks);
2271  if(item)
2272  {
2273  item->type = cJSON_True;
2274  }
2275 
2276  return item;
2277 }
2278 
2279 CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void)
2280 {
2281  cJSON *item = cJSON_New_Item(&global_hooks);
2282  if(item)
2283  {
2284  item->type = cJSON_False;
2285  }
2286 
2287  return item;
2288 }
2289 
2290 CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b)
2291 {
2292  cJSON *item = cJSON_New_Item(&global_hooks);
2293  if(item)
2294  {
2295  item->type = b ? cJSON_True : cJSON_False;
2296  }
2297 
2298  return item;
2299 }
2300 
2301 CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num)
2302 {
2303  cJSON *item = cJSON_New_Item(&global_hooks);
2304  if(item)
2305  {
2306  item->type = cJSON_Number;
2307  item->valuedouble = num;
2308 
2309  /* use saturation in case of overflow */
2310  if (num >= INT_MAX)
2311  {
2312  item->valueint = INT_MAX;
2313  }
2314  else if (num <= (double)INT_MIN)
2315  {
2316  item->valueint = INT_MIN;
2317  }
2318  else
2319  {
2320  item->valueint = (int)num;
2321  }
2322  }
2323 
2324  return item;
2325 }
2326 
2327 CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string)
2328 {
2329  cJSON *item = cJSON_New_Item(&global_hooks);
2330  if(item)
2331  {
2332  item->type = cJSON_String;
2333  item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
2334  if(!item->valuestring)
2335  {
2336  cJSON_Delete(item);
2337  return NULL;
2338  }
2339  }
2340 
2341  return item;
2342 }
2343 
2344 CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string)
2345 {
2346  cJSON *item = cJSON_New_Item(&global_hooks);
2347  if (item != NULL)
2348  {
2350  item->valuestring = (char*)cast_away_const(string);
2351  }
2352 
2353  return item;
2354 }
2355 
2356 CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child)
2357 {
2358  cJSON *item = cJSON_New_Item(&global_hooks);
2359  if (item != NULL) {
2361  item->child = (cJSON*)cast_away_const(child);
2362  }
2363 
2364  return item;
2365 }
2366 
2367 CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) {
2368  cJSON *item = cJSON_New_Item(&global_hooks);
2369  if (item != NULL) {
2371  item->child = (cJSON*)cast_away_const(child);
2372  }
2373 
2374  return item;
2375 }
2376 
2377 CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw)
2378 {
2379  cJSON *item = cJSON_New_Item(&global_hooks);
2380  if(item)
2381  {
2382  item->type = cJSON_Raw;
2383  item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks);
2384  if(!item->valuestring)
2385  {
2386  cJSON_Delete(item);
2387  return NULL;
2388  }
2389  }
2390 
2391  return item;
2392 }
2393 
2394 CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
2395 {
2396  cJSON *item = cJSON_New_Item(&global_hooks);
2397  if(item)
2398  {
2399  item->type=cJSON_Array;
2400  }
2401 
2402  return item;
2403 }
2404 
2405 CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
2406 {
2407  cJSON *item = cJSON_New_Item(&global_hooks);
2408  if (item)
2409  {
2410  item->type = cJSON_Object;
2411  }
2412 
2413  return item;
2414 }
2415 
2416 /* Create Arrays: */
2417 CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
2418 {
2419  size_t i = 0;
2420  cJSON *n = NULL;
2421  cJSON *p = NULL;
2422  cJSON *a = NULL;
2423 
2424  if ((count < 0) || (numbers == NULL))
2425  {
2426  return NULL;
2427  }
2428 
2429  a = cJSON_CreateArray();
2430  for(i = 0; a && (i < (size_t)count); i++)
2431  {
2432  n = cJSON_CreateNumber(numbers[i]);
2433  if (!n)
2434  {
2435  cJSON_Delete(a);
2436  return NULL;
2437  }
2438  if(!i)
2439  {
2440  a->child = n;
2441  }
2442  else
2443  {
2444  suffix_object(p, n);
2445  }
2446  p = n;
2447  }
2448 
2449  return a;
2450 }
2451 
2452 CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
2453 {
2454  size_t i = 0;
2455  cJSON *n = NULL;
2456  cJSON *p = NULL;
2457  cJSON *a = NULL;
2458 
2459  if ((count < 0) || (numbers == NULL))
2460  {
2461  return NULL;
2462  }
2463 
2464  a = cJSON_CreateArray();
2465 
2466  for(i = 0; a && (i < (size_t)count); i++)
2467  {
2468  n = cJSON_CreateNumber((double)numbers[i]);
2469  if(!n)
2470  {
2471  cJSON_Delete(a);
2472  return NULL;
2473  }
2474  if(!i)
2475  {
2476  a->child = n;
2477  }
2478  else
2479  {
2480  suffix_object(p, n);
2481  }
2482  p = n;
2483  }
2484 
2485  return a;
2486 }
2487 
2488 CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
2489 {
2490  size_t i = 0;
2491  cJSON *n = NULL;
2492  cJSON *p = NULL;
2493  cJSON *a = NULL;
2494 
2495  if ((count < 0) || (numbers == NULL))
2496  {
2497  return NULL;
2498  }
2499 
2500  a = cJSON_CreateArray();
2501 
2502  for(i = 0;a && (i < (size_t)count); i++)
2503  {
2504  n = cJSON_CreateNumber(numbers[i]);
2505  if(!n)
2506  {
2507  cJSON_Delete(a);
2508  return NULL;
2509  }
2510  if(!i)
2511  {
2512  a->child = n;
2513  }
2514  else
2515  {
2516  suffix_object(p, n);
2517  }
2518  p = n;
2519  }
2520 
2521  return a;
2522 }
2523 
2524 CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
2525 {
2526  size_t i = 0;
2527  cJSON *n = NULL;
2528  cJSON *p = NULL;
2529  cJSON *a = NULL;
2530 
2531  if ((count < 0) || (strings == NULL))
2532  {
2533  return NULL;
2534  }
2535 
2536  a = cJSON_CreateArray();
2537 
2538  for (i = 0; a && (i < (size_t)count); i++)
2539  {
2540  n = cJSON_CreateString(strings[i]);
2541  if(!n)
2542  {
2543  cJSON_Delete(a);
2544  return NULL;
2545  }
2546  if(!i)
2547  {
2548  a->child = n;
2549  }
2550  else
2551  {
2552  suffix_object(p,n);
2553  }
2554  p = n;
2555  }
2556 
2557  return a;
2558 }
2559 
2560 /* Duplication */
2561 CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
2562 {
2563  cJSON *newitem = NULL;
2564  cJSON *child = NULL;
2565  cJSON *next = NULL;
2566  cJSON *newchild = NULL;
2567 
2568  /* Bail on bad ptr */
2569  if (!item)
2570  {
2571  goto fail;
2572  }
2573  /* Create new item */
2574  newitem = cJSON_New_Item(&global_hooks);
2575  if (!newitem)
2576  {
2577  goto fail;
2578  }
2579  /* Copy over all vars */
2580  newitem->type = item->type & (~cJSON_IsReference);
2581  newitem->valueint = item->valueint;
2582  newitem->valuedouble = item->valuedouble;
2583  if (item->valuestring)
2584  {
2585  newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks);
2586  if (!newitem->valuestring)
2587  {
2588  goto fail;
2589  }
2590  }
2591  if (item->string)
2592  {
2593  newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks);
2594  if (!newitem->string)
2595  {
2596  goto fail;
2597  }
2598  }
2599  /* If non-recursive, then we're done! */
2600  if (!recurse)
2601  {
2602  return newitem;
2603  }
2604  /* Walk the ->next chain for the child. */
2605  child = item->child;
2606  while (child != NULL)
2607  {
2608  newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
2609  if (!newchild)
2610  {
2611  goto fail;
2612  }
2613  if (next != NULL)
2614  {
2615  /* If newitem->child already set, then crosswire ->prev and ->next and move on */
2616  next->next = newchild;
2617  newchild->prev = next;
2618  next = newchild;
2619  }
2620  else
2621  {
2622  /* Set newitem->child and move to it */
2623  newitem->child = newchild;
2624  next = newchild;
2625  }
2626  child = child->next;
2627  }
2628 
2629  return newitem;
2630 
2631 fail:
2632  if (newitem != NULL)
2633  {
2634  cJSON_Delete(newitem);
2635  }
2636 
2637  return NULL;
2638 }
2639 
2640 static void skip_oneline_comment(char **input)
2641 {
2642  *input += static_strlen("//");
2643 
2644  for (; (*input)[0] != '\0'; ++(*input))
2645  {
2646  if ((*input)[0] == '\n') {
2647  *input += static_strlen("\n");
2648  return;
2649  }
2650  }
2651 }
2652 
2653 static void skip_multiline_comment(char **input)
2654 {
2655  *input += static_strlen("/*");
2656 
2657  for (; (*input)[0] != '\0'; ++(*input))
2658  {
2659  if (((*input)[0] == '*') && ((*input)[1] == '/'))
2660  {
2661  *input += static_strlen("*/");
2662  return;
2663  }
2664  }
2665 }
2666 
2667 static void minify_string(char **input, char **output) {
2668  (*output)[0] = (*input)[0];
2669  *input += static_strlen("\"");
2670  *output += static_strlen("\"");
2671 
2672 
2673  for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) {
2674  (*output)[0] = (*input)[0];
2675 
2676  if ((*input)[0] == '\"') {
2677  (*output)[0] = '\"';
2678  *input += static_strlen("\"");
2679  *output += static_strlen("\"");
2680  return;
2681  } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) {
2682  (*output)[1] = (*input)[1];
2683  *input += static_strlen("\"");
2684  *output += static_strlen("\"");
2685  }
2686  }
2687 }
2688 
2689 CJSON_PUBLIC(void) cJSON_Minify(char *json)
2690 {
2691  char *into = json;
2692 
2693  if (json == NULL)
2694  {
2695  return;
2696  }
2697 
2698  while (json[0] != '\0')
2699  {
2700  switch (json[0])
2701  {
2702  case ' ':
2703  case '\t':
2704  case '\r':
2705  case '\n':
2706  json++;
2707  break;
2708 
2709  case '/':
2710  if (json[1] == '/')
2711  {
2712  skip_oneline_comment(&json);
2713  }
2714  else if (json[1] == '*')
2715  {
2716  skip_multiline_comment(&json);
2717  } else {
2718  json++;
2719  }
2720  break;
2721 
2722  case '\"':
2723  minify_string(&json, (char**)&into);
2724  break;
2725 
2726  default:
2727  into[0] = json[0];
2728  json++;
2729  into++;
2730  }
2731  }
2732 
2733  /* and null-terminate. */
2734  *into = '\0';
2735 }
2736 
2737 CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item)
2738 {
2739  if (item == NULL)
2740  {
2741  return false;
2742  }
2743 
2744  return (item->type & 0xFF) == cJSON_Invalid;
2745 }
2746 
2747 CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item)
2748 {
2749  if (item == NULL)
2750  {
2751  return false;
2752  }
2753 
2754  return (item->type & 0xFF) == cJSON_False;
2755 }
2756 
2757 CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item)
2758 {
2759  if (item == NULL)
2760  {
2761  return false;
2762  }
2763 
2764  return (item->type & 0xff) == cJSON_True;
2765 }
2766 
2767 
2768 CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item)
2769 {
2770  if (item == NULL)
2771  {
2772  return false;
2773  }
2774 
2775  return (item->type & (cJSON_True | cJSON_False)) != 0;
2776 }
2777 CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item)
2778 {
2779  if (item == NULL)
2780  {
2781  return false;
2782  }
2783 
2784  return (item->type & 0xFF) == cJSON_NULL;
2785 }
2786 
2787 CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item)
2788 {
2789  if (item == NULL)
2790  {
2791  return false;
2792  }
2793 
2794  return (item->type & 0xFF) == cJSON_Number;
2795 }
2796 
2797 CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item)
2798 {
2799  if (item == NULL)
2800  {
2801  return false;
2802  }
2803 
2804  return (item->type & 0xFF) == cJSON_String;
2805 }
2806 
2807 CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
2808 {
2809  if (item == NULL)
2810  {
2811  return false;
2812  }
2813 
2814  return (item->type & 0xFF) == cJSON_Array;
2815 }
2816 
2817 CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item)
2818 {
2819  if (item == NULL)
2820  {
2821  return false;
2822  }
2823 
2824  return (item->type & 0xFF) == cJSON_Object;
2825 }
2826 
2827 CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
2828 {
2829  if (item == NULL)
2830  {
2831  return false;
2832  }
2833 
2834  return (item->type & 0xFF) == cJSON_Raw;
2835 }
2836 
2837 CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
2838 {
2839  if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
2840  {
2841  return false;
2842  }
2843 
2844  /* check if type is valid */
2845  switch (a->type & 0xFF)
2846  {
2847  case cJSON_False:
2848  case cJSON_True:
2849  case cJSON_NULL:
2850  case cJSON_Number:
2851  case cJSON_String:
2852  case cJSON_Raw:
2853  case cJSON_Array:
2854  case cJSON_Object:
2855  break;
2856 
2857  default:
2858  return false;
2859  }
2860 
2861  /* identical objects are equal */
2862  if (a == b)
2863  {
2864  return true;
2865  }
2866 
2867  switch (a->type & 0xFF)
2868  {
2869  /* in these cases and equal type is enough */
2870  case cJSON_False:
2871  case cJSON_True:
2872  case cJSON_NULL:
2873  return true;
2874 
2875  case cJSON_Number:
2876  if (a->valuedouble == b->valuedouble)
2877  {
2878  return true;
2879  }
2880  return false;
2881 
2882  case cJSON_String:
2883  case cJSON_Raw:
2884  if ((a->valuestring == NULL) || (b->valuestring == NULL))
2885  {
2886  return false;
2887  }
2888  if (strcmp(a->valuestring, b->valuestring) == 0)
2889  {
2890  return true;
2891  }
2892 
2893  return false;
2894 
2895  case cJSON_Array:
2896  {
2897  cJSON *a_element = a->child;
2898  cJSON *b_element = b->child;
2899 
2900  for (; (a_element != NULL) && (b_element != NULL);)
2901  {
2902  if (!cJSON_Compare(a_element, b_element, case_sensitive))
2903  {
2904  return false;
2905  }
2906 
2907  a_element = a_element->next;
2908  b_element = b_element->next;
2909  }
2910 
2911  /* one of the arrays is longer than the other */
2912  if (a_element != b_element) {
2913  return false;
2914  }
2915 
2916  return true;
2917  }
2918 
2919  case cJSON_Object:
2920  {
2921  cJSON *a_element = NULL;
2922  cJSON *b_element = NULL;
2923  cJSON_ArrayForEach(a_element, a)
2924  {
2925  /* TODO This has O(n^2) runtime, which is horrible! */
2926  b_element = get_object_item(b, a_element->string, case_sensitive);
2927  if (b_element == NULL)
2928  {
2929  return false;
2930  }
2931 
2932  if (!cJSON_Compare(a_element, b_element, case_sensitive))
2933  {
2934  return false;
2935  }
2936  }
2937 
2938  /* doing this twice, once on a and b to prevent true comparison if a subset of b
2939  * TODO: Do this the proper way, this is just a fix for now */
2940  cJSON_ArrayForEach(b_element, b)
2941  {
2942  a_element = get_object_item(a, b_element->string, case_sensitive);
2943  if (a_element == NULL)
2944  {
2945  return false;
2946  }
2947 
2948  if (!cJSON_Compare(b_element, a_element, case_sensitive))
2949  {
2950  return false;
2951  }
2952  }
2953 
2954  return true;
2955  }
2956 
2957  default:
2958  return false;
2959  }
2960 }
2961 
2962 CJSON_PUBLIC(void *) cJSON_malloc(size_t size)
2963 {
2964  return global_hooks.allocate(size);
2965 }
2966 
2967 CJSON_PUBLIC(void) cJSON_free(void *object)
2968 {
2969  global_hooks.deallocate(object);
2970 }
const char cJSON_bool require_null_terminated
Definition: switch_cJSON.h:143
cJSON_bool format
Definition: cJSON.c:375
size_t offset
Definition: cJSON.c:372
const char ** return_parse_end
Definition: switch_cJSON.h:143
static unsigned parse_hex4(const unsigned char *const input)
Definition: cJSON.c:547
int cJSON * newitem
Definition: switch_cJSON.h:230
void *CJSON_CDECL * allocate(size_t size)
#define CJSON_NESTING_LIMIT
Definition: switch_cJSON.h:129
void *CJSON_CDECL * reallocate(void *pointer, size_t size)
#define cJSON_Object
Definition: switch_cJSON.h:88
const char *const const double number
Definition: switch_cJSON.h:254
#define CJSON_VERSION_PATCH
Definition: switch_cJSON.h:76
static cJSON_bool parse_value(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1211
#define cJSON_Raw
Definition: switch_cJSON.h:89
internal_hooks hooks
Definition: cJSON.c:261
static void minify_string(char **input, char **output)
Definition: cJSON.c:2667
int cJSON_bool
Definition: switch_cJSON.h:124
#define cjson_min(a, b)
Definition: cJSON.c:1092
const cJSON *const b
Definition: switch_cJSON.h:243
const char *const const char *const raw
Definition: switch_cJSON.h:256
#define cJSON_NULL
Definition: switch_cJSON.h:84
#define fail()
Definition: tone2wav.c:70
static cJSON_bool parse_object(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1496
const char *const const char *const const cJSON *const value
static cJSON * get_object_item(const cJSON *const object, const char *const name, const cJSON_bool case_sensitive)
Definition: cJSON.c:1771
int valueint
Definition: switch_cJSON.h:109
char * valuestring
Definition: switch_cJSON.h:107
static cJSON_bool print_number(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:481
static cJSON_bool print_string_ptr(const unsigned char *const input, printbuffer *const output_buffer)
Definition: cJSON.c:834
static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2)
Definition: cJSON.c:101
char const int const cJSON_bool format
Definition: switch_cJSON.h:153
struct internal_hooks internal_hooks
unsigned char * buffer
Definition: cJSON.c:370
#define cJSON_Invalid
Definition: switch_cJSON.h:81
struct cJSON * prev
Definition: switch_cJSON.h:99
static parse_buffer * skip_utf8_bom(parse_buffer *const buffer)
Definition: cJSON.c:991
internal_hooks hooks
Definition: cJSON.c:376
static cJSON_bool print_array(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1434
#define internal_malloc
Definition: cJSON.c:146
const char * pointer
#define buffer_at_offset(buffer)
Definition: cJSON.c:270
#define cJSON_Array
Definition: switch_cJSON.h:87
int cJSON_bool fmt
Definition: switch_cJSON.h:150
size_t depth
Definition: cJSON.c:373
static unsigned char * cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
Definition: cJSON.c:156
static cJSON_bool parse_number(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:273
#define can_access_at_index(buffer, index)
Definition: cJSON.c:267
int which
Definition: switch_cJSON.h:222
#define CJSON_VERSION_MINOR
Definition: switch_cJSON.h:75
static cJSON_bool add_item_to_array(cJSON *array, cJSON *item)
Definition: cJSON.c:1847
#define cJSON_String
Definition: switch_cJSON.h:86
Definition: cJSON.c:68
switch_byte_t switch_byte_t * buf
size_t length
Definition: cJSON.c:258
static unsigned char get_decimal_point(void)
Definition: cJSON.c:245
struct cJSON * child
Definition: switch_cJSON.h:101
char * string
Definition: switch_cJSON.h:114
size_t length
Definition: cJSON.c:371
#define CJSON_CDECL
Definition: switch_cJSON.h:63
#define cJSON_True
Definition: switch_cJSON.h:83
static cJSON * get_array_item(const cJSON *array, size_t index)
Definition: cJSON.c:1742
const char *const string
Definition: switch_cJSON.h:162
void(CJSON_CDECL *deallocate)(void *pointer)
int index
Definition: switch_cJSON.h:160
static void suffix_object(cJSON *prev, cJSON *item)
Definition: cJSON.c:1819
cJSON_bool noalloc
Definition: cJSON.c:374
cJSON_bool recurse
Definition: switch_cJSON.h:237
#define internal_free
Definition: cJSON.c:147
#define cannot_access_at_index(buffer, index)
Definition: cJSON.c:268
static void skip_oneline_comment(char **input)
Definition: cJSON.c:2640
struct cJSON * next
Definition: switch_cJSON.h:98
static unsigned char * ensure(printbuffer *const p, size_t needed)
Definition: cJSON.c:380
const cJSON *const const cJSON_bool case_sensitive
Definition: switch_cJSON.h:243
char const int length
Definition: switch_cJSON.h:153
static unsigned char * print(const cJSON *const item, cJSON_bool format, const internal_hooks *const hooks)
Definition: cJSON.c:1094
CJSON_PUBLIC(const char *)
Definition: cJSON.c:74
static void skip_multiline_comment(char **input)
Definition: cJSON.c:2653
static error global_error
Definition: cJSON.c:72
static unsigned char utf16_literal_to_utf8(const unsigned char *const input_pointer, const unsigned char *const input_end, unsigned char **output_pointer)
Definition: cJSON.c:584
#define static_strlen(string_literal)
Definition: cJSON.c:152
#define internal_realloc
Definition: cJSON.c:148
static void update_offset(printbuffer *const buffer)
Definition: cJSON.c:468
void *CJSON_CDECL * malloc_fn(size_t sz)
static parse_buffer * buffer_skip_whitespace(parse_buffer *const buffer)
Definition: cJSON.c:970
static cJSON * cJSON_New_Item(const internal_hooks *const hooks)
Definition: cJSON.c:209
static cJSON_bool parse_string(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:705
cJSON *const cJSON * replacement
Definition: switch_cJSON.h:231
static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
Definition: cJSON.c:2226
size_t position
Definition: cJSON.c:70
#define cJSON_StringIsConst
Definition: switch_cJSON.h:92
static void * cast_away_const(const void *string)
Definition: cJSON.c:1889
static cJSON_bool print_object(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1605
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)
Definition: cJSON.c:1898
int prebuffer
Definition: switch_cJSON.h:150
static cJSON_bool print_value(const cJSON *const item, printbuffer *const output_buffer)
Definition: cJSON.c:1266
cJSON * item
Definition: switch_cJSON.h:210
static cJSON_bool print_string(const cJSON *const item, printbuffer *const p)
Definition: cJSON.c:956
#define CJSON_VERSION_MAJOR
Definition: switch_cJSON.h:74
#define can_read(buffer, size)
Definition: cJSON.c:265
static cJSON * create_reference(const cJSON *item, const internal_hooks *const hooks)
Definition: cJSON.c:1826
static cJSON_bool parse_array(cJSON *const item, parse_buffer *const input_buffer)
Definition: cJSON.c:1340
char * buffer
Definition: switch_cJSON.h:153
const unsigned char * json
Definition: cJSON.c:69
int type
Definition: switch_cJSON.h:104
int count
Definition: switch_cJSON.h:204
const char *const name
Definition: switch_cJSON.h:250
size_t offset
Definition: cJSON.c:259
const unsigned char * content
Definition: cJSON.c:257
static internal_hooks global_hooks
Definition: cJSON.c:154
#define cJSON_ArrayForEach(element, array)
Definition: switch_cJSON.h:267
size_t depth
Definition: cJSON.c:260
double valuedouble
Definition: switch_cJSON.h:111
memset(buf, 0, buflen)
#define cJSON_False
Definition: switch_cJSON.h:82
#define cJSON_Number
Definition: switch_cJSON.h:85
#define cJSON_IsReference
Definition: switch_cJSON.h:91