xref: /iperf/src/cjson.c (revision faf335bb)
1 /*
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 
23 /* cJSON */
24 /* JSON parser in C. */
25 
26 #include <string.h>
27 #include <stdio.h>
28 #include <math.h>
29 #include <stdlib.h>
30 #include <float.h>
31 #include <limits.h>
32 #include <ctype.h>
33 #ifdef HAVE_STDINT_H
34 #include <stdint.h>
35 #endif
36 #include <sys/types.h>
37 #include "cjson.h"
38 
39 #ifndef LLONG_MAX
40 #define LLONG_MAX 9223372036854775807LL
41 #endif
42 #ifndef LLONG_MIN
43 #define LLONG_MIN (-LLONG_MAX - 1LL)
44 #endif
45 static const char *global_ep;
46 
47 const char *cJSON_GetErrorPtr(void) {return global_ep;}
48 
49 static int cJSON_strcasecmp(const char *s1,const char *s2)
50 {
51     if (!s1) return (s1==s2)?0:1;
52     if (!s2) return 1;
53     for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)	if(*s1 == 0)	return 0;
54     return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
55 }
56 
57 static void *(*cJSON_malloc)(size_t sz) = malloc;
58 static void (*cJSON_free)(void *ptr) = free;
59 
60 static char* cJSON_strdup(const char* str)
61 {
62       size_t len;
63       char* copy;
64 
65       len = strlen(str) + 1;
66       if (!(copy = (char*)cJSON_malloc(len))) return 0;
67       memcpy(copy,str,len);
68       return copy;
69 }
70 
71 void cJSON_InitHooks(cJSON_Hooks* hooks)
72 {
73     if (!hooks) { /* Reset hooks */
74         cJSON_malloc = malloc;
75         cJSON_free = free;
76         return;
77     }
78 
79 	cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
80 	cJSON_free	 = (hooks->free_fn)?hooks->free_fn:free;
81 }
82 
83 /* Internal constructor. */
84 static cJSON *cJSON_New_Item(void)
85 {
86 	cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
87 	if (node) memset(node,0,sizeof(cJSON));
88 	return node;
89 }
90 
91 /* Delete a cJSON structure. */
92 void cJSON_Delete(cJSON *c)
93 {
94 	cJSON *next;
95 	while (c)
96 	{
97 		next=c->next;
98 		if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
99 		if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
100 		if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string);
101 		cJSON_free(c);
102 		c=next;
103 	}
104 }
105 
106 /* Parse the input text to generate a number, and populate the result into item. */
107 static const char *parse_number(cJSON *item,const char *num)
108 {
109 	double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
110 
111 	if (*num=='-') sign=-1,num++;	/* Has sign? */
112 	if (*num=='0') num++;			/* is zero */
113 	if (*num>='1' && *num<='9')	do	n=(n*10.0)+(*num++ -'0');	while (*num>='0' && *num<='9');	/* Number? */
114 	if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;		do	n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}	/* Fractional part? */
115 	if (*num=='e' || *num=='E')		/* Exponent? */
116 	{	num++;if (*num=='+') num++;	else if (*num=='-') signsubscale=-1,num++;		/* With sign? */
117 		while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');	/* Number? */
118 	}
119 
120 	n=sign*n*pow(10.0,(scale+subscale*signsubscale));	/* number = +/- number.fraction * 10^+/- exponent */
121 
122 	item->valuedouble=n;
123 	item->valueint=(int64_t)n;
124 	item->type=cJSON_Number;
125 	return num;
126 }
127 
128 static int pow2gt (int x)	{	--x;	x|=x>>1;	x|=x>>2;	x|=x>>4;	x|=x>>8;	x|=x>>16;	return x+1;	}
129 
130 typedef struct {char *buffer; int length; int offset; } printbuffer;
131 
132 static char* ensure(printbuffer *p,int needed)
133 {
134 	char *newbuffer;int newsize;
135 	if (!p || !p->buffer) return 0;
136 	needed+=p->offset;
137 	if (needed<=p->length) return p->buffer+p->offset;
138 
139 	newsize=pow2gt(needed);
140 	newbuffer=(char*)cJSON_malloc(newsize);
141 	if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;}
142 	if (newbuffer) memcpy(newbuffer,p->buffer,p->length);
143 	cJSON_free(p->buffer);
144 	p->length=newsize;
145 	p->buffer=newbuffer;
146 	return newbuffer+p->offset;
147 }
148 
149 static int update(printbuffer *p)
150 {
151 	char *str;
152 	if (!p || !p->buffer) return 0;
153 	str=p->buffer+p->offset;
154 	return p->offset+strlen(str);
155 }
156 
157 /* Render the number nicely from the given item into a string. */
158 static char *print_number(cJSON *item,printbuffer *p)
159 {
160 	char *str=0;
161 	double d=item->valuedouble;
162 	if (d==0)
163 	{
164 		if (p)	str=ensure(p,2);
165 		else	str=(char*)cJSON_malloc(2);	/* special case for 0. */
166 		if (str) strcpy(str,"0");
167 	}
168 	else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=LLONG_MAX && d>=LLONG_MIN)
169 	{
170 		if (p)	str=ensure(p,64);
171 		else	str=(char*)cJSON_malloc(64);
172 		if (str)	sprintf(str,"%lld",(long long) item->valueint);
173 	}
174 	else
175 	{
176 		if (p)	str=ensure(p,64);
177 		else	str=(char*)cJSON_malloc(64);	/* This is a nice tradeoff. */
178 		if (str)
179 		{
180 			if (fpclassify(d) != FP_ZERO && !isnormal(d))				sprintf(str,"null");
181 			else if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)	sprintf(str,"%.0f",d);
182 			else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)					sprintf(str,"%e",d);
183 			else														sprintf(str,"%f",d);
184 		}
185 	}
186 	return str;
187 }
188 
189 static unsigned parse_hex4(const char *str)
190 {
191 	unsigned h=0;
192 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
193 	h=h<<4;str++;
194 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
195 	h=h<<4;str++;
196 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
197 	h=h<<4;str++;
198 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
199 	return h;
200 }
201 
202 /* Parse the input text into an unescaped cstring, and populate item. */
203 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
204 static const char *parse_string(cJSON *item,const char *str,const char **ep)
205 {
206 	const char *ptr,*end_ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
207 	if (*str!='\"') {*ep=str;return 0;}	/* not a string! */
208 
209 	while (*end_ptr!='\"' && *end_ptr && ++len)
210 	{
211 	    if (*end_ptr++ == '\\')
212 	    {
213 		if (*end_ptr == '\0')
214 		{
215 		    /* prevent buffer overflow when last input character is a backslash */
216 		    return 0;
217 		}
218 		end_ptr++;	/* Skip escaped quotes. */
219 	    }
220 	}
221 
222 	out=(char*)cJSON_malloc(len+1);	/* This is how long we need for the string, roughly. */
223 	if (!out) return 0;
224 	item->valuestring=out; /* assign here so out will be deleted during cJSON_Delete() later */
225 	item->type=cJSON_String;
226 
227 	ptr=str+1;ptr2=out;
228 	while (ptr < end_ptr)
229 	{
230 		if (*ptr!='\\') *ptr2++=*ptr++;
231 		else
232 		{
233 			ptr++;
234 			switch (*ptr)
235 			{
236 				case 'b': *ptr2++='\b';	break;
237 				case 'f': *ptr2++='\f';	break;
238 				case 'n': *ptr2++='\n';	break;
239 				case 'r': *ptr2++='\r';	break;
240 				case 't': *ptr2++='\t';	break;
241 				case 'u':	 /* transcode utf16 to utf8. */
242 					uc=parse_hex4(ptr+1);ptr+=4;	/* get the unicode char. */
243 					if (ptr >= end_ptr) {*ep=str;return 0;}	/* invalid */
244 
245 					if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)    {*ep=str;return 0;}	/* check for invalid.   */
246 
247 					if (uc>=0xD800 && uc<=0xDBFF)	/* UTF16 surrogate pairs.	*/
248 					{
249 						if (ptr+6 > end_ptr)    {*ep=str;return 0;}	/* invalid */
250 						if (ptr[1]!='\\' || ptr[2]!='u')    {*ep=str;return 0;}	/* missing second-half of surrogate.    */
251 						uc2=parse_hex4(ptr+3);ptr+=6;
252 						if (uc2<0xDC00 || uc2>0xDFFF)       {*ep=str;return 0;}	/* invalid second-half of surrogate.    */
253 						uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
254 					}
255 
256 					len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
257 
258 					switch (len) {
259 						case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
260 						case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
261 						case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
262 						case 1: *--ptr2 =(uc | firstByteMark[len]);
263 					}
264 					ptr2+=len;
265 					break;
266 				default:  *ptr2++=*ptr; break;
267 			}
268 			ptr++;
269 		}
270 	}
271 	*ptr2=0;
272 	if (*ptr=='\"') ptr++;
273 	return ptr;
274 }
275 
276 /* Render the cstring provided to an escaped version that can be printed. */
277 static char *print_string_ptr(const char *str,printbuffer *p)
278 {
279 	const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token;
280 
281 	if (!str)
282 	{
283 		if (p)	out=ensure(p,3);
284 		else	out=(char*)cJSON_malloc(3);
285 		if (!out) return 0;
286 		strcpy(out,"\"\"");
287 		return out;
288 	}
289 
290 	for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0;
291 	if (!flag)
292 	{
293 		len=ptr-str;
294 		if (p) out=ensure(p,len+3);
295 		else		out=(char*)cJSON_malloc(len+3);
296 		if (!out) return 0;
297 		ptr2=out;*ptr2++='\"';
298 		strcpy(ptr2,str);
299 		ptr2[len]='\"';
300 		ptr2[len+1]=0;
301 		return out;
302 	}
303 
304 	ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
305 
306 	if (p)	out=ensure(p,len+3);
307 	else	out=(char*)cJSON_malloc(len+3);
308 	if (!out) return 0;
309 
310 	ptr2=out;ptr=str;
311 	*ptr2++='\"';
312 	while (*ptr)
313 	{
314 		if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
315 		else
316 		{
317 			*ptr2++='\\';
318 			switch (token=*ptr++)
319 			{
320 				case '\\':	*ptr2++='\\';	break;
321 				case '\"':	*ptr2++='\"';	break;
322 				case '\b':	*ptr2++='b';	break;
323 				case '\f':	*ptr2++='f';	break;
324 				case '\n':	*ptr2++='n';	break;
325 				case '\r':	*ptr2++='r';	break;
326 				case '\t':	*ptr2++='t';	break;
327 				default: sprintf(ptr2,"u%04x",token);ptr2+=5;	break;	/* escape and print */
328 			}
329 		}
330 	}
331 	*ptr2++='\"';*ptr2++=0;
332 	return out;
333 }
334 /* Invote print_string_ptr (which is useful) on an item. */
335 static char *print_string(cJSON *item,printbuffer *p)	{return print_string_ptr(item->valuestring,p);}
336 
337 /* Predeclare these prototypes. */
338 static const char *parse_value(cJSON *item,const char *value,const char **ep);
339 static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p);
340 static const char *parse_array(cJSON *item,const char *value,const char **ep);
341 static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p);
342 static const char *parse_object(cJSON *item,const char *value,const char **ep);
343 static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p);
344 
345 /* Utility to jump whitespace and cr/lf */
346 static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
347 
348 /* Parse an object - create a new root, and populate. */
349 cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
350 {
351 	const char *end=0,**ep=return_parse_end?return_parse_end:&global_ep;
352 	cJSON *c=cJSON_New_Item();
353 	*ep=0;
354 	if (!c) return 0;       /* memory fail */
355 
356 	end=parse_value(c,skip(value),ep);
357 	if (!end)	{cJSON_Delete(c);return 0;}	/* parse failure. ep is set. */
358 
359 	/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
360 	if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);*ep=end;return 0;}}
361 	if (return_parse_end) *return_parse_end=end;
362 	return c;
363 }
364 /* Default options for cJSON_Parse */
365 cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
366 
367 /* Render a cJSON item/entity/structure to text. */
368 char *cJSON_Print(cJSON *item)				{return print_value(item,0,1,0);}
369 char *cJSON_PrintUnformatted(cJSON *item)	{return print_value(item,0,0,0);}
370 
371 char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt)
372 {
373 	printbuffer p;
374 	p.buffer=(char*)cJSON_malloc(prebuffer);
375 	p.length=prebuffer;
376 	p.offset=0;
377 	return print_value(item,0,fmt,&p);
378 }
379 
380 
381 /* Parser core - when encountering text, process appropriately. */
382 static const char *parse_value(cJSON *item,const char *value,const char **ep)
383 {
384 	if (!value)						return 0;	/* Fail on null. */
385 	if (!strncmp(value,"null",4))	{ item->type=cJSON_NULL;  return value+4; }
386 	if (!strncmp(value,"false",5))	{ item->type=cJSON_False; return value+5; }
387 	if (!strncmp(value,"true",4))	{ item->type=cJSON_True; item->valueint=1;	return value+4; }
388 	if (*value=='\"')				{ return parse_string(item,value,ep); }
389 	if (*value=='-' || (*value>='0' && *value<='9'))	{ return parse_number(item,value); }
390 	if (*value=='[')				{ return parse_array(item,value,ep); }
391 	if (*value=='{')				{ return parse_object(item,value,ep); }
392 
393 	*ep=value;return 0;	/* failure. */
394 }
395 
396 /* Render a value to text. */
397 static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p)
398 {
399 	char *out=0;
400 	if (!item) return 0;
401 	if (p)
402 	{
403 		switch ((item->type)&255)
404 		{
405 			case cJSON_NULL:	{out=ensure(p,5);	if (out) strcpy(out,"null");	break;}
406 			case cJSON_False:	{out=ensure(p,6);	if (out) strcpy(out,"false");	break;}
407 			case cJSON_True:	{out=ensure(p,5);	if (out) strcpy(out,"true");	break;}
408 			case cJSON_Number:	out=print_number(item,p);break;
409 			case cJSON_String:	out=print_string(item,p);break;
410 			case cJSON_Array:	out=print_array(item,depth,fmt,p);break;
411 			case cJSON_Object:	out=print_object(item,depth,fmt,p);break;
412 		}
413 	}
414 	else
415 	{
416 		switch ((item->type)&255)
417 		{
418 			case cJSON_NULL:	out=cJSON_strdup("null");	break;
419 			case cJSON_False:	out=cJSON_strdup("false");break;
420 			case cJSON_True:	out=cJSON_strdup("true"); break;
421 			case cJSON_Number:	out=print_number(item,0);break;
422 			case cJSON_String:	out=print_string(item,0);break;
423 			case cJSON_Array:	out=print_array(item,depth,fmt,0);break;
424 			case cJSON_Object:	out=print_object(item,depth,fmt,0);break;
425 		}
426 	}
427 	return out;
428 }
429 
430 /* Build an array from input text. */
431 static const char *parse_array(cJSON *item,const char *value,const char **ep)
432 {
433 	cJSON *child;
434 	if (*value!='[')	{*ep=value;return 0;}	/* not an array! */
435 
436 	item->type=cJSON_Array;
437 	value=skip(value+1);
438 	if (*value==']') return value+1;	/* empty array. */
439 
440 	item->child=child=cJSON_New_Item();
441 	if (!item->child) return 0;		 /* memory fail */
442 	value=skip(parse_value(child,skip(value),ep));	/* skip any spacing, get the value. */
443 	if (!value) return 0;
444 
445 	while (*value==',')
446 	{
447 		cJSON *new_item;
448 		if (!(new_item=cJSON_New_Item())) return 0; 	/* memory fail */
449 		child->next=new_item;new_item->prev=child;child=new_item;
450 		value=skip(parse_value(child,skip(value+1),ep));
451 		if (!value) return 0;	/* memory fail */
452 	}
453 
454 	if (*value==']') return value+1;	/* end of array */
455 	*ep=value;return 0;	/* malformed. */
456 }
457 
458 /* Render an array to text */
459 static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p)
460 {
461 	char **entries;
462 	char *out=0,*ptr,*ret;int len=5;
463 	cJSON *child=item->child;
464 	int numentries=0,i=0,fail=0;
465 	size_t tmplen=0;
466 
467 	/* How many entries in the array? */
468 	while (child) numentries++,child=child->next;
469 	/* Explicitly handle numentries==0 */
470 	if (!numentries)
471 	{
472 		if (p)	out=ensure(p,3);
473 		else	out=(char*)cJSON_malloc(3);
474 		if (out) strcpy(out,"[]");
475 		return out;
476 	}
477 
478 	if (p)
479 	{
480 		/* Compose the output array. */
481 		i=p->offset;
482 		ptr=ensure(p,1);if (!ptr) return 0;	*ptr='[';	p->offset++;
483 		child=item->child;
484 		while (child && !fail)
485 		{
486 			print_value(child,depth+1,fmt,p);
487 			p->offset=update(p);
488 			if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;}
489 			child=child->next;
490 		}
491 		ptr=ensure(p,2);if (!ptr) return 0;	*ptr++=']';*ptr=0;
492 		out=(p->buffer)+i;
493 	}
494 	else
495 	{
496 		/* Allocate an array to hold the values for each */
497 		entries=(char**)cJSON_malloc(numentries*sizeof(char*));
498 		if (!entries) return 0;
499 		memset(entries,0,numentries*sizeof(char*));
500 		/* Retrieve all the results: */
501 		child=item->child;
502 		while (child && !fail)
503 		{
504 			ret=print_value(child,depth+1,fmt,0);
505 			entries[i++]=ret;
506 			if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
507 			child=child->next;
508 		}
509 
510 		/* If we didn't fail, try to malloc the output string */
511 		if (!fail)	out=(char*)cJSON_malloc(len);
512 		/* If that fails, we fail. */
513 		if (!out) fail=1;
514 
515 		/* Handle failure. */
516 		if (fail)
517 		{
518 			for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
519 			cJSON_free(entries);
520 			return 0;
521 		}
522 
523 		/* Compose the output array. */
524 		*out='[';
525 		ptr=out+1;*ptr=0;
526 		for (i=0;i<numentries;i++)
527 		{
528 			tmplen=strlen(entries[i]);memcpy(ptr,entries[i],tmplen);ptr+=tmplen;
529 			if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
530 			cJSON_free(entries[i]);
531 		}
532 		cJSON_free(entries);
533 		*ptr++=']';*ptr++=0;
534 	}
535 	return out;
536 }
537 
538 /* Build an object from the text. */
539 static const char *parse_object(cJSON *item,const char *value,const char **ep)
540 {
541 	cJSON *child;
542 	if (*value!='{')	{*ep=value;return 0;}	/* not an object! */
543 
544 	item->type=cJSON_Object;
545 	value=skip(value+1);
546 	if (*value=='}') return value+1;	/* empty array. */
547 
548 	item->child=child=cJSON_New_Item();
549 	if (!item->child) return 0;
550 	value=skip(parse_string(child,skip(value),ep));
551 	if (!value) return 0;
552 	child->string=child->valuestring;child->valuestring=0;
553 	if (*value!=':') {*ep=value;return 0;}	/* fail! */
554 	value=skip(parse_value(child,skip(value+1),ep));	/* skip any spacing, get the value. */
555 	if (!value) return 0;
556 
557 	while (*value==',')
558 	{
559 		cJSON *new_item;
560 		if (!(new_item=cJSON_New_Item()))	return 0; /* memory fail */
561 		child->next=new_item;new_item->prev=child;child=new_item;
562 		value=skip(parse_string(child,skip(value+1),ep));
563 		if (!value) return 0;
564 		child->string=child->valuestring;child->valuestring=0;
565 		if (*value!=':') {*ep=value;return 0;}	/* fail! */
566 		value=skip(parse_value(child,skip(value+1),ep));	/* skip any spacing, get the value. */
567 		if (!value) return 0;
568 	}
569 
570 	if (*value=='}') return value+1;	/* end of array */
571 	*ep=value;return 0;	/* malformed. */
572 }
573 
574 /* Render an object to text. */
575 static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p)
576 {
577 	char **entries=0,**names=0;
578 	char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
579 	cJSON *child=item->child;
580 	int numentries=0,fail=0;
581 	size_t tmplen=0;
582 	/* Count the number of entries. */
583 	while (child) numentries++,child=child->next;
584 	/* Explicitly handle empty object case */
585 	if (!numentries)
586 	{
587 		if (p) out=ensure(p,fmt?depth+4:3);
588 		else	out=(char*)cJSON_malloc(fmt?depth+4:3);
589 		if (!out)	return 0;
590 		ptr=out;*ptr++='{';
591 		if (fmt) {*ptr++='\n';for (i=0;i<depth;i++) *ptr++='\t';}
592 		*ptr++='}';*ptr++=0;
593 		return out;
594 	}
595 	if (p)
596 	{
597 		/* Compose the output: */
598 		i=p->offset;
599 		len=fmt?2:1;	ptr=ensure(p,len+1);	if (!ptr) return 0;
600 		*ptr++='{';	if (fmt) *ptr++='\n';	*ptr=0;	p->offset+=len;
601 		child=item->child;depth++;
602 		while (child)
603 		{
604 			if (fmt)
605 			{
606 				ptr=ensure(p,depth);	if (!ptr) return 0;
607 				for (j=0;j<depth;j++) *ptr++='\t';
608 				p->offset+=depth;
609 			}
610 			print_string_ptr(child->string,p);
611 			p->offset=update(p);
612 
613 			len=fmt?2:1;
614 			ptr=ensure(p,len);	if (!ptr) return 0;
615 			*ptr++=':';if (fmt) *ptr++='\t';
616 			p->offset+=len;
617 
618 			print_value(child,depth,fmt,p);
619 			p->offset=update(p);
620 
621 			len=(fmt?1:0)+(child->next?1:0);
622 			ptr=ensure(p,len+1); if (!ptr) return 0;
623 			if (child->next) *ptr++=',';
624 			if (fmt) *ptr++='\n';
625 			*ptr=0;
626 			p->offset+=len;
627 			child=child->next;
628 		}
629 		ptr=ensure(p,fmt?(depth+1):2);	 if (!ptr) return 0;
630 		if (fmt)	for (i=0;i<depth-1;i++) *ptr++='\t';
631 		*ptr++='}';*ptr=0;
632 		out=(p->buffer)+i;
633 	}
634 	else
635 	{
636 		/* Allocate space for the names and the objects */
637 		entries=(char**)cJSON_malloc(numentries*sizeof(char*));
638 		if (!entries) return 0;
639 		names=(char**)cJSON_malloc(numentries*sizeof(char*));
640 		if (!names) {cJSON_free(entries);return 0;}
641 		memset(entries,0,sizeof(char*)*numentries);
642 		memset(names,0,sizeof(char*)*numentries);
643 
644 		/* Collect all the results into our arrays: */
645 		child=item->child;depth++;if (fmt) len+=depth;
646 		while (child && !fail)
647 		{
648 			names[i]=str=print_string_ptr(child->string,0);
649 			entries[i++]=ret=print_value(child,depth,fmt,0);
650 			if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
651 			child=child->next;
652 		}
653 
654 		/* Try to allocate the output string */
655 		if (!fail)	out=(char*)cJSON_malloc(len);
656 		if (!out) fail=1;
657 
658 		/* Handle failure */
659 		if (fail)
660 		{
661 			for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
662 			cJSON_free(names);cJSON_free(entries);
663 			return 0;
664 		}
665 
666 		/* Compose the output: */
667 		*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
668 		for (i=0;i<numentries;i++)
669 		{
670 			if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
671 			tmplen=strlen(names[i]);memcpy(ptr,names[i],tmplen);ptr+=tmplen;
672 			*ptr++=':';if (fmt) *ptr++='\t';
673 			strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
674 			if (i!=numentries-1) *ptr++=',';
675 			if (fmt) *ptr++='\n';
676 			*ptr=0;
677 			cJSON_free(names[i]);cJSON_free(entries[i]);
678 		}
679 
680 		cJSON_free(names);cJSON_free(entries);
681 		if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
682 		*ptr++='}';*ptr++=0;
683 	}
684 	return out;
685 }
686 
687 /* Get Array size/item / object item. */
688 int    cJSON_GetArraySize(cJSON *array)							{cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
689 cJSON *cJSON_GetArrayItem(cJSON *array,int item)				{cJSON *c=array?array->child:0;while (c && item>0) item--,c=c->next; return c;}
690 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)	{cJSON *c=object?object->child:0;while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
691 int cJSON_HasObjectItem(cJSON *object,const char *string)		{return cJSON_GetObjectItem(object,string)?1:0;}
692 
693 /* Utility for array list handling. */
694 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
695 /* Utility for handling references. */
696 static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
697 
698 /* Add item to array/object. */
699 void   cJSON_AddItemToArray(cJSON *array, cJSON *item)						{cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
700 void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)	{if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
701 void   cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item)	{if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);}
702 void	cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)						{cJSON_AddItemToArray(array,create_reference(item));}
703 void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)	{cJSON_AddItemToObject(object,string,create_reference(item));}
704 
705 cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)			{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
706 	if (c->prev) {c->prev->next=c->next;}if (c->next) {c->next->prev=c->prev;}if (c==array->child) {array->child=c->next;} c->prev=c->next=0;return c;}
707 void   cJSON_DeleteItemFromArray(cJSON *array,int which)			{cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
708 cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
709 void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
710 
711 /* Replace array/object items with new ones. */
712 void   cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;}
713 	newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;}
714 void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
715 	newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
716 	if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
717 void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
718 
719 /* Create basic types: */
720 cJSON *cJSON_CreateNull(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
721 cJSON *cJSON_CreateTrue(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
722 cJSON *cJSON_CreateFalse(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
723 cJSON *cJSON_CreateBool(int b)					{cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
724 cJSON *cJSON_CreateNumber(double num)			{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int64_t)num;}return item;}
725 cJSON *cJSON_CreateString(const char *string)	{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);if(!item->valuestring){cJSON_Delete(item);return 0;}}return item;}
726 cJSON *cJSON_CreateArray(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
727 cJSON *cJSON_CreateObject(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
728 
729 /* Create Arrays: */
730 cJSON *cJSON_CreateIntArray(const int *numbers,int count)		{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
731 cJSON *cJSON_CreateFloatArray(const float *numbers,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
732 cJSON *cJSON_CreateDoubleArray(const double *numbers,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
733 cJSON *cJSON_CreateStringArray(const char **strings,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
734 
735 /* Duplication */
736 cJSON *cJSON_Duplicate(cJSON *item,int recurse)
737 {
738 	cJSON *newitem,*cptr,*nptr=0,*newchild;
739 	/* Bail on bad ptr */
740 	if (!item) return 0;
741 	/* Create new item */
742 	newitem=cJSON_New_Item();
743 	if (!newitem) return 0;
744 	/* Copy over all vars */
745 	newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
746 	if (item->valuestring)	{newitem->valuestring=cJSON_strdup(item->valuestring);	if (!newitem->valuestring)	{cJSON_Delete(newitem);return 0;}}
747 	if (item->string)		{newitem->string=cJSON_strdup(item->string);			if (!newitem->string)		{cJSON_Delete(newitem);return 0;}}
748 	/* If non-recursive, then we're done! */
749 	if (!recurse) return newitem;
750 	/* Walk the ->next chain for the child. */
751 	cptr=item->child;
752 	while (cptr)
753 	{
754 		newchild=cJSON_Duplicate(cptr,1);		/* Duplicate (with recurse) each item in the ->next chain */
755 		if (!newchild) {cJSON_Delete(newitem);return 0;}
756 		if (nptr)	{nptr->next=newchild,newchild->prev=nptr;nptr=newchild;}	/* If newitem->child already set, then crosswire ->prev and ->next and move on */
757 		else		{newitem->child=newchild;nptr=newchild;}					/* Set newitem->child and move to it */
758 		cptr=cptr->next;
759 	}
760 	return newitem;
761 }
762 
763 void cJSON_Minify(char *json)
764 {
765 	char *into=json;
766 	while (*json)
767 	{
768 		if (*json==' ') json++;
769 		else if (*json=='\t') json++;	/* Whitespace characters. */
770 		else if (*json=='\r') json++;
771 		else if (*json=='\n') json++;
772 		else if (*json=='/' && json[1]=='/')  while (*json && *json!='\n') json++;	/* double-slash comments, to end of line. */
773 		else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;}	/* multiline comments. */
774 		else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */
775 		else *into++=*json++;			/* All other characters. */
776 	}
777 	*into=0;	/* and null-terminate. */
778 }
779