| #include <string.h> | 
 | #include <stdio.h> | 
 | #include <math.h> | 
 | #include <stdlib.h> | 
 | #include <float.h> | 
 | #include <limits.h> | 
 | #include <ctype.h> | 
 | #include "zte_web_cjson.h" | 
 |  | 
 |  | 
 | static const char *parse_value(cJSON *item, const char *value); | 
 | static char *print_value(cJSON *item, int depth, int fmt); | 
 | static const char *parse_array(cJSON *item, const char *value); | 
 | static char *print_array(cJSON *item, int depth, int fmt); | 
 | static const char *parse_object(cJSON *item, const char *value); | 
 | static char *print_object(cJSON *item, int depth, int fmt); | 
 |  | 
 | static const char *ep; | 
 |  | 
 | static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; | 
 |  | 
 |  | 
 | const char *cJSON_GetErrorPtr(void) | 
 | { | 
 | 	return ep; | 
 | } | 
 |  | 
 | static int cJSON_strcasecmp(const char *s1, const char *s2) | 
 | { | 
 | 	if (!s1) return (s1 == s2) ? 0 : 1; | 
 | 	if (!s2) return 1; | 
 | 	for (; tolower(*s1) == tolower(*s2); ++s1, ++s2)	if (*s1 == 0)	return 0; | 
 | 	return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); | 
 | } | 
 |  | 
 | static void *(*cJSON_malloc)(size_t sz) = malloc; | 
 | static void (*cJSON_free)(void *ptr) = free; | 
 |  | 
 | static const char *skip(const char *in) | 
 | { | 
 | 	while (in && *in && (unsigned char)*in <= 32) in++; | 
 | 	return in; | 
 | } | 
 |  | 
 | static char* cJSON_strdup(const char* str) | 
 | { | 
 | 	size_t len; | 
 | 	char* str_cpy; | 
 |  | 
 | 	len = strlen(str) + 1; | 
 | 	if (!(str_cpy = (char*)cJSON_malloc(len))) return 0; | 
 | 	memcpy(str_cpy, str, len); | 
 | 	return str_cpy; | 
 | } | 
 |  | 
 | void cJSON_InitHooks(cJSON_Hooks* hooks) | 
 | { | 
 | 	if (!hooks) { /*hooks reset*/ | 
 | 		cJSON_malloc = malloc; | 
 | 		cJSON_free = free; | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc; | 
 | 	cJSON_free	 = (hooks->free_fn) ? hooks->free_fn : free; | 
 | } | 
 |  | 
 | static cJSON *cJSON_New_Item(void) | 
 | { | 
 | 	cJSON* inode = (cJSON*)cJSON_malloc(sizeof(cJSON)); | 
 | 	if (inode) memset(inode, 0, sizeof(cJSON)); | 
 | 	return inode; | 
 | } | 
 |  | 
 | void cJSON_Delete(cJSON *c) | 
 | { | 
 | 	cJSON *next_node; | 
 | 	while (c) { | 
 | 		next_node = c->next; | 
 | 		if (!(c->type & cJSON_IsReference) && c->child) cJSON_Delete(c->child); | 
 | 		if (!(c->type & cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); | 
 | 		if (c->string) cJSON_free(c->string); | 
 | 		cJSON_free(c); | 
 | 		c = next_node; | 
 | 	} | 
 | } | 
 |  | 
 | static const char *parse_number(cJSON *item, const char *num) | 
 | { | 
 | 	int subscale = 0, signsubscale = 1; | 
 |  | 
 | 	double inum = 0, sign = 1, scale = 0; | 
 | 	 | 
 | 	if (*num == '-') sign = -1, num++; | 
 | 	if (*num == '0') num++; | 
 | 	if (*num >= '1' && *num <= '9')	do	inum = (inum * 10.0) + (*num++ -'0'); | 
 | 		while (*num >= '0' && *num <= '9'); | 
 | 	if (*num == '.' && num[1] >= '0' && num[1] <= '9') { | 
 | 		num++; | 
 | 		do	inum = (inum * 10.0) + (*num++ -'0'), scale--; | 
 | 		while (*num >= '0' && *num <= '9'); | 
 | 	} | 
 | 	if (*num == 'e' || *num == 'E') { | 
 | 		num++; | 
 | 		if (*num == '+') num++; | 
 | 		else if (*num == '-') signsubscale = -1, num++; | 
 | 		while (*num >= '0' && *num <= '9') subscale = (subscale * 10) + (*num++ - '0'); | 
 | 	} | 
 |  | 
 | 	inum = sign * inum * pow(10.0, (scale + subscale * signsubscale)); | 
 |  | 
 | 	item->valuedouble = inum; | 
 | 	item->valueint = (int)inum; | 
 | 	item->type = cJSON_Number; | 
 | 	return num; | 
 | } | 
 |  | 
 | static char *print_number(cJSON *item) | 
 | { | 
 | 	double d = item->valuedouble; | 
 |  | 
 | 	char *str; | 
 | 	 | 
 | 	if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) { | 
 | 		str = (char*)cJSON_malloc(21);	/* 2^64+1 can be represented in 21 chars. */ | 
 | 		if (str) sprintf(str, "%d", item->valueint); | 
 | 	} else { | 
 | 		str = (char*)cJSON_malloc(64); | 
 | 		if (str) { | 
 | 			if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)sprintf(str, "%.0f", d); | 
 | 			else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9)			sprintf(str, "%e", d); | 
 | 			else												sprintf(str, "%f", d); | 
 | 		} | 
 | 	} | 
 | 	return str; | 
 | } | 
 |  | 
 | static unsigned parse_hex4(const char *str) | 
 | { | 
 | 	unsigned hex = 0; | 
 | 	if (*str >= '0' && *str <= '9')  | 
 | 		hex += (*str) - '0'; | 
 | 	else if (*str >= 'A' && *str <= 'F')  | 
 | 		hex += 10 + (*str) - 'A'; | 
 | 	else if (*str >= 'a' && *str <= 'f')  | 
 | 		hex += 10 + (*str) - 'a'; | 
 | 	else  | 
 | 		return 0; | 
 | 	hex = hex << 4; | 
 | 	str++; | 
 | 	if (*str >= '0' && *str <= '9')  | 
 | 		hex += (*str) - '0'; | 
 | 	else if (*str >= 'A' && *str <= 'F')  | 
 | 		hex += 10 + (*str) - 'A'; | 
 | 	else if (*str >= 'a' && *str <= 'f')  | 
 | 		hex += 10 + (*str) - 'a'; | 
 | 	else  | 
 | 		return 0; | 
 | 	hex = hex << 4; | 
 | 	str++; | 
 | 	if (*str >= '0' && *str <= '9')  | 
 | 		hex += (*str) - '0'; | 
 | 	else if (*str >= 'A' && *str <= 'F')  | 
 | 		hex += 10 + (*str) - 'A'; | 
 | 	else if (*str >= 'a' && *str <= 'f')  | 
 | 		hex += 10 + (*str) - 'a'; | 
 | 	else  | 
 | 		return 0; | 
 | 	hex = hex << 4; | 
 | 	str++; | 
 | 	if (*str >= '0' && *str <= '9')  | 
 | 		hex += (*str) - '0'; | 
 | 	else if (*str >= 'A' && *str <= 'F')  | 
 | 		hex += 10 + (*str) - 'A'; | 
 | 	else if (*str >= 'a' && *str <= 'f')  | 
 | 		hex += 10 + (*str) - 'a'; | 
 | 	else  | 
 | 		return 0; | 
 | 	return hex; | 
 | } | 
 |  | 
 | static const char *parse_string(cJSON *item, const char *str) | 
 | { | 
 | 	const char *pstr = str + 1; | 
 | 	char *pstr2; | 
 | 	char *out; | 
 | 	int len = 0; | 
 | 	unsigned uc, uc2; | 
 | 	if (*str != '\"') { | 
 | 		ep = str;    /* not a string! */ | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	while (*pstr != '\"' && *pstr && ++len) if (*pstr++ == '\\') pstr++;	/* Skip escaped quotes. */ | 
 |  | 
 | 	out = (char*)cJSON_malloc(len + 1);	/* This is how long we need for the string, roughly. */ | 
 | 	if (!out) return 0; | 
 |  | 
 | 	pstr = str + 1; | 
 | 	pstr2 = out; | 
 | 	while (*pstr != '\"' && *pstr) { | 
 | 		if (*pstr != '\\') *pstr2++ = *pstr++; | 
 | 		else { | 
 | 			pstr++; | 
 | 			switch (*pstr) { | 
 | 			case 'b': | 
 | 				*pstr2++ = '\b'; | 
 | 				break; | 
 | 			case 'f': | 
 | 				*pstr2++ = '\f'; | 
 | 				break; | 
 | 			case 'n': | 
 | 				*pstr2++ = '\n'; | 
 | 				break; | 
 | 			case 'r': | 
 | 				*pstr2++ = '\r'; | 
 | 				break; | 
 | 			case 't': | 
 | 				*pstr2++ = '\t'; | 
 | 				break; | 
 | 			case 'u': | 
 | 				uc = parse_hex4(pstr + 1); | 
 | 				pstr += 4; | 
 |  | 
 | 				if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) | 
 | 					break; | 
 |  | 
 | 				if (uc >= 0xD800 && uc <= 0xDBFF) { | 
 | 					if (pstr[1] != '\\' || pstr[2] != 'u') | 
 | 						break; | 
 | 					uc2 = parse_hex4(pstr + 3); | 
 | 					pstr += 6; | 
 | 					if (uc2 < 0xDC00 || uc2 > 0xDFFF) | 
 | 						break; | 
 | 					uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF)); | 
 | 				} | 
 |  | 
 | 				len = 4; | 
 | 				if (uc < 0x80) len = 1; | 
 | 				else if (uc < 0x800) len = 2; | 
 | 				else if (uc < 0x10000) len = 3; | 
 | 				pstr2 += len; | 
 |  | 
 | 				switch (len) { | 
 | 				case 4: | 
 | 					*--pstr2 = ((uc | 0x80) & 0xBF); | 
 | 					uc >>= 6; | 
 | 				case 3: | 
 | 					*--pstr2 = ((uc | 0x80) & 0xBF); | 
 | 					uc >>= 6; | 
 | 				case 2: | 
 | 					*--pstr2 = ((uc | 0x80) & 0xBF); | 
 | 					uc >>= 6; | 
 | 				case 1: | 
 | 					*--pstr2 = (uc | firstByteMark[len]); | 
 | 				} | 
 | 				pstr2 += len; | 
 | 				break; | 
 | 			default: | 
 | 				*pstr2++ = *pstr; | 
 | 				break; | 
 | 			} | 
 | 			pstr++; | 
 | 		} | 
 | 	} | 
 | 	*pstr2 = 0; | 
 | 	if (*pstr == '\"') pstr++; | 
 | 	item->valuestring = out; | 
 | 	item->type = cJSON_String; | 
 | 	return pstr; | 
 | } | 
 |  | 
 | static char *print_string_ptr(const char *str) | 
 | { | 
 | 	const char *pstr; | 
 | 	char *pstr2, *out; | 
 | 	int len = 0; | 
 | 	unsigned char token; | 
 |  | 
 | 	if (!str) return cJSON_strdup(""); | 
 | 	pstr = str; | 
 | 	while ((token = *pstr) && ++len) { | 
 | 		if (strchr("\"\\\b\f\n\r\t", token)) len++; | 
 | 		else if (token < 32) len += 5; | 
 | 		pstr++; | 
 | 	} | 
 |  | 
 | 	out = (char*)cJSON_malloc(len + 3); | 
 | 	if (!out) return 0; | 
 |  | 
 | 	pstr2 = out; | 
 | 	pstr = str; | 
 | 	*pstr2++ = '\"'; | 
 | 	while (*pstr) { | 
 | 		if ((unsigned char)*pstr > 31 && *pstr != '\"' && *pstr != '\\') *pstr2++ = *pstr++; | 
 | 		else { | 
 | 			*pstr2++ = '\\'; | 
 | 			switch (token = *pstr++) { | 
 | 			case '\\': | 
 | 				*pstr2++ = '\\'; | 
 | 				break; | 
 | 			case '\"': | 
 | 				*pstr2++ = '\"'; | 
 | 				break; | 
 | 			case '\b': | 
 | 				*pstr2++ = 'b'; | 
 | 				break; | 
 | 			case '\f': | 
 | 				*pstr2++ = 'f'; | 
 | 				break; | 
 | 			case '\n': | 
 | 				*pstr2++ = 'n'; | 
 | 				break; | 
 | 			case '\r': | 
 | 				*pstr2++ = 'r'; | 
 | 				break; | 
 | 			case '\t': | 
 | 				*pstr2++ = 't'; | 
 | 				break; | 
 | 			default: | 
 | 				sprintf(pstr2, "u%04x", token); | 
 | 				pstr2 += 5; | 
 | 				break; | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	*pstr2++ = '\"'; | 
 | 	*pstr2++ = 0; | 
 | 	return out; | 
 | } | 
 |  | 
 | static char *print_string(cJSON *item) | 
 | { | 
 | 	return print_string_ptr(item->valuestring); | 
 | } | 
 |  | 
 | cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int require_null_terminated) | 
 | { | 
 | 	const char *str_end = 0; | 
 | 	cJSON *c = cJSON_New_Item(); | 
 | 	ep = 0; | 
 | 	if (!c)  | 
 | 		return 0; | 
 |  | 
 | 	str_end = parse_value(c, skip(value)); | 
 | 	if (!str_end)	{ | 
 | 		cJSON_Delete(c);     | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	if (require_null_terminated) { | 
 | 		str_end = skip(str_end); | 
 | 		if (*str_end) { | 
 | 			cJSON_Delete(c); | 
 | 			ep = str_end; | 
 | 			return 0; | 
 | 		} | 
 | 	} | 
 | 	if (return_parse_end) *return_parse_end = str_end; | 
 | 	return c; | 
 | } | 
 |  | 
 | cJSON *cJSON_Parse(const char *value) | 
 | { | 
 | 	return cJSON_ParseWithOpts(value, 0, 0); | 
 | } | 
 | char *cJSON_Print(cJSON *item) | 
 | { | 
 | 	return print_value(item, 0, 1); | 
 | } | 
 | char *cJSON_PrintUnformatted(cJSON *item) | 
 | { | 
 | 	return print_value(item, 0, 0); | 
 | } | 
 |  | 
 | static const char *parse_value(cJSON *item, const char *value) | 
 | { | 
 | 	if (!value)						 | 
 | 		return 0; | 
 | 	if (!strncmp(value, "null", 4))	{ | 
 | 		item->type = cJSON_NULL; | 
 | 		return value + 4; | 
 | 	} | 
 | 	if (!strncmp(value, "false", 5))	{ | 
 | 		item->type = cJSON_False; | 
 | 		return value + 5; | 
 | 	} | 
 | 	if (!strncmp(value, "true", 4))	{ | 
 | 		item->type = cJSON_True; | 
 | 		item->valueint = 1; | 
 | 		return value + 4; | 
 | 	} | 
 | 	if (*value == '\"')				{ | 
 | 		return parse_string(item, value); | 
 | 	} | 
 | 	if (*value == '-' || (*value >= '0' && *value <= '9'))	{ | 
 | 		return parse_number(item, value); | 
 | 	} | 
 | 	if (*value == '[')				{ | 
 | 		return parse_array(item, value); | 
 | 	} | 
 | 	if (*value == '{')				{ | 
 | 		return parse_object(item, value); | 
 | 	} | 
 |  | 
 | 	ep = value; | 
 | 	return 0; | 
 | } | 
 |  | 
 | static char *print_value(cJSON *item, int depth, int fmt) | 
 | { | 
 | 	char *item_value = 0; | 
 | 	if (!item)  | 
 | 		return 0; | 
 | 	switch ((item->type) & 255) { | 
 | 	case cJSON_NULL: | 
 | 		item_value = cJSON_strdup("null"); | 
 | 		break; | 
 | 	case cJSON_False: | 
 | 		item_value = cJSON_strdup("false"); | 
 | 		break; | 
 | 	case cJSON_True: | 
 | 		item_value = cJSON_strdup("true"); | 
 | 		break; | 
 | 	case cJSON_Number: | 
 | 		item_value = print_number(item); | 
 | 		break; | 
 | 	case cJSON_String: | 
 | 		item_value = print_string(item); | 
 | 		break; | 
 | 	case cJSON_Array: | 
 | 		item_value = print_array(item, depth, fmt); | 
 | 		break; | 
 | 	case cJSON_Object: | 
 | 		item_value = print_object(item, depth, fmt); | 
 | 		break; | 
 | 	} | 
 | 	return item_value; | 
 | } | 
 |  | 
 |  | 
 | static const char *parse_array(cJSON *item, const char *value) | 
 | { | 
 | 	cJSON *child; | 
 | 	if (*value != '[')	{ | 
 | 		ep = value; | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	item->type = cJSON_Array; | 
 | 	value = skip(value + 1); | 
 | 	if (*value == ']') return value + 1; | 
 |  | 
 | 	item->child = child = cJSON_New_Item(); | 
 | 	if (!item->child) return 0; | 
 | 	value = skip(parse_value(child, skip(value))); | 
 | 	if (!value) return 0; | 
 |  | 
 | 	while (*value == ',') { | 
 | 		cJSON *new_item; | 
 | 		if (!(new_item = cJSON_New_Item()))  | 
 | 			return 0; | 
 | 		child->next = new_item; | 
 | 		new_item->prev = child; | 
 | 		child = new_item; | 
 | 		value = skip(parse_value(child, skip(value + 1))); | 
 | 		if (!value)  | 
 | 			return 0; | 
 | 	} | 
 |  | 
 | 	if (*value == ']')  | 
 | 		return value + 1; | 
 | 	ep = value; | 
 | 	return 0; | 
 | } | 
 |  | 
 | static char *print_array(cJSON *item, int depth, int fmt) | 
 | { | 
 | 	char *oitem = 0, *pstr, *ret; | 
 | 	char **entries; | 
 | 	int len = 5; | 
 | 	int numentries = 0, i = 0, fail = 0; | 
 | 	cJSON *child = item->child; | 
 |  | 
 | 	while (child) numentries++, child = child->next; | 
 | 	 | 
 | 	if (!numentries) { | 
 | 		oitem = (char*)cJSON_malloc(3); | 
 | 		if (oitem)  | 
 | 			strcpy(oitem, "[]"); | 
 | 		return oitem; | 
 | 	} | 
 | 	 | 
 | 	entries = (char**)cJSON_malloc(numentries * sizeof(char*)); | 
 | 	if (!entries) return 0; | 
 | 	memset(entries, 0, numentries * sizeof(char*)); | 
 | 	 | 
 | 	child = item->child; | 
 | 	while (child && !fail) { | 
 | 		ret = print_value(child, depth + 1, fmt); | 
 | 		entries[i++] = ret; | 
 | 		if (ret) len += strlen(ret) + 2 + (fmt ? 1 : 0); | 
 | 		else fail = 1; | 
 | 		child = child->next; | 
 | 	} | 
 |  | 
 | 	 | 
 | 	if (!fail)  | 
 | 		oitem = (char*)cJSON_malloc(len); | 
 | 	 | 
 | 	if (!oitem)  | 
 | 		fail = 1; | 
 |  | 
 | 	 | 
 | 	if (fail) { | 
 | 		for (i = 0; i < numentries; i++) if (entries[i]) cJSON_free(entries[i]); | 
 | 		cJSON_free(entries); | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	 | 
 | 	*oitem = '['; | 
 | 	pstr = oitem + 1; | 
 | 	*pstr = 0; | 
 | 	for (i = 0; i < numentries; i++) { | 
 | 		strcpy(pstr, entries[i]); | 
 | 		pstr += strlen(entries[i]); | 
 | 		if (i != numentries - 1) { | 
 | 			*pstr++ = ','; | 
 | 			if (fmt)*pstr++ = ' '; | 
 | 			*pstr = 0; | 
 | 		} | 
 | 		cJSON_free(entries[i]); | 
 | 	} | 
 | 	cJSON_free(entries); | 
 | 	*pstr++ = ']'; | 
 | 	*pstr++ = 0; | 
 | 	return oitem; | 
 | } | 
 |  | 
 | static const char *parse_object(cJSON *item, const char *value) | 
 | { | 
 | 	cJSON *child; | 
 | 	if (*value != '{')	{ | 
 | 		ep = value; | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	item->type = cJSON_Object; | 
 | 	value = skip(value + 1); | 
 | 	if (*value == '}') return value + 1; | 
 |  | 
 | 	item->child = child = cJSON_New_Item(); | 
 | 	if (!item->child) return 0; | 
 | 	value = skip(parse_string(child, skip(value))); | 
 | 	if (!value) return 0; | 
 | 	child->string = child->valuestring; | 
 | 	child->valuestring = 0; | 
 | 	if (*value != ':') { | 
 | 		ep = value; | 
 | 		return 0; | 
 | 	} | 
 | 	value = skip(parse_value(child, skip(value + 1))); | 
 | 	if (!value) return 0; | 
 |  | 
 | 	while (*value == ',') { | 
 | 		cJSON *new_item; | 
 | 		if (!(new_item = cJSON_New_Item()))	return 0; | 
 | 		child->next = new_item; | 
 | 		new_item->prev = child; | 
 | 		child = new_item; | 
 | 		value = skip(parse_string(child, skip(value + 1))); | 
 | 		if (!value) return 0; | 
 | 		child->string = child->valuestring; | 
 | 		child->valuestring = 0; | 
 | 		if (*value != ':') { | 
 | 			ep = value; | 
 | 			return 0; | 
 | 		} | 
 | 		value = skip(parse_value(child, skip(value + 1))); | 
 | 		if (!value) return 0; | 
 | 	} | 
 |  | 
 | 	if (*value == '}') return value + 1; | 
 | 	ep = value; | 
 | 	return 0; | 
 | } | 
 |  | 
 | static char *print_object(cJSON *item, int depth, int fmt) | 
 | { | 
 | 	char *oitem = 0, *pstr, *ret, *str; | 
 | 	char **entries = 0, **names = 0; | 
 | 	int len = 7, i = 0, j; | 
 | 	int numentries = 0, fail = 0; | 
 | 	cJSON *child = item->child; | 
 | 	 | 
 | 	while (child) numentries++, child = child->next; | 
 | 	 | 
 | 	if (!numentries) { | 
 | 		oitem = (char*)cJSON_malloc(fmt ? depth + 4 : 3); | 
 | 		if (!oitem)	return 0; | 
 | 		pstr = oitem; | 
 | 		*pstr++ = '{'; | 
 | 		if (fmt) { | 
 | 			*pstr++ = '\n'; | 
 | 			for (i = 0; i < depth - 1; i++) *pstr++ = '\t'; | 
 | 		} | 
 | 		*pstr++ = '}'; | 
 | 		*pstr++ = 0; | 
 | 		return oitem; | 
 | 	} | 
 | 	 | 
 | 	entries = (char**)cJSON_malloc(numentries * sizeof(char*)); | 
 | 	if (!entries)  | 
 | 		return 0; | 
 | 	names = (char**)cJSON_malloc(numentries * sizeof(char*)); | 
 | 	if (!names) { | 
 | 		cJSON_free(entries); | 
 | 		return 0; | 
 | 	} | 
 | 	memset(entries, 0, sizeof(char*)*numentries); | 
 | 	memset(names, 0, sizeof(char*)*numentries); | 
 |  | 
 | 	 | 
 | 	child = item->child; | 
 | 	depth++; | 
 | 	if (fmt) len += depth; | 
 | 	while (child) { | 
 | 		names[i] = str = print_string_ptr(child->string); | 
 | 		entries[i++] = ret = print_value(child, depth, fmt); | 
 | 		if (str && ret)  | 
 | 			len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); | 
 | 		else  | 
 | 			fail = 1; | 
 | 		child = child->next; | 
 | 	} | 
 |  | 
 | 	 | 
 | 	if (!fail) oitem = (char*)cJSON_malloc(len); | 
 | 	if (!oitem) fail = 1; | 
 |  | 
 | 	 | 
 | 	if (fail) { | 
 | 		for (i = 0; i < numentries; i++) { | 
 | 			if (names[i]) cJSON_free(names[i]); | 
 | 			if (entries[i]) cJSON_free(entries[i]); | 
 | 		} | 
 | 		cJSON_free(names); | 
 | 		cJSON_free(entries); | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	 | 
 | 	*oitem = '{'; | 
 | 	pstr = oitem + 1; | 
 | 	if (fmt)*pstr++ = '\n'; | 
 | 	*pstr = 0; | 
 | 	for (i = 0; i < numentries; i++) { | 
 | 		if (fmt) for (j = 0; j < depth; j++) *pstr++ = '\t'; | 
 | 		strcpy(pstr, names[i]); | 
 | 		pstr += strlen(names[i]); | 
 | 		*pstr++ = ':'; | 
 | 		if (fmt) *pstr++ = '\t'; | 
 | 		strcpy(pstr, entries[i]); | 
 | 		pstr += strlen(entries[i]); | 
 | 		if (i != numentries - 1) *pstr++ = ','; | 
 | 		if (fmt) *pstr++ = '\n'; | 
 | 		*pstr = 0; | 
 | 		cJSON_free(names[i]); | 
 | 		cJSON_free(entries[i]); | 
 | 	} | 
 |  | 
 | 	cJSON_free(names); | 
 | 	cJSON_free(entries); | 
 | 	if (fmt) for (i = 0; i < depth - 1; i++) *pstr++ = '\t'; | 
 | 	*pstr++ = '}'; | 
 | 	*pstr++ = 0; | 
 | 	return oitem; | 
 | } | 
 |  | 
 | int cJSON_GetArraySize(cJSON *array) | 
 | { | 
 | 	int i = 0; | 
 | 	cJSON *citem = array->child; | 
 | 	 | 
 | 	while (citem)i++, citem = citem->next; | 
 | 	return i; | 
 | } | 
 | cJSON *cJSON_GetArrayItem(cJSON *array, int item) | 
 | { | 
 | 	cJSON *citem = array->child; | 
 | 	while (citem && item > 0) item--, citem = citem->next; | 
 | 	return citem; | 
 | } | 
 | cJSON *cJSON_GetObjectItem(cJSON *object, const char *string) | 
 | { | 
 | 	cJSON *citem = object->child; | 
 | 	while (citem && cJSON_strcasecmp(citem->string, string)) citem = citem->next; | 
 | 	return citem; | 
 | } | 
 |  | 
 | static void suffix_object(cJSON *prev, cJSON *item) | 
 | { | 
 | 	prev->next = item; | 
 | 	item->prev = prev; | 
 | } | 
 |  | 
 | static cJSON *create_reference(cJSON *item) | 
 | { | 
 | 	cJSON *refer = cJSON_New_Item(); | 
 | 	if (!refer)  | 
 | 		return 0; | 
 | 	memcpy(refer, item, sizeof(cJSON)); | 
 | 	refer->string = 0; | 
 | 	refer->type |= cJSON_IsReference; | 
 | 	refer->next = refer->prev = 0; | 
 | 	return refer; | 
 | } | 
 |  | 
 | void cJSON_AddItemToArray(cJSON *array, cJSON *item) | 
 | { | 
 | 	cJSON *citem = array->child; | 
 | 	if (!item)  | 
 | 		return; | 
 | 	if (!citem) { | 
 | 		array->child = item; | 
 | 	} else { | 
 | 		while (citem && citem->next) citem = citem->next; | 
 | 		suffix_object(citem, item); | 
 | 	} | 
 | } | 
 | 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); | 
 | } | 
 | void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) | 
 | { | 
 | 	cJSON_AddItemToArray(array, create_reference(item)); | 
 | } | 
 | void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) | 
 | { | 
 | 	cJSON_AddItemToObject(object, string, create_reference(item)); | 
 | } | 
 |  | 
 | cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) | 
 | { | 
 | 	cJSON *citem = array->child; | 
 | 	while (citem && which > 0) citem = citem->next, which--; | 
 | 	if (!citem)  | 
 | 		return 0; | 
 | 	if (citem->prev) citem->prev->next = citem->next; | 
 | 	if (citem->next) citem->next->prev = citem->prev; | 
 | 	if (citem == array->child) array->child = citem->next; | 
 | 	citem->prev = citem->next = 0; | 
 | 	return citem; | 
 | } | 
 | void cJSON_DeleteItemFromArray(cJSON *array, int which) | 
 | { | 
 | 	cJSON_Delete(cJSON_DetachItemFromArray(array, which)); | 
 | } | 
 | cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) | 
 | { | 
 | 	int i = 0; | 
 | 	cJSON *citem = object->child; | 
 | 	while (citem && cJSON_strcasecmp(citem->string, string)) i++, citem = citem->next; | 
 | 	if (citem)  | 
 | 		return cJSON_DetachItemFromArray(object, i); | 
 | 	return 0; | 
 | } | 
 | void   cJSON_DeleteItemFromObject(cJSON *object, const char *string) | 
 | { | 
 | 	cJSON_Delete(cJSON_DetachItemFromObject(object, string)); | 
 | } | 
 |  | 
 | void   cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) | 
 | { | 
 | 	cJSON *citem = array->child; | 
 | 	while (citem && which > 0) citem = citem->next, which--; | 
 | 	if (!citem)  | 
 | 		return; | 
 | 	newitem->next = citem->next; | 
 | 	newitem->prev = citem->prev; | 
 | 	if (newitem->next) newitem->next->prev = newitem; | 
 | 	if (citem == array->child) array->child = newitem; | 
 | 	else newitem->prev->next = newitem; | 
 | 	citem->next = citem->prev = 0; | 
 | 	cJSON_Delete(citem); | 
 | } | 
 | void   cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) | 
 | { | 
 | 	int i = 0; | 
 | 	cJSON *citem = object->child; | 
 | 	while (citem && cJSON_strcasecmp(citem->string, string))i++, citem = citem->next; | 
 | 	if (citem) { | 
 | 		newitem->string = cJSON_strdup(string); | 
 | 		cJSON_ReplaceItemInArray(object, i, newitem); | 
 | 	} | 
 | } | 
 |  | 
 | cJSON *cJSON_CreateNull(void) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item)item->type = cJSON_NULL; | 
 | 	return item; | 
 | } | 
 | cJSON *cJSON_CreateTrue(void) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item)item->type = cJSON_True; | 
 | 	return item; | 
 | } | 
 | cJSON *cJSON_CreateFalse(void) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item)item->type = cJSON_False; | 
 | 	return item; | 
 | } | 
 | cJSON *cJSON_CreateBool(int b) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item)item->type = b ? cJSON_True : cJSON_False; | 
 | 	return item; | 
 | } | 
 | cJSON *cJSON_CreateNumber(double num) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item) { | 
 | 		item->type = cJSON_Number; | 
 | 		item->valuedouble = num; | 
 | 		item->valueint = (int)num; | 
 | 	} | 
 | 	return item; | 
 | } | 
 | cJSON *cJSON_CreateString(const char *string) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item) { | 
 | 		item->type = cJSON_String; | 
 | 		item->valuestring = cJSON_strdup(string); | 
 | 	} | 
 | 	return item; | 
 | } | 
 | cJSON *cJSON_CreateArray(void) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item)item->type = cJSON_Array; | 
 | 	return item; | 
 | } | 
 | cJSON *cJSON_CreateObject(void) | 
 | { | 
 | 	cJSON *item = cJSON_New_Item(); | 
 | 	if (item)item->type = cJSON_Object; | 
 | 	return item; | 
 | } | 
 |  | 
 | 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 (!i)a->child = n; | 
 | 		else suffix_object(p, n); | 
 | 		p = n; | 
 | 	} | 
 | 	return a; | 
 | } | 
 | 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 (!i)a->child = n; | 
 | 		else suffix_object(p, n); | 
 | 		p = n; | 
 | 	} | 
 | 	return a; | 
 | } | 
 | 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 (!i)a->child = n; | 
 | 		else suffix_object(p, n); | 
 | 		p = n; | 
 | 	} | 
 | 	return a; | 
 | } | 
 | 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 (!i)a->child = n; | 
 | 		else suffix_object(p, n); | 
 | 		p = n; | 
 | 	} | 
 | 	return a; | 
 | } | 
 |  | 
 | cJSON *cJSON_Duplicate(cJSON *item, int recurse) | 
 | { | 
 | 	cJSON *newitem, *cptr, *nptr = 0, *newchild; | 
 |  | 
 | 	if (!item)  | 
 | 		return 0; | 
 |  | 
 | 	newitem = cJSON_New_Item(); | 
 | 	if (!newitem)  | 
 | 		return 0; | 
 |  | 
 | 	newitem->type = item->type & (~cJSON_IsReference), newitem->valueint = item->valueint, newitem->valuedouble = item->valuedouble; | 
 | 	if (item->valuestring)	{ | 
 | 		newitem->valuestring = cJSON_strdup(item->valuestring); | 
 | 		if (!newitem->valuestring)	{ | 
 | 			cJSON_Delete(newitem); | 
 | 			return 0; | 
 | 		} | 
 | 	} | 
 | 	if (item->string)		{ | 
 | 		newitem->string = cJSON_strdup(item->string); | 
 | 		if (!newitem->string)		{ | 
 | 			cJSON_Delete(newitem); | 
 | 			return 0; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	if (!recurse)  | 
 | 		return newitem; | 
 |  | 
 | 	cptr = item->child; | 
 | 	while (cptr) { | 
 | 		newchild = cJSON_Duplicate(cptr, 1); | 
 | 		if (!newchild) { | 
 | 			cJSON_Delete(newitem); | 
 | 			return 0; | 
 | 		} | 
 | 		if (nptr)	{ | 
 | 			nptr->next = newchild, newchild->prev = nptr; | 
 | 			nptr = newchild; | 
 | 		} else		{ | 
 | 			newitem->child = newchild; | 
 | 			nptr = newchild; | 
 | 		} | 
 | 		cptr = cptr->next; | 
 | 	} | 
 | 	return newitem; | 
 | } | 
 |  | 
 | void cJSON_Minify(char *json) | 
 | { | 
 | 	char *cpr_str = json; | 
 | 	while (*json) { | 
 | 		if (*json == ' ') json++; | 
 | 		else if (*json == '\t') json++; | 
 | 		else if (*json == '\r') json++; | 
 | 		else if (*json == '\n') json++; | 
 | 		else if (*json == '/' && json[1] == '/')  while (*json && *json != '\n') json++; | 
 | 		else if (*json == '/' && json[1] == '*') { | 
 | 			while (*json && !(*json == '*' && json[1] == '/')) json++; | 
 | 			json += 2; | 
 | 		} else if (*json == '\"') { | 
 | 			*cpr_str++ = *json++; | 
 | 			while (*json && *json != '\"') { | 
 | 				if (*json == '\\') *cpr_str++ = *json++; | 
 | 				*cpr_str++ = *json++; | 
 | 			} | 
 | 			*cpr_str++ = *json++; | 
 | 		} else *cpr_str++ = *json++; | 
 | 	} | 
 | 	*cpr_str = 0; | 
 | } |