| #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; |
| } |