1 /*
2 Copyright (c) 2009 Dave Gamble
3 Copyright (c) 2009 The OpenTyrian Development Team
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22 */
23
24 // cJSON
25 // JSON parser in C.
26
27 #include "cJSON.h"
28 #include "mingw_fixes.h"
29
30 #include <assert.h>
31 #include <ctype.h>
32 #include <float.h>
33 #include <limits.h>
34 #include <math.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 static void *(*cJSON_malloc)( size_t ) = malloc;
40 static void *(*cJSON_realloc)( void *, size_t ) = realloc;
41 static void (*cJSON_free)( void *ptr ) = free;
42
43 // helper for compilers without strdup
cJSON_strdup(const char * str)44 static char *cJSON_strdup( const char *str )
45 {
46 size_t size = strlen(str) + 1;
47 char *copy = (char *)cJSON_malloc(size);
48
49 if (copy != NULL)
50 memcpy(copy, str, size);
51
52 return copy;
53 }
54
55 // helper for compilers without strcasecmp
cJSON_strcasecmp(const char * s1,const char * s2)56 static int cJSON_strcasecmp( const char *s1, const char *s2 )
57 {
58 for(; tolower(*(const unsigned char *)s1) == tolower(*(const unsigned char *)s2); ++s1, ++s2)
59 if (*s1 == 0)
60 return 0;
61 return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
62 }
63
64 // construct empty item
cJSON_NewItem(cJSON_Type type)65 static cJSON *cJSON_NewItem( cJSON_Type type )
66 {
67 cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON));
68
69 if (node != NULL)
70 {
71 node->type = type;
72 node->child =
73 node->prev =
74 node->next = NULL;
75
76 node->string = NULL;
77
78 node->valuestring = NULL;
79 node->valueint =
80 node->valuedouble = 0;
81 }
82
83 return node;
84 }
85
86 // destroy item chain
cJSON_Delete(cJSON * item)87 void cJSON_Delete( cJSON *item )
88 {
89 while (item != NULL)
90 {
91 if (item->child)
92 cJSON_Delete(item->child);
93
94 cJSON *next = item->next;
95
96 if (item->string)
97 cJSON_free(item->string);
98 if (item->valuestring)
99 cJSON_free(item->valuestring);
100 cJSON_free(item);
101
102 item = next;
103 }
104 }
105
106 // parser/emitter prototypes
107
108 static const char *parse_value( cJSON *item, const char *in );
109 static char *print_value(cJSON *item,int depth);
110
111 static const char *parse_number( cJSON *item, const char *in );
112 static char *print_number( cJSON *item );
113
114 static const char *parse_string(cJSON *item,const char *str);
115 static char *print_string(cJSON *item);
116
117 static const char *parse_array_or_object( cJSON *item, const char *in, cJSON_Type type );
118 static char *print_array(cJSON *item,int depth);
119 static char *print_object(cJSON *item,int depth);
120
parse_array(cJSON * item,const char * in)121 static inline const char *parse_array( cJSON *item, const char *in )
122 {
123 return parse_array_or_object(item, in, cJSON_Array);
124 }
parse_object(cJSON * item,const char * in)125 static inline const char *parse_object( cJSON *item, const char *in )
126 {
127 return parse_array_or_object(item, in, cJSON_Object);
128 }
129
130 // helper to skip whitespace
skip_space(const char * str)131 static inline const char *skip_space( const char *str )
132 {
133 if (str != NULL)
134 while (isspace(*str))
135 ++str;
136 return str;
137 }
138
139 // parse root of JSON into cJSON item
cJSON_Parse(const char * in)140 cJSON *cJSON_Parse( const char *in )
141 {
142 cJSON *item = cJSON_NewItem(cJSON_NULL);
143
144 if (item != NULL)
145 {
146 if (parse_value(item, skip_space(in)) == NULL) // if malformed or out-of-memory
147 {
148 cJSON_Delete(item);
149 item = NULL;
150 }
151 }
152
153 return item;
154 }
155
156 // emit cJSON item as JSON value
cJSON_Print(cJSON * item)157 char *cJSON_Print( cJSON *item )
158 {
159 return print_value(item, 0);
160 }
161
162 // parse JSON value into cJSON item
parse_value(cJSON * item,const char * in)163 static const char *parse_value( cJSON *item, const char *in )
164 {
165 if (in == NULL)
166 return in;
167
168 if (!strncmp(in, "null", 4))
169 {
170 item->type = cJSON_NULL;
171 return in + 4;
172 }
173 if (!strncmp(in, "false", 5))
174 {
175 item->type = cJSON_False;
176 return in + 5;
177 }
178 if (!strncmp(in, "true", 4))
179 {
180 item->type = cJSON_True;
181 return in + 4;
182 }
183 if (*in == '\"')
184 return parse_string(item, in);
185 if (*in == '-' || (*in >= '0' && *in <= '9'))
186 return parse_number(item, in);
187 if (*in == '[')
188 return parse_array(item, in);
189 if (*in == '{')
190 return parse_object(item, in);
191
192 return NULL; // malformed: expected value
193 }
194
195 // emit cJSON item as JSON value
print_value(cJSON * item,int depth)196 static char *print_value( cJSON *item, int depth )
197 {
198 char *out = NULL;
199
200 switch (item->type)
201 {
202 case cJSON_NULL:
203 out = cJSON_strdup("null");
204 break;
205 case cJSON_False:
206 out = cJSON_strdup("false");
207 break;
208 case cJSON_True:
209 out = cJSON_strdup("true");
210 break;
211 case cJSON_Number:
212 out = print_number(item);
213 break;
214 case cJSON_String:
215 out = print_string(item);
216 break;
217 case cJSON_Array:
218 out = print_array(item, depth);
219 break;
220 case cJSON_Object:
221 out = print_object(item, depth);
222 break;
223 }
224
225 return out;
226 }
227
228 // parse JSON number value into cJSON item
parse_number(cJSON * item,const char * in)229 static const char *parse_number( cJSON *item, const char *in )
230 {
231 double n = 0;
232 int sign = 1, decimal_shift = 0;
233 int exponent_sign = 1, exponent = 0;
234
235 if (*in == '-')
236 sign = -1, ++in;
237
238 // integer part
239 if (*in == '0')
240 ++in;
241 else if (*in >= '1' && *in <= '9')
242 do
243 n = (n * 10.0) + (*(in++) - '0');
244 while (*in >= '0' && *in <= '9');
245
246 // fractional part
247 if (*in == '.')
248 {
249 ++in;
250
251 while (*in >= '0' && *in <= '9')
252 n = (n * 10.0) + (*(in++) - '0'), decimal_shift--;
253 }
254
255 // exponent part
256 if (*in == 'e' || *in == 'E')
257 {
258 ++in;
259
260 if (*in == '+')
261 ++in;
262 else if (*in == '-')
263 exponent_sign = -1, ++in;
264
265 while (*in >= '0' && *in <= '9')
266 exponent = (exponent * 10) + (*(in++) - '0');
267 }
268
269 // number = +/- number.fraction * (10 ^ +/- exponent)
270 n = sign * n * pow(10.0, decimal_shift + exponent_sign * exponent);
271
272 item->valuedouble = n;
273 item->valueint = n;
274 item->type = cJSON_Number;
275
276 return in;
277 }
278
279 // emit string containing numeric value of cJSON item
print_number(cJSON * item)280 static char *print_number( cJSON *item )
281 {
282 char *str = (char *)cJSON_malloc(DBL_DIG + 10);
283 snprintf(str, DBL_DIG + 10, "%.*g", DBL_DIG, item->valuedouble);
284 return str;
285 }
286
287 // Parse the input text into an unescaped cstring, and populate item.
288 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
parse_string(cJSON * item,const char * str)289 static const char *parse_string(cJSON *item,const char *str)
290 {
291 const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
292 if (*str!='\"') return 0; // not a string!
293
294 while (*ptr!='\"' && *ptr>31 && ++len) if (*ptr++ == '\\') ptr++; // skip escaped quotes.
295
296 out=(char*)cJSON_malloc(len+1); // This is how long we need for the string, roughly.
297 if (!out) return 0;
298
299 ptr=str+1;ptr2=out;
300 while (*ptr!='\"' && *ptr>31)
301 {
302 if (*ptr!='\\') *ptr2++=*ptr++;
303 else
304 {
305 ptr++;
306 switch (*ptr)
307 {
308 case 'b': *ptr2++='\b'; break;
309 case 'f': *ptr2++='\f'; break;
310 case 'n': *ptr2++='\n'; break;
311 case 'r': *ptr2++='\r'; break;
312 case 't': *ptr2++='\t'; break;
313 case 'u': // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
314 sscanf(ptr+1,"%4x",&uc); // get the unicode char.
315 len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
316
317 switch (len) {
318 case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
319 case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
320 case 1: *--ptr2 =(uc | firstByteMark[len]);
321 }
322 ptr2+=len;ptr+=4;
323 break;
324 default: *ptr2++=*ptr; break;
325 }
326 ptr++;
327 }
328 }
329 *ptr2=0;
330 if (*ptr=='\"') ptr++;
331 item->valuestring=out;
332 item->type=cJSON_String;
333 return ptr;
334 }
335
336 // Render the cstring provided to an escaped version that can be printed.
print_string_ptr(const char * str)337 static char *print_string_ptr(const char *str)
338 {
339 const char *ptr;char *ptr2,*out;int len=0;
340
341 ptr=str;while (*ptr && ++len) {if (*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
342
343 out=(char*)cJSON_malloc(len+3);
344 ptr2=out;ptr=str;
345 *ptr2++='\"';
346 while (*ptr)
347 {
348 if (*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
349 else
350 {
351 *ptr2++='\\';
352 switch (*ptr++)
353 {
354 case '\\': *ptr2++='\\'; break;
355 case '\"': *ptr2++='\"'; break;
356 case '\b': *ptr2++='b'; break;
357 case '\f': *ptr2++='f'; break;
358 case '\n': *ptr2++='n'; break;
359 case '\r': *ptr2++='r'; break;
360 case '\t': *ptr2++='t'; break;
361 default: ptr2--; break; // eviscerate with prejudice.
362 }
363 }
364 }
365 *ptr2++='\"';*ptr2++=0;
366 return out;
367 }
368 // Invote print_string_ptr (which is useful) on an item.
print_string(cJSON * item)369 static char *print_string(cJSON *item)
370 {
371 return (item->valuestring != NULL) ? print_string_ptr(item->valuestring) : cJSON_strdup("");
372 }
373
374 // parse JSON array/object into cJSON item chain
parse_array_or_object(cJSON * const item,const char * in,cJSON_Type type)375 static const char *parse_array_or_object( cJSON *const item, const char *in, cJSON_Type type )
376 {
377 assert(type == cJSON_Array || type == cJSON_Object);
378
379 const char opening = (type == cJSON_Object) ? '{' : '[',
380 closing = (type == cJSON_Object) ? '}' : ']';
381
382 if (*in != opening) // not an array/object!
383 return NULL;
384 else
385 in = skip_space(++in);
386
387 item->type = type;
388
389 if (*in == closing) // empty array/object
390 return ++in;
391
392 cJSON *prev_child = NULL;
393 for (; ; )
394 {
395 cJSON *child = cJSON_NewItem(cJSON_NULL);
396 if (child == NULL) // memory fail
397 return NULL;
398
399 if (prev_child == NULL)
400 {
401 // attach first child to parent
402 item->child = child;
403 }
404 else
405 {
406 // attach other children to older sibling
407 prev_child->next = child;
408 child->prev = prev_child;
409 }
410
411 if (type == cJSON_Object)
412 {
413 // object children have identifier string
414
415 in = skip_space(parse_string(child, skip_space(in)));
416 if (in == NULL) // malformed or memory fail
417 return NULL;
418
419 // parse_string parses into the item's value; we can use it to parse the identifier string, we just have to move the results
420 child->string = child->valuestring;
421 child->valuestring = NULL;
422
423 if (*in != ':') // malformed
424 return NULL;
425 else
426 ++in;
427 }
428
429 in = skip_space(parse_value(child, skip_space(in)));
430 if (in == NULL) // malformed or memory fail
431 return NULL;
432
433 prev_child = child;
434
435 if (*in == ',')
436 ++in;
437 else
438 break;
439 }
440
441 if (*in == closing) // end of array/object
442 return ++in;
443
444 return NULL; // malformed
445 }
446
447 // Render an array to text
print_array(cJSON * item,int depth)448 static char *print_array(cJSON *item,int depth)
449 {
450 char *out, *ptr;
451 size_t len = 3; // minimum needed to print empty array
452
453 ptr = out = (char*)cJSON_malloc(len);
454
455 strcpy(ptr, "[");
456 ptr += 1;
457
458 cJSON *child = item->child;
459
460 while (child)
461 {
462 char *ret = print_value(child, depth + 1);
463 if (!ret)
464 {
465 cJSON_free(out);
466 return NULL;
467 }
468 size_t ret_len = strlen(ret);
469
470 len += ret_len + 2;
471 ptr = out = (char*)cJSON_realloc(out, len);
472 ptr += strlen(out);
473
474 strcpy(ptr, ret); // strcat(out, ret);
475 ptr += ret_len;
476
477 cJSON_free(ret);
478
479 if (child->next)
480 {
481 strcpy(ptr, ", "); // strcat(out, ", ");
482 ptr += 2;
483 }
484
485 child = child->next;
486 }
487
488 strcpy(ptr, "]"); // strcat(out, "]");
489
490 return out;
491 }
492
493 // Render an object to text.
print_object(cJSON * item,int depth)494 static char *print_object(cJSON *item,int depth)
495 {
496 char *out, *ptr;
497 size_t len = 4 + depth; // minimum needed to print empty object
498
499 ++depth;
500
501 ptr = out = (char*)cJSON_malloc(len);
502
503 strcpy(ptr, "{\n");
504 ptr += 2;
505
506 cJSON *child = item->child;
507
508 while (child)
509 {
510 char *str = print_string_ptr(child->string);
511 if (!str)
512 {
513 cJSON_free(out);
514 return NULL;
515 }
516 size_t str_len = strlen(str);
517
518 char *ret = print_value(child, depth);
519 if (!ret)
520 {
521 cJSON_free(str);
522 cJSON_free(out);
523 return NULL;
524 }
525 size_t ret_len = strlen(ret);
526
527 len += depth + str_len + ret_len + 4;
528 out = (char*)cJSON_realloc(out, len);
529 ptr = out + strlen(out);
530
531 for (int i = 0; i < depth; ++i)
532 *(ptr++) = '\t';
533
534 strcpy(ptr, str); // strcat(out, str);
535 ptr += str_len;
536
537 cJSON_free(str);
538
539 strcpy(ptr, ":\t"); // strcat(out, ":\t");
540 ptr += 2;
541
542 strcpy(ptr, ret); // strcat(out, ret);
543 ptr += ret_len;
544
545 cJSON_free(ret);
546
547 if (child->next)
548 {
549 strcpy(ptr, ",\n"); // strcat(out, ",\n");
550 ptr += 2;
551 }
552 else
553 {
554 strcpy(ptr, "\n"); // strcat(out, "\n");
555 ptr += 1;
556 }
557
558 child = child->next;
559 }
560
561 --depth;
562
563 for (int i = 0; i < depth; ++i)
564 *(ptr++) = '\t';
565
566 strcpy(ptr, "}"); // strcat(out, "}");
567
568 return out;
569 }
570
571 // Get Array size/item / object item.
cJSON_GetArraySize(cJSON * array)572 int cJSON_GetArraySize( cJSON *array )
573 {
574 int size = 0;
575 cJSON *item = array->child;
576 while (item != NULL)
577 item = item->next, ++size;
578 return size;
579 }
cJSON_GetArrayItem(cJSON * array,int index)580 cJSON *cJSON_GetArrayItem( cJSON *array, int index )
581 {
582 cJSON *item = array->child;
583 while (item != NULL && index > 0)
584 item = item->next, --index;
585 return item;
586 }
cJSON_GetObjectItem(cJSON * object,const char * string)587 cJSON *cJSON_GetObjectItem( cJSON *object, const char *string)
588 {
589 cJSON *item=object->child;
590 while (item != NULL && cJSON_strcasecmp(item->string, string) != 0)
591 item = item->next;
592 return item;
593 }
594
cJSON_CreateOrGetObjectItem(cJSON * object,const char * string)595 cJSON *cJSON_CreateOrGetObjectItem( cJSON *object, const char *string )
596 {
597 cJSON *child = cJSON_GetObjectItem(object, string);
598 if (child == NULL)
599 cJSON_AddItemToObject(object, string, child = cJSON_CreateNull());
600
601 return child;
602 }
603
604 // Utility for array list handling.
suffix_object(cJSON * prev,cJSON * item)605 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
606
607 // Add item to array/object.
cJSON_AddItemToArray(cJSON * array,cJSON * item)608 void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
cJSON_AddItemToObject(cJSON * object,const char * string,cJSON * item)609 void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
610
611 // remove all items from array/object
cJSON_ClearArray(cJSON * array)612 void cJSON_ClearArray( cJSON *array )
613 {
614 cJSON_Delete(array->child);
615 array->child = NULL;
616 }
617
618 // create basic types
619
cJSON_CreateNull(void)620 cJSON *cJSON_CreateNull( void )
621 {
622 return cJSON_NewItem(cJSON_NULL);
623 }
cJSON_CreateBoolean(bool value)624 cJSON *cJSON_CreateBoolean( bool value )
625 {
626 return cJSON_NewItem(value ? cJSON_True : cJSON_False);
627 }
cJSON_CreateNumber(double value)628 cJSON *cJSON_CreateNumber( double value )
629 {
630 cJSON *item = cJSON_NewItem(cJSON_Number);
631 item->valueint = item->valuedouble = value;
632 return item;
633 }
cJSON_CreateString(const char * value)634 cJSON *cJSON_CreateString( const char *value )
635 {
636 cJSON *item = cJSON_NewItem(cJSON_String);
637 item->valuestring = cJSON_strdup(value);
638 return item;
639 }
cJSON_CreateArray(void)640 cJSON *cJSON_CreateArray( void )
641 {
642 return cJSON_NewItem(cJSON_Array);
643 }
cJSON_CreateObject(void)644 cJSON *cJSON_CreateObject( void )
645 {
646 return cJSON_NewItem(cJSON_Object);
647 }
648
cJSON_ForceType(cJSON * item,cJSON_Type type)649 void cJSON_ForceType( cJSON *item, cJSON_Type type )
650 {
651 if (item->type != type)
652 {
653 cJSON_Delete(item->child);
654 item->child = NULL;
655
656 item->type = type;
657 }
658 }
659
cJSON_SetBoolean(cJSON * item,bool value)660 void cJSON_SetBoolean( cJSON *item, bool value )
661 {
662 cJSON_ForceType(item, value ? cJSON_True : cJSON_False);
663 }
cJSON_SetNumber(cJSON * item,double value)664 void cJSON_SetNumber( cJSON *item, double value )
665 {
666 cJSON_ForceType(item, cJSON_Number);
667 item->valueint = item->valuedouble = value;
668 }
cJSON_SetString(cJSON * item,const char * value)669 void cJSON_SetString( cJSON *item, const char *value )
670 {
671 cJSON_ForceType(item, cJSON_String);
672 cJSON_free(item->valuestring);
673 item->valuestring = cJSON_strdup(value);
674 }
675
676 // Create Arrays:
cJSON_CreateIntArray(int * numbers,int count)677 cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateFloatArray(float * numbers,int count)678 cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateDoubleArray(double * numbers,int count)679 cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateStringArray(const char ** strings,int count)680 cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
681