1/*
2  Copyright (c) 2009 Dave Gamble
3  Copyright (c) 2015-2016 The Khronos Group Inc.
4  Copyright (c) 2015-2016 Valve Corporation
5  Copyright (c) 2015-2016 LunarG, Inc.
6
7  Permission is hereby granted, free of charge, to any person obtaining a copy
8  of this software and associated documentation files (the "Software"), to deal
9  in the Software without restriction, including without limitation the rights
10  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  copies of the Software, and to permit persons to whom the Software is
12  furnished to do so, subject to the following conditions:
13
14  The above copyright notice and this permission notice shall be included in
15  all copies or substantial portions of the Software.
16
17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  THE SOFTWARE.
24*/
25
26/* cJSON */
27/* JSON parser in C. */
28
29#include <string.h>
30#include <stdio.h>
31#include <math.h>
32#include <stdlib.h>
33#include <float.h>
34#include <limits.h>
35#include <ctype.h>
36#include "cJSON.h"
37
38static const char *ep;
39
40const char *cJSON_GetErrorPtr(void) { return ep; }
41
42static void *(*cJSON_malloc)(size_t sz) = malloc;
43static void (*cJSON_free)(void *ptr) = free;
44
45static char *cJSON_strdup(const char *str) {
46    size_t len;
47    char *copy;
48
49    len = strlen(str) + 1;
50    if (!(copy = (char *)cJSON_malloc(len)))
51        return 0;
52    memcpy(copy, str, len);
53    return copy;
54}
55
56void cJSON_InitHooks(cJSON_Hooks *hooks) {
57    if (!hooks) { /* Reset hooks */
58        cJSON_malloc = malloc;
59        cJSON_free = free;
60        return;
61    }
62
63    cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc;
64    cJSON_free = (hooks->free_fn) ? hooks->free_fn : free;
65}
66
67/* Internal constructor. */
68static cJSON *cJSON_New_Item(void) {
69    cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON));
70    if (node)
71        memset(node, 0, sizeof(cJSON));
72    return node;
73}
74
75/* Delete a cJSON structure. */
76void cJSON_Delete(cJSON *c) {
77    cJSON *next;
78    while (c) {
79        next = c->next;
80        if (!(c->type & cJSON_IsReference) && c->child)
81            cJSON_Delete(c->child);
82        if (!(c->type & cJSON_IsReference) && c->valuestring)
83            cJSON_free(c->valuestring);
84        if (!(c->type & cJSON_StringIsConst) && c->string)
85            cJSON_free(c->string);
86        cJSON_free(c);
87        c = next;
88    }
89}
90
91void cJSON_Free(void *p) {
92    cJSON_free(p);
93}
94
95/* Parse the input text to generate a number, and populate the result into item.
96 */
97static const char *parse_number(cJSON *item, const char *num) {
98    double n = 0, sign = 1, scale = 0;
99    int subscale = 0, signsubscale = 1;
100
101    if (*num == '-')
102        sign = -1, num++; /* Has sign? */
103    if (*num == '0')
104        num++; /* is zero */
105    if (*num >= '1' && *num <= '9')
106        do
107            n = (n * 10.0) + (*num++ - '0');
108        while (*num >= '0' && *num <= '9'); /* Number? */
109    if (*num == '.' && num[1] >= '0' && num[1] <= '9') {
110        num++;
111        do
112            n = (n * 10.0) + (*num++ - '0'), scale--;
113        while (*num >= '0' && *num <= '9');
114    }                               /* Fractional part? */
115    if (*num == 'e' || *num == 'E') /* Exponent? */
116    {
117        num++;
118        if (*num == '+')
119            num++;
120        else if (*num == '-')
121            signsubscale = -1, num++; /* With sign? */
122        while (*num >= '0' && *num <= '9')
123            subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
124    }
125
126    n = sign * n *
127        pow(10.0, (scale + subscale * signsubscale)); /* number = +/-
128                                                         number.fraction *
129                                                         10^+/- exponent */
130
131    item->valuedouble = n;
132    item->valueint = (int)n;
133    item->type = cJSON_Number;
134    return num;
135}
136
137static size_t pow2gt(size_t x) {
138    --x;
139    x |= x >> 1;
140    x |= x >> 2;
141    x |= x >> 4;
142    x |= x >> 8;
143    x |= x >> 16;
144    return x + 1;
145}
146
147typedef struct {
148    char *buffer;
149    size_t length;
150    size_t offset;
151} printbuffer;
152
153static char *ensure(printbuffer *p, size_t needed) {
154    char *newbuffer;
155    size_t newsize;
156    if (!p || !p->buffer)
157        return 0;
158    needed += p->offset;
159    if (needed <= p->length)
160        return p->buffer + p->offset;
161
162    newsize = pow2gt(needed);
163    newbuffer = (char *)cJSON_malloc(newsize);
164    if (!newbuffer) {
165        cJSON_free(p->buffer);
166        p->length = 0, p->buffer = 0;
167        return 0;
168    }
169    if (newbuffer)
170        memcpy(newbuffer, p->buffer, p->length);
171    cJSON_free(p->buffer);
172    p->length = newsize;
173    p->buffer = newbuffer;
174    return newbuffer + p->offset;
175}
176
177static size_t update(printbuffer *p) {
178    char *str;
179    if (!p || !p->buffer)
180        return 0;
181    str = p->buffer + p->offset;
182    return p->offset + strlen(str);
183}
184
185/* Render the number nicely from the given item into a string. */
186static char *print_number(cJSON *item, printbuffer *p) {
187    char *str = 0;
188    double d = item->valuedouble;
189    if (d == 0) {
190        if (p)
191            str = ensure(p, 2);
192        else
193            str = (char *)cJSON_malloc(2); /* special case for 0. */
194        if (str)
195            strcpy(str, "0");
196    } else if (fabs(((double)item->valueint) - d) <= DBL_EPSILON &&
197               d <= INT_MAX && d >= INT_MIN) {
198        if (p)
199            str = ensure(p, 21);
200        else
201            str = (char *)cJSON_malloc(
202                21); /* 2^64+1 can be represented in 21 chars. */
203        if (str)
204            sprintf(str, "%d", item->valueint);
205    } else {
206        if (p)
207            str = ensure(p, 64);
208        else
209            str = (char *)cJSON_malloc(64); /* This is a nice tradeoff. */
210        if (str) {
211            if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)
212                sprintf(str, "%.0f", d);
213            else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9)
214                sprintf(str, "%e", d);
215            else
216                sprintf(str, "%f", d);
217        }
218    }
219    return str;
220}
221
222static unsigned parse_hex4(const char *str) {
223    unsigned h = 0;
224    if (*str >= '0' && *str <= '9')
225        h += (*str) - '0';
226    else if (*str >= 'A' && *str <= 'F')
227        h += 10 + (*str) - 'A';
228    else if (*str >= 'a' && *str <= 'f')
229        h += 10 + (*str) - 'a';
230    else
231        return 0;
232    h = h << 4;
233    str++;
234    if (*str >= '0' && *str <= '9')
235        h += (*str) - '0';
236    else if (*str >= 'A' && *str <= 'F')
237        h += 10 + (*str) - 'A';
238    else if (*str >= 'a' && *str <= 'f')
239        h += 10 + (*str) - 'a';
240    else
241        return 0;
242    h = h << 4;
243    str++;
244    if (*str >= '0' && *str <= '9')
245        h += (*str) - '0';
246    else if (*str >= 'A' && *str <= 'F')
247        h += 10 + (*str) - 'A';
248    else if (*str >= 'a' && *str <= 'f')
249        h += 10 + (*str) - 'a';
250    else
251        return 0;
252    h = h << 4;
253    str++;
254    if (*str >= '0' && *str <= '9')
255        h += (*str) - '0';
256    else if (*str >= 'A' && *str <= 'F')
257        h += 10 + (*str) - 'A';
258    else if (*str >= 'a' && *str <= 'f')
259        h += 10 + (*str) - 'a';
260    else
261        return 0;
262    return h;
263}
264
265/* Parse the input text into an unescaped cstring, and populate item. */
266static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0,
267                                               0xF0, 0xF8, 0xFC};
268static const char *parse_string(cJSON *item, const char *str) {
269    const char *ptr = str + 1;
270    char *ptr2;
271    char *out;
272    int len = 0;
273    unsigned uc, uc2;
274    if (*str != '\"') {
275        ep = str;
276        return 0;
277    } /* not a string! */
278
279    while (*ptr != '\"' && *ptr && ++len)
280        if (*ptr++ == '\\')
281            ptr++; /* Skip escaped quotes. */
282
283    out = (char *)cJSON_malloc(
284        len + 1); /* This is how long we need for the string, roughly. */
285    if (!out)
286        return 0;
287
288    ptr = str + 1;
289    ptr2 = out;
290    while (*ptr != '\"' && *ptr) {
291        if (*ptr != '\\')
292            *ptr2++ = *ptr++;
293        else {
294            ptr++;
295            switch (*ptr) {
296            case 'b':
297                *ptr2++ = '\b';
298                break;
299            case 'f':
300                *ptr2++ = '\f';
301                break;
302            case 'n':
303                *ptr2++ = '\n';
304                break;
305            case 'r':
306                *ptr2++ = '\r';
307                break;
308            case 't':
309                *ptr2++ = '\t';
310                break;
311            case 'u': /* transcode utf16 to utf8. */
312                uc = parse_hex4(ptr + 1);
313                ptr += 4; /* get the unicode char. */
314
315                if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0)
316                    break; /* check for invalid.	*/
317
318                if (uc >= 0xD800 &&
319                    uc <= 0xDBFF) /* UTF16 surrogate pairs.	*/
320                {
321                    if (ptr[1] != '\\' || ptr[2] != 'u')
322                        break; /* missing second-half of surrogate.	*/
323                    uc2 = parse_hex4(ptr + 3);
324                    ptr += 6;
325                    if (uc2 < 0xDC00 || uc2 > 0xDFFF)
326                        break; /* invalid second-half of surrogate.	*/
327                    uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
328                }
329
330                len = 4;
331                if (uc < 0x80)
332                    len = 1;
333                else if (uc < 0x800)
334                    len = 2;
335                else if (uc < 0x10000)
336                    len = 3;
337                ptr2 += len;
338
339                switch (len) {
340                case 4:
341                    *--ptr2 = ((uc | 0x80) & 0xBF);
342                    uc >>= 6;
343                case 3:
344                    *--ptr2 = ((uc | 0x80) & 0xBF);
345                    uc >>= 6;
346                case 2:
347                    *--ptr2 = ((uc | 0x80) & 0xBF);
348                    uc >>= 6;
349                case 1:
350                    *--ptr2 = ((unsigned char)uc | firstByteMark[len]);
351                }
352                ptr2 += len;
353                break;
354            default:
355                *ptr2++ = *ptr;
356                break;
357            }
358            ptr++;
359        }
360    }
361    *ptr2 = 0;
362    if (*ptr == '\"')
363        ptr++;
364    item->valuestring = out;
365    item->type = cJSON_String;
366    return ptr;
367}
368
369/* Render the cstring provided to an escaped version that can be printed. */
370static char *print_string_ptr(const char *str, printbuffer *p) {
371    const char *ptr;
372    char *ptr2;
373    char *out;
374    size_t len = 0, flag = 0;
375    unsigned char token;
376
377    for (ptr = str; *ptr; ptr++)
378        flag |= ((*ptr > 0 && *ptr < 32) || (*ptr == '\"') || (*ptr == '\\'))
379                    ? 1
380                    : 0;
381    if (!flag) {
382        len = ptr - str;
383        if (p)
384            out = ensure(p, len + 3);
385        else
386            out = (char *)cJSON_malloc(len + 3);
387        if (!out)
388            return 0;
389        ptr2 = out;
390        *ptr2++ = '\"';
391        strcpy(ptr2, str);
392        ptr2[len] = '\"';
393        ptr2[len + 1] = 0;
394        return out;
395    }
396
397    if (!str) {
398        if (p)
399            out = ensure(p, 3);
400        else
401            out = (char *)cJSON_malloc(3);
402        if (!out)
403            return 0;
404        strcpy(out, "\"\"");
405        return out;
406    }
407    ptr = str;
408    while ((token = *ptr) && ++len) {
409        if (strchr("\"\\\b\f\n\r\t", token))
410            len++;
411        else if (token < 32)
412            len += 5;
413        ptr++;
414    }
415
416    if (p)
417        out = ensure(p, len + 3);
418    else
419        out = (char *)cJSON_malloc(len + 3);
420    if (!out)
421        return 0;
422
423    ptr2 = out;
424    ptr = str;
425    *ptr2++ = '\"';
426    while (*ptr) {
427        if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\')
428            *ptr2++ = *ptr++;
429        else {
430            switch (token = *ptr++) {
431            case '\\':
432                *ptr2++ = '\\';
433                break;
434            case '\"':
435                *ptr2++ = '\"';
436                break;
437            case '\b':
438                *ptr2++ = '\b';
439                break;
440            case '\f':
441                *ptr2++ = '\f';
442                break;
443            case '\n':
444                *ptr2++ = '\n';
445                break;
446            case '\r':
447                *ptr2++ = '\r';
448                break;
449            case '\t':
450                *ptr2++ = '\t';
451                break;
452            default:
453                sprintf(ptr2, "u%04x", token);
454                ptr2 += 5;
455                break; /* escape and print */
456            }
457        }
458    }
459    *ptr2++ = '\"';
460    *ptr2++ = 0;
461    return out;
462}
463/* Invote print_string_ptr (which is useful) on an item. */
464static char *print_string(cJSON *item, printbuffer *p) {
465    return print_string_ptr(item->valuestring, p);
466}
467
468/* Predeclare these prototypes. */
469static const char *parse_value(cJSON *item, const char *value);
470static char *print_value(cJSON *item, int depth, int fmt, printbuffer *p);
471static const char *parse_array(cJSON *item, const char *value);
472static char *print_array(cJSON *item, int depth, int fmt, printbuffer *p);
473static const char *parse_object(cJSON *item, const char *value);
474static char *print_object(cJSON *item, int depth, int fmt, printbuffer *p);
475
476/* Utility to jump whitespace and cr/lf */
477static const char *skip(const char *in) {
478    while (in && *in && (unsigned char)*in <= 32)
479        in++;
480    return in;
481}
482
483/* Parse an object - create a new root, and populate. */
484cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
485                           int require_null_terminated) {
486    const char *end = 0;
487    cJSON *c = cJSON_New_Item();
488    ep = 0;
489    if (!c)
490        return 0; /* memory fail */
491
492    end = parse_value(c, skip(value));
493    if (!end) {
494        cJSON_Delete(c);
495        return 0;
496    } /* parse failure. ep is set. */
497
498    /* if we require null-terminated JSON without appended garbage, skip and
499     * then check for a null terminator */
500    if (require_null_terminated) {
501        end = skip(end);
502        if (*end) {
503            cJSON_Delete(c);
504            ep = end;
505            return 0;
506        }
507    }
508    if (return_parse_end)
509        *return_parse_end = end;
510    return c;
511}
512/* Default options for cJSON_Parse */
513cJSON *cJSON_Parse(const char *value) {
514    return cJSON_ParseWithOpts(value, 0, 0);
515}
516
517/* Render a cJSON item/entity/structure to text. */
518char *cJSON_Print(cJSON *item) { return print_value(item, 0, 1, 0); }
519char *cJSON_PrintUnformatted(cJSON *item) { return print_value(item, 0, 0, 0); }
520
521char *cJSON_PrintBuffered(cJSON *item, int prebuffer, int fmt) {
522    printbuffer p;
523    p.buffer = (char *)cJSON_malloc(prebuffer);
524    p.length = prebuffer;
525    p.offset = 0;
526    return print_value(item, 0, fmt, &p);
527}
528
529/* Parser core - when encountering text, process appropriately. */
530static const char *parse_value(cJSON *item, const char *value) {
531    if (!value)
532        return 0; /* Fail on null. */
533    if (!strncmp(value, "null", 4)) {
534        item->type = cJSON_NULL;
535        return value + 4;
536    }
537    if (!strncmp(value, "false", 5)) {
538        item->type = cJSON_False;
539        return value + 5;
540    }
541    if (!strncmp(value, "true", 4)) {
542        item->type = cJSON_True;
543        item->valueint = 1;
544        return value + 4;
545    }
546    if (*value == '\"') {
547        return parse_string(item, value);
548    }
549    if (*value == '-' || (*value >= '0' && *value <= '9')) {
550        return parse_number(item, value);
551    }
552    if (*value == '[') {
553        return parse_array(item, value);
554    }
555    if (*value == '{') {
556        return parse_object(item, value);
557    }
558
559    ep = value;
560    return 0; /* failure. */
561}
562
563/* Render a value to text. */
564static char *print_value(cJSON *item, int depth, int fmt, printbuffer *p) {
565    char *out = 0;
566    if (!item)
567        return 0;
568    if (p) {
569        switch ((item->type) & 255) {
570        case cJSON_NULL: {
571            out = ensure(p, 5);
572            if (out)
573                strcpy(out, "null");
574            break;
575        }
576        case cJSON_False: {
577            out = ensure(p, 6);
578            if (out)
579                strcpy(out, "false");
580            break;
581        }
582        case cJSON_True: {
583            out = ensure(p, 5);
584            if (out)
585                strcpy(out, "true");
586            break;
587        }
588        case cJSON_Number:
589            out = print_number(item, p);
590            break;
591        case cJSON_String:
592            out = print_string(item, p);
593            break;
594        case cJSON_Array:
595            out = print_array(item, depth, fmt, p);
596            break;
597        case cJSON_Object:
598            out = print_object(item, depth, fmt, p);
599            break;
600        }
601    } else {
602        switch ((item->type) & 255) {
603        case cJSON_NULL:
604            out = cJSON_strdup("null");
605            break;
606        case cJSON_False:
607            out = cJSON_strdup("false");
608            break;
609        case cJSON_True:
610            out = cJSON_strdup("true");
611            break;
612        case cJSON_Number:
613            out = print_number(item, 0);
614            break;
615        case cJSON_String:
616            out = print_string(item, 0);
617            break;
618        case cJSON_Array:
619            out = print_array(item, depth, fmt, 0);
620            break;
621        case cJSON_Object:
622            out = print_object(item, depth, fmt, 0);
623            break;
624        }
625    }
626    return out;
627}
628
629/* Build an array from input text. */
630static const char *parse_array(cJSON *item, const char *value) {
631    cJSON *child;
632    if (*value != '[') {
633        ep = value;
634        return 0;
635    } /* not an array! */
636
637    item->type = cJSON_Array;
638    value = skip(value + 1);
639    if (*value == ']')
640        return value + 1; /* empty array. */
641
642    item->child = child = cJSON_New_Item();
643    if (!item->child)
644        return 0; /* memory fail */
645    value = skip(
646        parse_value(child, skip(value))); /* skip any spacing, get the value. */
647    if (!value)
648        return 0;
649
650    while (*value == ',') {
651        cJSON *new_item;
652        if (!(new_item = cJSON_New_Item()))
653            return 0; /* memory fail */
654        child->next = new_item;
655        new_item->prev = child;
656        child = new_item;
657        value = skip(parse_value(child, skip(value + 1)));
658        if (!value)
659            return 0; /* memory fail */
660    }
661
662    if (*value == ']')
663        return value + 1; /* end of array */
664    ep = value;
665    return 0; /* malformed. */
666}
667
668/* Render an array to text */
669static char *print_array(cJSON *item, int depth, int fmt, printbuffer *p) {
670    char **entries;
671    char *out = 0, *ptr, *ret;
672    size_t len = 5;
673    cJSON *child = item->child;
674    int numentries = 0, fail = 0, j = 0;
675    size_t tmplen = 0, i = 0;
676
677    /* How many entries in the array? */
678    while (child)
679        numentries++, child = child->next;
680    /* Explicitly handle numentries==0 */
681    if (!numentries) {
682        if (p)
683            out = ensure(p, 3);
684        else
685            out = (char *)cJSON_malloc(3);
686        if (out)
687            strcpy(out, "[]");
688        return out;
689    }
690
691    if (p) {
692        /* Compose the output array. */
693        i = p->offset;
694        ptr = ensure(p, 1);
695        if (!ptr)
696            return 0;
697        *ptr = '[';
698        p->offset++;
699        child = item->child;
700        while (child && !fail) {
701            print_value(child, depth + 1, fmt, p);
702            p->offset = update(p);
703            if (child->next) {
704                len = fmt ? 2 : 1;
705                ptr = ensure(p, len + 1);
706                if (!ptr)
707                    return 0;
708                *ptr++ = ',';
709                if (fmt)
710                    *ptr++ = ' ';
711                *ptr = 0;
712                p->offset += len;
713            }
714            child = child->next;
715        }
716        ptr = ensure(p, 2);
717        if (!ptr)
718            return 0;
719        *ptr++ = ']';
720        *ptr = 0;
721        out = (p->buffer) + i;
722    } else {
723        /* Allocate an array to hold the values for each */
724        entries = (char **)cJSON_malloc(numentries * sizeof(char *));
725        if (!entries)
726            return 0;
727        memset(entries, 0, numentries * sizeof(char *));
728        /* Retrieve all the results: */
729        child = item->child;
730        while (child && !fail) {
731            ret = print_value(child, depth + 1, fmt, 0);
732            entries[i++] = ret;
733            if (ret)
734                len += strlen(ret) + 2 + (fmt ? 1 : 0);
735            else
736                fail = 1;
737            child = child->next;
738        }
739
740        /* If we didn't fail, try to malloc the output string */
741        if (!fail)
742            out = (char *)cJSON_malloc(len);
743        /* If that fails, we fail. */
744        if (!out)
745            fail = 1;
746
747        /* Handle failure. */
748        if (fail) {
749            for (j = 0; j < numentries; j++)
750                if (entries[j])
751                    cJSON_free(entries[j]);
752            cJSON_free(entries);
753            return 0;
754        }
755
756        /* Compose the output array. */
757        *out = '[';
758        ptr = out + 1;
759        *ptr = 0;
760        for (j = 0; j < numentries; j++) {
761            tmplen = strlen(entries[j]);
762            memcpy(ptr, entries[j], tmplen);
763            ptr += tmplen;
764            if (j != numentries - 1) {
765                *ptr++ = ',';
766                if (fmt)
767                    *ptr++ = ' ';
768                *ptr = 0;
769            }
770            cJSON_free(entries[j]);
771        }
772        cJSON_free(entries);
773        *ptr++ = ']';
774        *ptr++ = 0;
775    }
776    return out;
777}
778
779/* Build an object from the text. */
780static const char *parse_object(cJSON *item, const char *value) {
781    cJSON *child;
782    if (*value != '{') {
783        ep = value;
784        return 0;
785    } /* not an object! */
786
787    item->type = cJSON_Object;
788    value = skip(value + 1);
789    if (*value == '}')
790        return value + 1; /* empty array. */
791
792    item->child = child = cJSON_New_Item();
793    if (!item->child)
794        return 0;
795    value = skip(parse_string(child, skip(value)));
796    if (!value)
797        return 0;
798    child->string = child->valuestring;
799    child->valuestring = 0;
800    if (*value != ':') {
801        ep = value;
802        return 0;
803    } /* fail! */
804    value = skip(parse_value(
805        child, skip(value + 1))); /* skip any spacing, get the value. */
806    if (!value)
807        return 0;
808
809    while (*value == ',') {
810        cJSON *new_item;
811        if (!(new_item = cJSON_New_Item()))
812            return 0; /* memory fail */
813        child->next = new_item;
814        new_item->prev = child;
815        child = new_item;
816        value = skip(parse_string(child, skip(value + 1)));
817        if (!value)
818            return 0;
819        child->string = child->valuestring;
820        child->valuestring = 0;
821        if (*value != ':') {
822            ep = value;
823            return 0;
824        } /* fail! */
825        value = skip(parse_value(
826            child, skip(value + 1))); /* skip any spacing, get the value. */
827        if (!value)
828            return 0;
829    }
830
831    if (*value == '}')
832        return value + 1; /* end of array */
833    ep = value;
834    return 0; /* malformed. */
835}
836
837/* Render an object to text. */
838static char *print_object(cJSON *item, int depth, int fmt, printbuffer *p) {
839    char **entries = 0, **names = 0;
840    char *out = 0, *ptr, *ret, *str;
841    int j;
842    cJSON *child = item->child;
843    int numentries = 0, fail = 0, k;
844    size_t tmplen = 0, i = 0, len = 7;
845    /* Count the number of entries. */
846    while (child)
847        numentries++, child = child->next;
848    /* Explicitly handle empty object case */
849    if (!numentries) {
850        if (p)
851            out = ensure(p, fmt ? depth + 4 : 3);
852        else
853            out = (char *)cJSON_malloc(fmt ? depth + 4 : 3);
854        if (!out)
855            return 0;
856        ptr = out;
857        *ptr++ = '{';
858        if (fmt) {
859            *ptr++ = '\n';
860            for (j = 0; j < depth - 1; j++)
861                *ptr++ = '\t';
862        }
863        *ptr++ = '}';
864        *ptr++ = 0;
865        return out;
866    }
867    if (p) {
868        /* Compose the output: */
869        i = p->offset;
870        len = fmt ? 2 : 1;
871        ptr = ensure(p, len + 1);
872        if (!ptr)
873            return 0;
874        *ptr++ = '{';
875        if (fmt)
876            *ptr++ = '\n';
877        *ptr = 0;
878        p->offset += len;
879        child = item->child;
880        depth++;
881        while (child) {
882            if (fmt) {
883                ptr = ensure(p, depth);
884                if (!ptr)
885                    return 0;
886                for (j = 0; j < depth; j++)
887                    *ptr++ = '\t';
888                p->offset += depth;
889            }
890            print_string_ptr(child->string, p);
891            p->offset = update(p);
892
893            len = fmt ? 2 : 1;
894            ptr = ensure(p, len);
895            if (!ptr)
896                return 0;
897            *ptr++ = ':';
898            if (fmt)
899                *ptr++ = '\t';
900            p->offset += len;
901
902            print_value(child, depth, fmt, p);
903            p->offset = update(p);
904
905            len = (fmt ? 1 : 0) + (child->next ? 1 : 0);
906            ptr = ensure(p, len + 1);
907            if (!ptr)
908                return 0;
909            if (child->next)
910                *ptr++ = ',';
911            if (fmt)
912                *ptr++ = '\n';
913            *ptr = 0;
914            p->offset += len;
915            child = child->next;
916        }
917        ptr = ensure(p, fmt ? (depth + 1) : 2);
918        if (!ptr)
919            return 0;
920        if (fmt)
921            for (j = 0; j < depth - 1; j++)
922                *ptr++ = '\t';
923        *ptr++ = '}';
924        *ptr = 0;
925        out = (p->buffer) + i;
926    } else {
927        /* Allocate space for the names and the objects */
928        entries = (char **)cJSON_malloc(numentries * sizeof(char *));
929        if (!entries)
930            return 0;
931        names = (char **)cJSON_malloc(numentries * sizeof(char *));
932        if (!names) {
933            cJSON_free(entries);
934            return 0;
935        }
936        memset(entries, 0, sizeof(char *) * numentries);
937        memset(names, 0, sizeof(char *) * numentries);
938
939        /* Collect all the results into our arrays: */
940        child = item->child;
941        depth++;
942        if (fmt)
943            len += depth;
944        while (child) {
945            names[i] = str = print_string_ptr(child->string, 0);
946            entries[i++] = ret = print_value(child, depth, fmt, 0);
947            if (str && ret)
948                len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0);
949            else
950                fail = 1;
951            child = child->next;
952        }
953
954        /* Try to allocate the output string */
955        if (!fail)
956            out = (char *)cJSON_malloc(len);
957        if (!out)
958            fail = 1;
959
960        /* Handle failure */
961        if (fail) {
962            for (j = 0; j < numentries; j++) {
963                if (names[i])
964                    cJSON_free(names[j]);
965                if (entries[j])
966                    cJSON_free(entries[j]);
967            }
968            cJSON_free(names);
969            cJSON_free(entries);
970            return 0;
971        }
972
973        /* Compose the output: */
974        *out = '{';
975        ptr = out + 1;
976        if (fmt)
977            *ptr++ = '\n';
978        *ptr = 0;
979        for (j = 0; j < numentries; j++) {
980            if (fmt)
981                for (k = 0; k < depth; k++)
982                    *ptr++ = '\t';
983            tmplen = strlen(names[j]);
984            memcpy(ptr, names[j], tmplen);
985            ptr += tmplen;
986            *ptr++ = ':';
987            if (fmt)
988                *ptr++ = '\t';
989            strcpy(ptr, entries[j]);
990            ptr += strlen(entries[j]);
991            if (j != numentries - 1)
992                *ptr++ = ',';
993            if (fmt)
994                *ptr++ = '\n';
995            *ptr = 0;
996            cJSON_free(names[j]);
997            cJSON_free(entries[j]);
998        }
999
1000        cJSON_free(names);
1001        cJSON_free(entries);
1002        if (fmt)
1003            for (j = 0; j < depth - 1; j++)
1004                *ptr++ = '\t';
1005        *ptr++ = '}';
1006        *ptr++ = 0;
1007    }
1008    return out;
1009}
1010
1011/* Get Array size/item / object item. */
1012int cJSON_GetArraySize(cJSON *array) {
1013    cJSON *c = array->child;
1014    int i = 0;
1015    while (c)
1016        i++, c = c->next;
1017    return i;
1018}
1019cJSON *cJSON_GetArrayItem(cJSON *array, int item) {
1020    cJSON *c = array->child;
1021    while (c && item > 0)
1022        item--, c = c->next;
1023    return c;
1024}
1025cJSON *cJSON_GetObjectItem(cJSON *object, const char *string) {
1026    cJSON *c = object->child;
1027    while (c && strcmp(c->string, string))
1028        c = c->next;
1029    return c;
1030}
1031
1032/* Utility for array list handling. */
1033static void suffix_object(cJSON *prev, cJSON *item) {
1034    prev->next = item;
1035    item->prev = prev;
1036}
1037/* Utility for handling references. */
1038static cJSON *create_reference(cJSON *item) {
1039    cJSON *ref = cJSON_New_Item();
1040    if (!ref)
1041        return 0;
1042    memcpy(ref, item, sizeof(cJSON));
1043    ref->string = 0;
1044    ref->type |= cJSON_IsReference;
1045    ref->next = ref->prev = 0;
1046    return ref;
1047}
1048
1049/* Add item to array/object. */
1050void cJSON_AddItemToArray(cJSON *array, cJSON *item) {
1051    cJSON *c = array->child;
1052    if (!item)
1053        return;
1054    if (!c) {
1055        array->child = item;
1056    } else {
1057        while (c && c->next)
1058            c = c->next;
1059        suffix_object(c, item);
1060    }
1061}
1062void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) {
1063    if (!item)
1064        return;
1065    if (item->string)
1066        cJSON_free(item->string);
1067    item->string = cJSON_strdup(string);
1068    cJSON_AddItemToArray(object, item);
1069}
1070void cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) {
1071    if (!item)
1072        return;
1073    if (!(item->type & cJSON_StringIsConst) && item->string)
1074        cJSON_free(item->string);
1075    item->string = (char *)string;
1076    item->type |= cJSON_StringIsConst;
1077    cJSON_AddItemToArray(object, item);
1078}
1079void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {
1080    cJSON_AddItemToArray(array, create_reference(item));
1081}
1082void cJSON_AddItemReferenceToObject(cJSON *object, const char *string,
1083                                    cJSON *item) {
1084    cJSON_AddItemToObject(object, string, create_reference(item));
1085}
1086
1087cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) {
1088    cJSON *c = array->child;
1089    while (c && which > 0)
1090        c = c->next, which--;
1091    if (!c)
1092        return 0;
1093    if (c->prev)
1094        c->prev->next = c->next;
1095    if (c->next)
1096        c->next->prev = c->prev;
1097    if (c == array->child)
1098        array->child = c->next;
1099    c->prev = c->next = 0;
1100    return c;
1101}
1102void cJSON_DeleteItemFromArray(cJSON *array, int which) {
1103    cJSON_Delete(cJSON_DetachItemFromArray(array, which));
1104}
1105cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) {
1106    int i = 0;
1107    cJSON *c = object->child;
1108    while (c && strcmp(c->string, string))
1109        i++, c = c->next;
1110    if (c)
1111        return cJSON_DetachItemFromArray(object, i);
1112    return 0;
1113}
1114void cJSON_DeleteItemFromObject(cJSON *object, const char *string) {
1115    cJSON_Delete(cJSON_DetachItemFromObject(object, string));
1116}
1117
1118/* Replace array/object items with new ones. */
1119void cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) {
1120    cJSON *c = array->child;
1121    while (c && which > 0)
1122        c = c->next, which--;
1123    if (!c) {
1124        cJSON_AddItemToArray(array, newitem);
1125        return;
1126    }
1127    newitem->next = c;
1128    newitem->prev = c->prev;
1129    c->prev = newitem;
1130    if (c == array->child)
1131        array->child = newitem;
1132    else
1133        newitem->prev->next = newitem;
1134}
1135void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) {
1136    cJSON *c = array->child;
1137    while (c && which > 0)
1138        c = c->next, which--;
1139    if (!c)
1140        return;
1141    newitem->next = c->next;
1142    newitem->prev = c->prev;
1143    if (newitem->next)
1144        newitem->next->prev = newitem;
1145    if (c == array->child)
1146        array->child = newitem;
1147    else
1148        newitem->prev->next = newitem;
1149    c->next = c->prev = 0;
1150    cJSON_Delete(c);
1151}
1152void cJSON_ReplaceItemInObject(cJSON *object, const char *string,
1153                               cJSON *newitem) {
1154    int i = 0;
1155    cJSON *c = object->child;
1156    while (c && strcmp(c->string, string))
1157        i++, c = c->next;
1158    if (c) {
1159        newitem->string = cJSON_strdup(string);
1160        cJSON_ReplaceItemInArray(object, i, newitem);
1161    }
1162}
1163
1164/* Create basic types: */
1165cJSON *cJSON_CreateNull(void) {
1166    cJSON *item = cJSON_New_Item();
1167    if (item)
1168        item->type = cJSON_NULL;
1169    return item;
1170}
1171cJSON *cJSON_CreateTrue(void) {
1172    cJSON *item = cJSON_New_Item();
1173    if (item)
1174        item->type = cJSON_True;
1175    return item;
1176}
1177cJSON *cJSON_CreateFalse(void) {
1178    cJSON *item = cJSON_New_Item();
1179    if (item)
1180        item->type = cJSON_False;
1181    return item;
1182}
1183cJSON *cJSON_CreateBool(int b) {
1184    cJSON *item = cJSON_New_Item();
1185    if (item)
1186        item->type = b ? cJSON_True : cJSON_False;
1187    return item;
1188}
1189cJSON *cJSON_CreateNumber(double num) {
1190    cJSON *item = cJSON_New_Item();
1191    if (item) {
1192        item->type = cJSON_Number;
1193        item->valuedouble = num;
1194        item->valueint = (int)num;
1195    }
1196    return item;
1197}
1198cJSON *cJSON_CreateString(const char *string) {
1199    cJSON *item = cJSON_New_Item();
1200    if (item) {
1201        item->type = cJSON_String;
1202        item->valuestring = cJSON_strdup(string);
1203    }
1204    return item;
1205}
1206cJSON *cJSON_CreateArray(void) {
1207    cJSON *item = cJSON_New_Item();
1208    if (item)
1209        item->type = cJSON_Array;
1210    return item;
1211}
1212cJSON *cJSON_CreateObject(void) {
1213    cJSON *item = cJSON_New_Item();
1214    if (item)
1215        item->type = cJSON_Object;
1216    return item;
1217}
1218
1219/* Create Arrays: */
1220cJSON *cJSON_CreateIntArray(const int *numbers, int count) {
1221    int i;
1222    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
1223    for (i = 0; a && i < count; i++) {
1224        n = cJSON_CreateNumber(numbers[i]);
1225        if (!i)
1226            a->child = n;
1227        else
1228            suffix_object(p, n);
1229        p = n;
1230    }
1231    return a;
1232}
1233cJSON *cJSON_CreateFloatArray(const float *numbers, int count) {
1234    int i;
1235    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
1236    for (i = 0; a && i < count; i++) {
1237        n = cJSON_CreateNumber(numbers[i]);
1238        if (!i)
1239            a->child = n;
1240        else
1241            suffix_object(p, n);
1242        p = n;
1243    }
1244    return a;
1245}
1246cJSON *cJSON_CreateDoubleArray(const double *numbers, int count) {
1247    int i;
1248    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
1249    for (i = 0; a && i < count; i++) {
1250        n = cJSON_CreateNumber(numbers[i]);
1251        if (!i)
1252            a->child = n;
1253        else
1254            suffix_object(p, n);
1255        p = n;
1256    }
1257    return a;
1258}
1259cJSON *cJSON_CreateStringArray(const char **strings, int count) {
1260    int i;
1261    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
1262    for (i = 0; a && i < count; i++) {
1263        n = cJSON_CreateString(strings[i]);
1264        if (!i)
1265            a->child = n;
1266        else
1267            suffix_object(p, n);
1268        p = n;
1269    }
1270    return a;
1271}
1272
1273/* Duplication */
1274cJSON *cJSON_Duplicate(cJSON *item, int recurse) {
1275    cJSON *newitem, *cptr, *nptr = 0, *newchild;
1276    /* Bail on bad ptr */
1277    if (!item)
1278        return 0;
1279    /* Create new item */
1280    newitem = cJSON_New_Item();
1281    if (!newitem)
1282        return 0;
1283    /* Copy over all vars */
1284    newitem->type = item->type & (~cJSON_IsReference),
1285    newitem->valueint = item->valueint,
1286    newitem->valuedouble = item->valuedouble;
1287    if (item->valuestring) {
1288        newitem->valuestring = cJSON_strdup(item->valuestring);
1289        if (!newitem->valuestring) {
1290            cJSON_Delete(newitem);
1291            return 0;
1292        }
1293    }
1294    if (item->string) {
1295        newitem->string = cJSON_strdup(item->string);
1296        if (!newitem->string) {
1297            cJSON_Delete(newitem);
1298            return 0;
1299        }
1300    }
1301    /* If non-recursive, then we're done! */
1302    if (!recurse)
1303        return newitem;
1304    /* Walk the ->next chain for the child. */
1305    cptr = item->child;
1306    while (cptr) {
1307        newchild = cJSON_Duplicate(
1308            cptr,
1309            1); /* Duplicate (with recurse) each item in the ->next chain */
1310        if (!newchild) {
1311            cJSON_Delete(newitem);
1312            return 0;
1313        }
1314        if (nptr) {
1315            nptr->next = newchild, newchild->prev = nptr;
1316            nptr = newchild;
1317        } /* If newitem->child already set, then crosswire ->prev and ->next and
1318             move on */
1319        else {
1320            newitem->child = newchild;
1321            nptr = newchild;
1322        } /* Set newitem->child and move to it */
1323        cptr = cptr->next;
1324    }
1325    return newitem;
1326}
1327
1328void cJSON_Minify(char *json) {
1329    char *into = json;
1330    while (*json) {
1331        if (*json == ' ')
1332            json++;
1333        else if (*json == '\t')
1334            json++; /* Whitespace characters. */
1335        else if (*json == '\r')
1336            json++;
1337        else if (*json == '\n')
1338            json++;
1339        else if (*json == '/' && json[1] == '/')
1340            while (*json && *json != '\n')
1341                json++; /* double-slash comments, to end of line. */
1342        else if (*json == '/' && json[1] == '*') {
1343            while (*json && !(*json == '*' && json[1] == '/'))
1344                json++;
1345            json += 2;
1346        } /* multiline comments. */
1347        else if (*json == '\"') {
1348            *into++ = *json++;
1349            while (*json && *json != '\"') {
1350                if (*json == '\\')
1351                    *into++ = *json++;
1352                *into++ = *json++;
1353            }
1354            *into++ = *json++;
1355        } /* string literals, which are \" sensitive. */
1356        else
1357            *into++ = *json++; /* All other characters. */
1358    }
1359    *into = 0; /* and null-terminate. */
1360}
1361