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