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