#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "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;
}
