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