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