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