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