blob: 21ac10b532468bf16fc2241d48c16cca6e27d664 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include <string.h>
2#include <stdio.h>
3#include <math.h>
4#include <stdlib.h>
5#include <float.h>
6#include <limits.h>
7#include <ctype.h>
8#include "cjson.h"
9
10
11static const char *parse_value(cJSON *item, const char *value);
12static char *print_value(cJSON *item, int depth, int fmt);
13static const char *parse_array(cJSON *item, const char *value);
14static char *print_array(cJSON *item, int depth, int fmt);
15static const char *parse_object(cJSON *item, const char *value);
16static char *print_object(cJSON *item, int depth, int fmt);
17
18static const char *ep;
19
20static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
21
22
23const char *cJSON_GetErrorPtr(void)
24{
25 return ep;
26}
27
28static int cJSON_strcasecmp(const char *s1, const char *s2)
29{
30 if (!s1) return (s1 == s2) ? 0 : 1;
31 if (!s2) return 1;
32 for (; tolower(*s1) == tolower(*s2); ++s1, ++s2) if (*s1 == 0) return 0;
33 return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
34}
35
36static void *(*cJSON_malloc)(size_t sz) = malloc;
37static void (*cJSON_free)(void *ptr) = free;
38
39static const char *skip(const char *in)
40{
41 while (in && *in && (unsigned char)*in <= 32) in++;
42 return in;
43}
44
45static char* cJSON_strdup(const char* str)
46{
47 size_t len;
48 char* str_cpy;
49
50 len = strlen(str) + 1;
51 if (!(str_cpy = (char*)cJSON_malloc(len))) return 0;
52 memcpy(str_cpy, str, len);
53 return str_cpy;
54}
55
56void cJSON_InitHooks(cJSON_Hooks* hooks)
57{
58 if (!hooks) { /*hooks reset*/
59 cJSON_malloc = malloc;
60 cJSON_free = free;
61 return;
62 }
63
64 cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc;
65 cJSON_free = (hooks->free_fn) ? hooks->free_fn : free;
66}
67
68static cJSON *cJSON_New_Item(void)
69{
70 cJSON* inode = (cJSON*)cJSON_malloc(sizeof(cJSON));
71 if (inode) memset(inode, 0, sizeof(cJSON));
72 return inode;
73}
74
75void cJSON_Delete(cJSON *c)
76{
77 cJSON *next_node;
78 while (c) {
79 next_node = c->next;
80 if (!(c->type & cJSON_IsReference) && c->child) cJSON_Delete(c->child);
81 if (!(c->type & cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
82 if (c->string) cJSON_free(c->string);
83 cJSON_free(c);
84 c = next_node;
85 }
86}
87
88static const char *parse_number(cJSON *item, const char *num)
89{
90 int subscale = 0, signsubscale = 1;
91
92 double inum = 0, sign = 1, scale = 0;
93
94 if (*num == '-') sign = -1, num++;
95 if (*num == '0') num++;
96 if (*num >= '1' && *num <= '9') do inum = (inum * 10.0) + (*num++ -'0');
97 while (*num >= '0' && *num <= '9');
98 if (*num == '.' && num[1] >= '0' && num[1] <= '9') {
99 num++;
100 do inum = (inum * 10.0) + (*num++ -'0'), scale--;
101 while (*num >= '0' && *num <= '9');
102 }
103 if (*num == 'e' || *num == 'E') {
104 num++;
105 if (*num == '+') num++;
106 else if (*num == '-') signsubscale = -1, num++;
107 while (*num >= '0' && *num <= '9') subscale = (subscale * 10) + (*num++ - '0');
108 }
109
110 inum = sign * inum * pow(10.0, (scale + subscale * signsubscale));
111
112 item->valuedouble = inum;
113 item->valueint = (int)inum;
114 item->type = cJSON_Number;
115 return num;
116}
117
118static char *print_number(cJSON *item)
119{
120 double d = item->valuedouble;
121
122 char *str;
123
124 if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) {
125 str = (char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
126 if (str) sprintf(str, "%d", item->valueint);
127 } else {
128 str = (char*)cJSON_malloc(64);
129 if (str) {
130 if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)sprintf(str, "%.0f", d);
131 else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9) sprintf(str, "%e", d);
132 else sprintf(str, "%f", d);
133 }
134 }
135 return str;
136}
137
138static unsigned parse_hex4(const char *str)
139{
140 unsigned hex = 0;
141 if (*str >= '0' && *str <= '9')
142 hex += (*str) - '0';
143 else if (*str >= 'A' && *str <= 'F')
144 hex += 10 + (*str) - 'A';
145 else if (*str >= 'a' && *str <= 'f')
146 hex += 10 + (*str) - 'a';
147 else
148 return 0;
149 hex = hex << 4;
150 str++;
151 if (*str >= '0' && *str <= '9')
152 hex += (*str) - '0';
153 else if (*str >= 'A' && *str <= 'F')
154 hex += 10 + (*str) - 'A';
155 else if (*str >= 'a' && *str <= 'f')
156 hex += 10 + (*str) - 'a';
157 else
158 return 0;
159 hex = hex << 4;
160 str++;
161 if (*str >= '0' && *str <= '9')
162 hex += (*str) - '0';
163 else if (*str >= 'A' && *str <= 'F')
164 hex += 10 + (*str) - 'A';
165 else if (*str >= 'a' && *str <= 'f')
166 hex += 10 + (*str) - 'a';
167 else
168 return 0;
169 hex = hex << 4;
170 str++;
171 if (*str >= '0' && *str <= '9')
172 hex += (*str) - '0';
173 else if (*str >= 'A' && *str <= 'F')
174 hex += 10 + (*str) - 'A';
175 else if (*str >= 'a' && *str <= 'f')
176 hex += 10 + (*str) - 'a';
177 else
178 return 0;
179 return hex;
180}
181
182static const char *parse_string(cJSON *item, const char *str)
183{
184 const char *pstr = str + 1;
185 char *pstr2;
186 char *out;
187 int len = 0;
188 unsigned uc, uc2;
189 if (*str != '\"') {
190 ep = str; /* not a string! */
191 return 0;
192 }
193
194 while (*pstr != '\"' && *pstr && ++len) if (*pstr++ == '\\') pstr++; /* Skip escaped quotes. */
195
196 out = (char*)cJSON_malloc(len + 1); /* This is how long we need for the string, roughly. */
197 if (!out) return 0;
198
199 pstr = str + 1;
200 pstr2 = out;
201 while (*pstr != '\"' && *pstr) {
202 if (*pstr != '\\') *pstr2++ = *pstr++;
203 else {
204 pstr++;
205 switch (*pstr) {
206 case 'b':
207 *pstr2++ = '\b';
208 break;
209 case 'f':
210 *pstr2++ = '\f';
211 break;
212 case 'n':
213 *pstr2++ = '\n';
214 break;
215 case 'r':
216 *pstr2++ = '\r';
217 break;
218 case 't':
219 *pstr2++ = '\t';
220 break;
221 case 'u':
222 uc = parse_hex4(pstr + 1);
223 pstr += 4;
224
225 if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0)
226 break;
227
228 if (uc >= 0xD800 && uc <= 0xDBFF) {
229 if (pstr[1] != '\\' || pstr[2] != 'u')
230 break;
231 uc2 = parse_hex4(pstr + 3);
232 pstr += 6;
233 if (uc2 < 0xDC00 || uc2 > 0xDFFF)
234 break;
235 uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
236 }
237
238 len = 4;
239 if (uc < 0x80) len = 1;
240 else if (uc < 0x800) len = 2;
241 else if (uc < 0x10000) len = 3;
242 pstr2 += len;
243
244 switch (len) {
245 case 4:
246 *--pstr2 = ((uc | 0x80) & 0xBF);
247 uc >>= 6;
248 case 3:
249 *--pstr2 = ((uc | 0x80) & 0xBF);
250 uc >>= 6;
251 case 2:
252 *--pstr2 = ((uc | 0x80) & 0xBF);
253 uc >>= 6;
254 case 1:
255 *--pstr2 = (uc | firstByteMark[len]);
256 }
257 pstr2 += len;
258 break;
259 default:
260 *pstr2++ = *pstr;
261 break;
262 }
263 pstr++;
264 }
265 }
266 *pstr2 = 0;
267 if (*pstr == '\"') pstr++;
268 item->valuestring = out;
269 item->type = cJSON_String;
270 return pstr;
271}
272
273static char *print_string_ptr(const char *str)
274{
275 const char *pstr;
276 char *pstr2, *out;
277 int len = 0;
278 unsigned char token;
279
280 if (!str) return cJSON_strdup("");
281 pstr = str;
282 while ((token = *pstr) && ++len) {
283 if (strchr("\"\\\b\f\n\r\t", token)) len++;
284 else if (token < 32) len += 5;
285 pstr++;
286 }
287
288 out = (char*)cJSON_malloc(len + 3);
289 if (!out) return 0;
290
291 pstr2 = out;
292 pstr = str;
293 *pstr2++ = '\"';
294 while (*pstr) {
295 if ((unsigned char)*pstr > 31 && *pstr != '\"' && *pstr != '\\') *pstr2++ = *pstr++;
296 else {
297 *pstr2++ = '\\';
298 switch (token = *pstr++) {
299 case '\\':
300 *pstr2++ = '\\';
301 break;
302 case '\"':
303 *pstr2++ = '\"';
304 break;
305 case '\b':
306 *pstr2++ = 'b';
307 break;
308 case '\f':
309 *pstr2++ = 'f';
310 break;
311 case '\n':
312 *pstr2++ = 'n';
313 break;
314 case '\r':
315 *pstr2++ = 'r';
316 break;
317 case '\t':
318 *pstr2++ = 't';
319 break;
320 default:
321 sprintf(pstr2, "u%04x", token);
322 pstr2 += 5;
323 break;
324 }
325 }
326 }
327 *pstr2++ = '\"';
328 *pstr2++ = 0;
329 return out;
330}
331
332static char *print_string(cJSON *item)
333{
334 return print_string_ptr(item->valuestring);
335}
336
337cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int require_null_terminated)
338{
339 const char *str_end = 0;
340 cJSON *c = cJSON_New_Item();
341 ep = 0;
342 if (!c)
343 return 0;
344
345 str_end = parse_value(c, skip(value));
346 if (!str_end) {
347 cJSON_Delete(c);
348 return 0;
349 }
350
351 if (require_null_terminated) {
352 str_end = skip(str_end);
353 if (*str_end) {
354 cJSON_Delete(c);
355 ep = str_end;
356 return 0;
357 }
358 }
359 if (return_parse_end) *return_parse_end = str_end;
360 return c;
361}
362
363cJSON *cJSON_Parse(const char *value)
364{
365 return cJSON_ParseWithOpts(value, 0, 0);
366}
367char *cJSON_Print(cJSON *item)
368{
369 return print_value(item, 0, 1);
370}
371char *cJSON_PrintUnformatted(cJSON *item)
372{
373 return print_value(item, 0, 0);
374}
375
376static const char *parse_value(cJSON *item, const char *value)
377{
378 if (!value)
379 return 0;
380 if (!strncmp(value, "null", 4)) {
381 item->type = cJSON_NULL;
382 return value + 4;
383 }
384 if (!strncmp(value, "false", 5)) {
385 item->type = cJSON_False;
386 return value + 5;
387 }
388 if (!strncmp(value, "true", 4)) {
389 item->type = cJSON_True;
390 item->valueint = 1;
391 return value + 4;
392 }
393 if (*value == '\"') {
394 return parse_string(item, value);
395 }
396 if (*value == '-' || (*value >= '0' && *value <= '9')) {
397 return parse_number(item, value);
398 }
399 if (*value == '[') {
400 return parse_array(item, value);
401 }
402 if (*value == '{') {
403 return parse_object(item, value);
404 }
405
406 ep = value;
407 return 0;
408}
409
410static char *print_value(cJSON *item, int depth, int fmt)
411{
412 char *item_value = 0;
413 if (!item)
414 return 0;
415 switch ((item->type) & 255) {
416 case cJSON_NULL:
417 item_value = cJSON_strdup("null");
418 break;
419 case cJSON_False:
420 item_value = cJSON_strdup("false");
421 break;
422 case cJSON_True:
423 item_value = cJSON_strdup("true");
424 break;
425 case cJSON_Number:
426 item_value = print_number(item);
427 break;
428 case cJSON_String:
429 item_value = print_string(item);
430 break;
431 case cJSON_Array:
432 item_value = print_array(item, depth, fmt);
433 break;
434 case cJSON_Object:
435 item_value = print_object(item, depth, fmt);
436 break;
437 }
438 return item_value;
439}
440
441
442static const char *parse_array(cJSON *item, const char *value)
443{
444 cJSON *child;
445 if (*value != '[') {
446 ep = value;
447 return 0;
448 }
449
450 item->type = cJSON_Array;
451 value = skip(value + 1);
452 if (*value == ']') return value + 1;
453
454 item->child = child = cJSON_New_Item();
455 if (!item->child) return 0;
456 value = skip(parse_value(child, skip(value)));
457 if (!value) return 0;
458
459 while (*value == ',') {
460 cJSON *new_item;
461 if (!(new_item = cJSON_New_Item()))
462 return 0;
463 child->next = new_item;
464 new_item->prev = child;
465 child = new_item;
466 value = skip(parse_value(child, skip(value + 1)));
467 if (!value)
468 return 0;
469 }
470
471 if (*value == ']')
472 return value + 1;
473 ep = value;
474 return 0;
475}
476
477static char *print_array(cJSON *item, int depth, int fmt)
478{
479 char *oitem = 0, *pstr, *ret;
480 char **entries;
481 int len = 5;
482 int numentries = 0, i = 0, fail = 0;
483 cJSON *child = item->child;
484
485 while (child) numentries++, child = child->next;
486
487 if (!numentries) {
488 oitem = (char*)cJSON_malloc(3);
489 if (oitem)
490 strcpy(oitem, "[]");
491 return oitem;
492 }
493
494 entries = (char**)cJSON_malloc(numentries * sizeof(char*));
495 if (!entries) return 0;
496 memset(entries, 0, numentries * sizeof(char*));
497
498 child = item->child;
499 while (child && !fail) {
500 ret = print_value(child, depth + 1, fmt);
501 entries[i++] = ret;
502 if (ret) len += strlen(ret) + 2 + (fmt ? 1 : 0);
503 else fail = 1;
504 child = child->next;
505 }
506
507
508 if (!fail)
509 oitem = (char*)cJSON_malloc(len);
510
511 if (!oitem)
512 fail = 1;
513
514
515 if (fail) {
516 for (i = 0; i < numentries; i++) if (entries[i]) cJSON_free(entries[i]);
517 cJSON_free(entries);
518 return 0;
519 }
520
521
522 *oitem = '[';
523 pstr = oitem + 1;
524 *pstr = 0;
525 for (i = 0; i < numentries; i++) {
526 strcpy(pstr, entries[i]);
527 pstr += strlen(entries[i]);
528 if (i != numentries - 1) {
529 *pstr++ = ',';
530 if (fmt)*pstr++ = ' ';
531 *pstr = 0;
532 }
533 cJSON_free(entries[i]);
534 }
535 cJSON_free(entries);
536 *pstr++ = ']';
537 *pstr++ = 0;
538 return oitem;
539}
540
541static const char *parse_object(cJSON *item, const char *value)
542{
543 cJSON *child;
544 if (*value != '{') {
545 ep = value;
546 return 0;
547 }
548
549 item->type = cJSON_Object;
550 value = skip(value + 1);
551 if (*value == '}') return value + 1;
552
553 item->child = child = cJSON_New_Item();
554 if (!item->child) return 0;
555 value = skip(parse_string(child, skip(value)));
556 if (!value) return 0;
557 child->string = child->valuestring;
558 child->valuestring = 0;
559 if (*value != ':') {
560 ep = value;
561 return 0;
562 }
563 value = skip(parse_value(child, skip(value + 1)));
564 if (!value) return 0;
565
566 while (*value == ',') {
567 cJSON *new_item;
568 if (!(new_item = cJSON_New_Item())) return 0;
569 child->next = new_item;
570 new_item->prev = child;
571 child = new_item;
572 value = skip(parse_string(child, skip(value + 1)));
573 if (!value) return 0;
574 child->string = child->valuestring;
575 child->valuestring = 0;
576 if (*value != ':') {
577 ep = value;
578 return 0;
579 }
580 value = skip(parse_value(child, skip(value + 1)));
581 if (!value) return 0;
582 }
583
584 if (*value == '}') return value + 1;
585 ep = value;
586 return 0;
587}
588
589static char *print_object(cJSON *item, int depth, int fmt)
590{
591 char *oitem = 0, *pstr, *ret, *str;
592 char **entries = 0, **names = 0;
593 int len = 7, i = 0, j;
594 int numentries = 0, fail = 0;
595 cJSON *child = item->child;
596
597 while (child) numentries++, child = child->next;
598
599 if (!numentries) {
600 oitem = (char*)cJSON_malloc(fmt ? depth + 4 : 3);
601 if (!oitem) return 0;
602 pstr = oitem;
603 *pstr++ = '{';
604 if (fmt) {
605 *pstr++ = '\n';
606 for (i = 0; i < depth - 1; i++) *pstr++ = '\t';
607 }
608 *pstr++ = '}';
609 *pstr++ = 0;
610 return oitem;
611 }
612
613 entries = (char**)cJSON_malloc(numentries * sizeof(char*));
614 if (!entries)
615 return 0;
616 names = (char**)cJSON_malloc(numentries * sizeof(char*));
617 if (!names) {
618 cJSON_free(entries);
619 return 0;
620 }
621 memset(entries, 0, sizeof(char*)*numentries);
622 memset(names, 0, sizeof(char*)*numentries);
623
624
625 child = item->child;
626 depth++;
627 if (fmt) len += depth;
628 while (child) {
629 names[i] = str = print_string_ptr(child->string);
630 entries[i++] = ret = print_value(child, depth, fmt);
631 if (str && ret)
632 len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0);
633 else
634 fail = 1;
635 child = child->next;
636 }
637
638
639 if (!fail) oitem = (char*)cJSON_malloc(len);
640 if (!oitem) fail = 1;
641
642
643 if (fail) {
644 for (i = 0; i < numentries; i++) {
645 if (names[i]) cJSON_free(names[i]);
646 if (entries[i]) cJSON_free(entries[i]);
647 }
648 cJSON_free(names);
649 cJSON_free(entries);
650 return 0;
651 }
652
653
654 *oitem = '{';
655 pstr = oitem + 1;
656 if (fmt)*pstr++ = '\n';
657 *pstr = 0;
658 for (i = 0; i < numentries; i++) {
659 if (fmt) for (j = 0; j < depth; j++) *pstr++ = '\t';
660 strcpy(pstr, names[i]);
661 pstr += strlen(names[i]);
662 *pstr++ = ':';
663 if (fmt) *pstr++ = '\t';
664 strcpy(pstr, entries[i]);
665 pstr += strlen(entries[i]);
666 if (i != numentries - 1) *pstr++ = ',';
667 if (fmt) *pstr++ = '\n';
668 *pstr = 0;
669 cJSON_free(names[i]);
670 cJSON_free(entries[i]);
671 }
672
673 cJSON_free(names);
674 cJSON_free(entries);
675 if (fmt) for (i = 0; i < depth - 1; i++) *pstr++ = '\t';
676 *pstr++ = '}';
677 *pstr++ = 0;
678 return oitem;
679}
680
681int cJSON_GetArraySize(cJSON *array)
682{
683 int i = 0;
684 cJSON *citem = array->child;
685
686 while (citem)i++, citem = citem->next;
687 return i;
688}
689cJSON *cJSON_GetArrayItem(cJSON *array, int item)
690{
691 cJSON *citem = array->child;
692 while (citem && item > 0) item--, citem = citem->next;
693 return citem;
694}
695cJSON *cJSON_GetObjectItem(cJSON *object, const char *string)
696{
697 cJSON *citem = object->child;
698 while (citem && cJSON_strcasecmp(citem->string, string)) citem = citem->next;
699 return citem;
700}
701
702static void suffix_object(cJSON *prev, cJSON *item)
703{
704 prev->next = item;
705 item->prev = prev;
706}
707
708static cJSON *create_reference(cJSON *item)
709{
710 cJSON *refer = cJSON_New_Item();
711 if (!refer)
712 return 0;
713 memcpy(refer, item, sizeof(cJSON));
714 refer->string = 0;
715 refer->type |= cJSON_IsReference;
716 refer->next = refer->prev = 0;
717 return refer;
718}
719
720void cJSON_AddItemToArray(cJSON *array, cJSON *item)
721{
722 cJSON *citem = array->child;
723 if (!item)
724 return;
725 if (!citem) {
726 array->child = item;
727 } else {
728 while (citem && citem->next) citem = citem->next;
729 suffix_object(citem, item);
730 }
731}
732void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
733{
734 if (!item)
735 return;
736 if (item->string) cJSON_free(item->string);
737 item->string = cJSON_strdup(string);
738 cJSON_AddItemToArray(object, item);
739}
740void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
741{
742 cJSON_AddItemToArray(array, create_reference(item));
743}
744void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
745{
746 cJSON_AddItemToObject(object, string, create_reference(item));
747}
748
749cJSON *cJSON_DetachItemFromArray(cJSON *array, int which)
750{
751 cJSON *citem = array->child;
752 while (citem && which > 0) citem = citem->next, which--;
753 if (!citem)
754 return 0;
755 if (citem->prev) citem->prev->next = citem->next;
756 if (citem->next) citem->next->prev = citem->prev;
757 if (citem == array->child) array->child = citem->next;
758 citem->prev = citem->next = 0;
759 return citem;
760}
761void cJSON_DeleteItemFromArray(cJSON *array, int which)
762{
763 cJSON_Delete(cJSON_DetachItemFromArray(array, which));
764}
765cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string)
766{
767 int i = 0;
768 cJSON *citem = object->child;
769 while (citem && cJSON_strcasecmp(citem->string, string)) i++, citem = citem->next;
770 if (citem)
771 return cJSON_DetachItemFromArray(object, i);
772 return 0;
773}
774void cJSON_DeleteItemFromObject(cJSON *object, const char *string)
775{
776 cJSON_Delete(cJSON_DetachItemFromObject(object, string));
777}
778
779void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
780{
781 cJSON *citem = array->child;
782 while (citem && which > 0) citem = citem->next, which--;
783 if (!citem)
784 return;
785 newitem->next = citem->next;
786 newitem->prev = citem->prev;
787 if (newitem->next) newitem->next->prev = newitem;
788 if (citem == array->child) array->child = newitem;
789 else newitem->prev->next = newitem;
790 citem->next = citem->prev = 0;
791 cJSON_Delete(citem);
792}
793void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
794{
795 int i = 0;
796 cJSON *citem = object->child;
797 while (citem && cJSON_strcasecmp(citem->string, string))i++, citem = citem->next;
798 if (citem) {
799 newitem->string = cJSON_strdup(string);
800 cJSON_ReplaceItemInArray(object, i, newitem);
801 }
802}
803
804cJSON *cJSON_CreateNull(void)
805{
806 cJSON *item = cJSON_New_Item();
807 if (item)item->type = cJSON_NULL;
808 return item;
809}
810cJSON *cJSON_CreateTrue(void)
811{
812 cJSON *item = cJSON_New_Item();
813 if (item)item->type = cJSON_True;
814 return item;
815}
816cJSON *cJSON_CreateFalse(void)
817{
818 cJSON *item = cJSON_New_Item();
819 if (item)item->type = cJSON_False;
820 return item;
821}
822cJSON *cJSON_CreateBool(int b)
823{
824 cJSON *item = cJSON_New_Item();
825 if (item)item->type = b ? cJSON_True : cJSON_False;
826 return item;
827}
828cJSON *cJSON_CreateNumber(double num)
829{
830 cJSON *item = cJSON_New_Item();
831 if (item) {
832 item->type = cJSON_Number;
833 item->valuedouble = num;
834 item->valueint = (int)num;
835 }
836 return item;
837}
838cJSON *cJSON_CreateString(const char *string)
839{
840 cJSON *item = cJSON_New_Item();
841 if (item) {
842 item->type = cJSON_String;
843 item->valuestring = cJSON_strdup(string);
844 }
845 return item;
846}
847cJSON *cJSON_CreateArray(void)
848{
849 cJSON *item = cJSON_New_Item();
850 if (item)item->type = cJSON_Array;
851 return item;
852}
853cJSON *cJSON_CreateObject(void)
854{
855 cJSON *item = cJSON_New_Item();
856 if (item)item->type = cJSON_Object;
857 return item;
858}
859
860cJSON *cJSON_CreateIntArray(const int *numbers, int count)
861{
862 int i;
863 cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
864 for (i = 0; a && i < count; i++) {
865 n = cJSON_CreateNumber(numbers[i]);
866 if (!i)a->child = n;
867 else suffix_object(p, n);
868 p = n;
869 }
870 return a;
871}
872cJSON *cJSON_CreateFloatArray(const float *numbers, int count)
873{
874 int i;
875 cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
876 for (i = 0; a && i < count; i++) {
877 n = cJSON_CreateNumber(numbers[i]);
878 if (!i)a->child = n;
879 else suffix_object(p, n);
880 p = n;
881 }
882 return a;
883}
884cJSON *cJSON_CreateDoubleArray(const double *numbers, int count)
885{
886 int i;
887 cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
888 for (i = 0; a && i < count; i++) {
889 n = cJSON_CreateNumber(numbers[i]);
890 if (!i)a->child = n;
891 else suffix_object(p, n);
892 p = n;
893 }
894 return a;
895}
896cJSON *cJSON_CreateStringArray(const char **strings, int count)
897{
898 int i;
899 cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
900 for (i = 0; a && i < count; i++) {
901 n = cJSON_CreateString(strings[i]);
902 if (!i)a->child = n;
903 else suffix_object(p, n);
904 p = n;
905 }
906 return a;
907}
908
909cJSON *cJSON_Duplicate(cJSON *item, int recurse)
910{
911 cJSON *newitem, *cptr, *nptr = 0, *newchild;
912
913 if (!item)
914 return 0;
915
916 newitem = cJSON_New_Item();
917 if (!newitem)
918 return 0;
919
920 newitem->type = item->type & (~cJSON_IsReference), newitem->valueint = item->valueint, newitem->valuedouble = item->valuedouble;
921 if (item->valuestring) {
922 newitem->valuestring = cJSON_strdup(item->valuestring);
923 if (!newitem->valuestring) {
924 cJSON_Delete(newitem);
925 return 0;
926 }
927 }
928 if (item->string) {
929 newitem->string = cJSON_strdup(item->string);
930 if (!newitem->string) {
931 cJSON_Delete(newitem);
932 return 0;
933 }
934 }
935
936 if (!recurse)
937 return newitem;
938
939 cptr = item->child;
940 while (cptr) {
941 newchild = cJSON_Duplicate(cptr, 1);
942 if (!newchild) {
943 cJSON_Delete(newitem);
944 return 0;
945 }
946 if (nptr) {
947 nptr->next = newchild, newchild->prev = nptr;
948 nptr = newchild;
949 } else {
950 newitem->child = newchild;
951 nptr = newchild;
952 }
953 cptr = cptr->next;
954 }
955 return newitem;
956}
957
958void cJSON_Minify(char *json)
959{
960 char *cpr_str = json;
961 while (*json) {
962 if (*json == ' ') json++;
963 else if (*json == '\t') json++;
964 else if (*json == '\r') json++;
965 else if (*json == '\n') json++;
966 else if (*json == '/' && json[1] == '/') while (*json && *json != '\n') json++;
967 else if (*json == '/' && json[1] == '*') {
968 while (*json && !(*json == '*' && json[1] == '/')) json++;
969 json += 2;
970 } else if (*json == '\"') {
971 *cpr_str++ = *json++;
972 while (*json && *json != '\"') {
973 if (*json == '\\') *cpr_str++ = *json++;
974 *cpr_str++ = *json++;
975 }
976 *cpr_str++ = *json++;
977 } else *cpr_str++ = *json++;
978 }
979 *cpr_str = 0;
980}