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