void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { if (!item) { return; } /* free old key and set new one */ if (item->string) { cJSON_free(item->string); } item->string = cJSON_strdup(string); cJSON_AddItemToArray(object,item); }
void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) { int i = 0; cJSON *c = object->child; while(c && cJSON_strcasecmp(c->string, string)) { i++; c = c->next; } if(c) { /* free the old string if not const */ if (!(newitem->type & cJSON_StringIsConst) && newitem->string) { cJSON_free(newitem->string); } newitem->string = cJSON_strdup(string); cJSON_ReplaceItemInArray(object, i, newitem); } }
/* Render an array to text */ static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p) { char **entries; char *out=0,*ptr,*ret;int len=5; cJSON *child=item->child; int numentries=0,i=0,fail=0; size_t tmplen=0; /* How many entries in the array? */ while (child) numentries++,child=child->next; /* Explicitly handle numentries==0 */ if (!numentries) { if (p) out=ensure(p,3); else out=(char*)cJSON_malloc(3); if (out) strcpy(out,"[]"); return out; } if (p) { /* Compose the output array. */ i=p->offset; ptr=ensure(p,1);if (!ptr) return 0; *ptr='['; p->offset++; child=item->child; while (child && !fail) { print_value(child,depth+1,fmt,p); p->offset=update(p); if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;} child=child->next; } ptr=ensure(p,2);if (!ptr) return 0; *ptr++=']';*ptr=0; out=(p->buffer)+i; } else { /* Allocate an array to hold the values for each */ entries=(char**)cJSON_malloc(numentries*sizeof(char*)); if (!entries) return 0; memset(entries,0,numentries*sizeof(char*)); /* Retrieve all the results: */ child=item->child; while (child && !fail) { ret=print_value(child,depth+1,fmt,0); entries[i++]=ret; if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; child=child->next; } /* If we didn't fail, try to malloc the output string */ if (!fail) out=(char*)cJSON_malloc(len); /* If that fails, we fail. */ if (!out) fail=1; /* Handle failure. */ if (fail) { for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]); cJSON_free(entries); return 0; } /* Compose the output array. */ *out='['; ptr=out+1;*ptr=0; for (i=0;i<numentries;i++) { tmplen=strlen(entries[i]);memcpy(ptr,entries[i],tmplen);ptr+=tmplen; if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;} cJSON_free(entries[i]); } cJSON_free(entries); *ptr++=']';*ptr++=0; } return out; }
static char *print_array(cJSON *item) { char **entries; char *out = 0; char *ptr, *ret; int len = 5; cJSON *child = item->child; int numentries = 0, i = 0, fail = 0; size_t tmplen = 0; /* How many entries in the array? */ while(child) numentries++, child = child->next; /* Explicitly handle numentries==0 */ if(!numentries) { out = (char*) cJSON_malloc(3); if(out) strcpy(out, "[]"); return out; } /* Allocate an array to hold the values for each */ entries = (char**) cJSON_malloc(numentries * sizeof(char*)); if(!entries) return 0; memset(entries, 0, numentries * sizeof(char*)); /* Retrieve all the results: */ child = item->child; while(child && !fail) { ret = print_value(child, 1, 1, 0); entries[i++] = ret; if(ret) len += strlen(ret) + 2 + (1 ? 1 : 0); else fail = 1; child = child->next; } /* If we didn't fail, try to malloc the output string */ if(!fail) out = (char*) cJSON_malloc(len); /* If that fails, we fail. */ if(!out) fail = 1; /* Handle failure. */ if(fail) { for(i = 0; i < numentries; i++) if(entries[i]) cJSON_free(entries[i]); cJSON_free(entries); return 0; } /* Compose the output array. */ *out = '['; ptr = out + 1; *ptr = 0; for(i = 0; i < numentries; i++) { tmplen = strlen(entries[i]); memcpy(ptr, entries[i], tmplen); ptr += tmplen; if(i != numentries - 1) { *ptr++ = ','; *ptr++ = ' '; *ptr = 0; } cJSON_free(entries[i]); } cJSON_free(entries); *ptr++ = ']'; *ptr++ = 0; return out; }
/* Render an object to text. */ static char *print_object(cJSON *item,int depth,int fmt) { char **entries=0,**names=0; char *out=0,*ptr,*ret,*str; int len=1024,i=0,j; int num_size = 0; cJSON *child=item->child; int numentries=0,fail=0; //return 0; /* Count the number of entries. */ while (child) { numentries++; child=child->next; } /* Explicitly handle empty object case */ if (!numentries) { out=(char*)cJSON_malloc(fmt?depth+4:3); if (!out) return 0; ptr=out;*ptr++='{'; if (fmt) { *ptr ++ ='\n'; for (i=0;i<depth-1;i++) *ptr++='\t'; } *ptr++='}';*ptr++=0; return out; } num_size = numentries*sizeof(char*); /* Allocate space for the names and the objects */ entries=(char**)cJSON_malloc(num_size); if (!entries) return 0; names=(char**)cJSON_malloc(num_size); if (!names) { cJSON_free(entries); return 0; } //debug code //if(depth >1 ) //{ //_hx_printf("entries=%X,names=%X",entries,names); //return 0; //} //mymemset(entries,0,num_size); //mymemset(names,0,num_size); //return 0; /* Collect all the results into our arrays: */ child = item->child; depth ++; if (fmt) { len+=depth; } while (child) { names[i] = str = print_string_ptr(child->string); //debug code //_hx_printf("numentries=%d,i=%d,fmt=%d,depth=%d,type=%d",numentries,i,fmt,depth,(child->type)&255); entries[i] = ret = print_value(child,depth,fmt); i++; if (str && ret) { len += mystrlen(ret)+mystrlen(str)+2+(fmt?2+depth:0); } else { fail=1; } child=child->next; } //return 0; /* Try to allocate the output string */ if (!fail) out=(char*)cJSON_malloc(len); if (!out) fail=1; /* Handle failure */ 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; } /* Compose the output: */ *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0; for (i=0;i<numentries;i++) { if (fmt) { //for (j=0;j<depth;j++) //{ // *ptr++ ='\t'; //} } mystrcpy(ptr,names[i]);ptr+=mystrlen(names[i]); *ptr++=':';if (fmt) *ptr++='\t'; mystrcpy(ptr,entries[i]);ptr+=mystrlen(entries[i]); if (i!=numentries-1) *ptr++=','; if (fmt) *ptr++='\n';*ptr=0; cJSON_free(names[i]);cJSON_free(entries[i]); } //return 0; cJSON_free(names);cJSON_free(entries); if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t'; *ptr++='}';*ptr++=0; return out; }
/* Render an object to text. */ static char *print_object(cJSON *item,int depth) { char **entries=0,**names=0; char *out=0,*ptr,*ret,*str;int len=7,i=0,j; cJSON *child=item->child; int numentries=0,fail=0; /* Count the number of entries. */ while (child) numentries++,child=child->next; /* Explicitly handle empty object case */ if (!numentries) { out=(char*)cJSON_malloc(depth * 3 +4); if (!out) return 0; ptr=out; for (i=0;i<depth-1;i++){ *ptr++=' '; *ptr++=' '; }; *ptr++=0; return out; } /* Allocate space for the names and the objects */ 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); /* Collect all the results into our arrays: */ child=item->child;depth++; len+=depth; while (child) { names[i]=str=strdup(child->string); entries[i++]=ret=print_value(child,depth); if (str && ret) len+=strlen(ret)+strlen(str)+2+(depth*3); else fail=1; child=child->next; } /* Try to allocate the output string */ if (!fail) out=(char*)cJSON_malloc(len); if (!out) fail=1; /* Handle failure */ 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; } /* Compose the output: */ ptr=out; *ptr=0; if( depth > 1 ) *ptr++='\n'; for (i=0;i<numentries;i++) { for (j=0;j<depth-1;j++){ *ptr++=' '; *ptr++=' '; }; strcpy(ptr,names[i]);ptr+=strlen(names[i]); *ptr++=':'; *ptr++=' '; strcpy(ptr,entries[i]);ptr+=strlen(entries[i]); cJSON_free(names[i]); cJSON_free(entries[i]); if( i < numentries - 1 ) *ptr++='\n'; } cJSON_free(names);cJSON_free(entries); *ptr++=0; return out; }
/* Render an array to text */ static char *ICACHE_FLASH_ATTR print_array(cJSON *item, int depth, int fmt) { char **entries; char *out = 0, *ptr, *ret; int len = 5; cJSON *child = item->child; int numentries = 0, i = 0, fail = 0; /* How many entries in the array? */ while (child) { numentries++, child = child->next; } /* Explicitly handle numentries==0 */ if (!numentries) { out = (char *)cJSON_malloc(3); if (out) { strcpy(out, "[]"); } return out; } /* Allocate an array to hold the values for each */ entries = (char **)cJSON_malloc(numentries * sizeof(char *)); if (!entries) { return 0; } memset(entries, 0, numentries * sizeof(char *)); /* Retrieve all the results: */ 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 we didn't fail, try to malloc the output string */ if (!fail) { out = (char *)cJSON_malloc(len); } /* If that fails, we fail. */ if (!out) { fail = 1; } /* Handle failure. */ if (fail) { for (i = 0; i < numentries; i++) if (entries[i]) { cJSON_free(entries[i]); } cJSON_free(entries); return 0; } /* Compose the output array. */ *out = '['; ptr = out + 1; *ptr = 0; for (i = 0; i < numentries; i++) { strcpy(ptr, entries[i]); ptr += strlen(entries[i]); if (i != numentries - 1) { *ptr++ = ','; if (fmt) { *ptr++ = ' '; }*ptr = 0; } cJSON_free(entries[i]); } cJSON_free(entries); *ptr++ = ']'; *ptr++ = 0; return out; }
PREDEM_CURL_CODE predem_curl_send_event(const char *name, const char* json_string){ CURL *curl; CURLcode res; struct curl_slist *list = NULL; char url_buff[512]; if (inited == 0) { return PREDEM_CURL_NOT_INIT; } if (json_string == NULL || name == NULL) { return PREDEM_CURL_INVALID_DATA; } /* get a curl handle */ curl = curl_easy_init(); if (curl == NULL ) { return PREDEM_CURL_NO_MEMORY; } memset(url_buff, 0, sizeof(url_buff)); int pos = 0; if (has_http(g_domain) == 0) { memcpy(url_buff, "http://", 7); pos += 7; } snprintf(url_buff+pos, sizeof(url_buff)-pos, "%s/v2/%s/custom-events", g_domain, g_app_id); curl_easy_setopt(curl, CURLOPT_URL, url_buff); curl_easy_setopt(curl, CURLOPT_USERAGENT, g_UA); list = curl_slist_append(list, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); cJSON* event = build_event(name, json_string); const char* c = cJSON_PrintUnformatted(event); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(c)); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, c); res = curl_easy_perform(curl); curl_easy_cleanup(curl); curl_slist_free_all(list); cJSON_free((void*)c); cJSON_Delete(event); if(res != CURLE_OK) { return (PREDEM_CURL_CODE)res; } return PREDEM_CURL_OK; }
/* Render an object to text. */ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer *p) { char **entries = NULL; char **names = NULL; char *out = NULL; char *ptr = NULL; char *ret = NULL; char *str = NULL; int len = 7; int i = 0; int j = 0; cJSON *child = item->child; int numentries = 0; cjbool fail = false; size_t tmplen = 0; /* Count the number of entries. */ while (child) { numentries++; child = child->next; } /* Explicitly handle empty object case */ if (!numentries) { if (p) { out = ensure(p, fmt ? depth + 4 : 3); } else { out = (char*)cJSON_malloc(fmt ? depth + 4 : 3); } if (!out) { return NULL; } ptr = out; *ptr++ = '{'; if (fmt) { *ptr++ = '\n'; for (i = 0; i < depth; i++) { *ptr++ = '\t'; } } *ptr++ = '}'; *ptr++ = '\0'; return out; } if (p) { /* Compose the output: */ i = p->offset; len = fmt ? 2 : 1; /* fmt: {\n */ ptr = ensure(p, len + 1); if (!ptr) { return NULL; } *ptr++ = '{'; if (fmt) { *ptr++ = '\n'; } *ptr = '\0'; p->offset += len; child = item->child; depth++; while (child) { if (fmt) { ptr = ensure(p, depth); if (!ptr) { return NULL; } for (j = 0; j < depth; j++) { *ptr++ = '\t'; } p->offset += depth; } /* print key */ if (!print_string_ptr(child->string, p)) { return NULL; } p->offset = update(p); len = fmt ? 2 : 1; ptr = ensure(p, len); if (!ptr) { return NULL; } *ptr++ = ':'; if (fmt) { *ptr++ = '\t'; } p->offset+=len; /* print value */ if (!print_value(child, depth, fmt, p)) { return NULL; }; p->offset = update(p); /* print comma if not last */ len = (fmt ? 1 : 0) + (child->next ? 1 : 0); ptr = ensure(p, len + 1); if (!ptr) { return NULL; } if (child->next) { *ptr++ = ','; } if (fmt) { *ptr++ = '\n'; } *ptr = '\0'; p->offset += len; child = child->next; } ptr = ensure(p, fmt ? (depth + 1) : 2); if (!ptr) { return NULL; } if (fmt) { for (i = 0; i < (depth - 1); i++) { *ptr++ = '\t'; } } *ptr++ = '}'; *ptr = '\0'; out = (p->buffer) + i; } else { /* Allocate space for the names and the objects */ entries = (char**)cJSON_malloc(numentries * sizeof(char*)); if (!entries) { return NULL; } names = (char**)cJSON_malloc(numentries * sizeof(char*)); if (!names) { cJSON_free(entries); return NULL; } memset(entries, '\0', sizeof(char*) * numentries); memset(names, '\0', sizeof(char*) * numentries); /* Collect all the results into our arrays: */ child = item->child; depth++; if (fmt) { len += depth; } while (child && !fail) { names[i] = str = print_string_ptr(child->string, 0); /* print key */ entries[i++] = ret = print_value(child, depth, fmt, 0); if (str && ret) { len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); } else { fail = true; } child = child->next; } /* Try to allocate the output string */ if (!fail) { out = (char*)cJSON_malloc(len); } if (!out) { fail = true; } /* Handle failure */ if (fail) { /* free all the printed keys and values */ 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 NULL; } /* Compose the output: */ *out = '{'; ptr = out + 1; if (fmt) { *ptr++ = '\n'; } *ptr = '\0'; for (i = 0; i < numentries; i++) { if (fmt) { for (j = 0; j < depth; j++) { *ptr++='\t'; } } tmplen = strlen(names[i]); memcpy(ptr, names[i], tmplen); ptr += tmplen; *ptr++ = ':'; if (fmt) { *ptr++ = '\t'; } strcpy(ptr, entries[i]); ptr += strlen(entries[i]); if (i != (numentries - 1)) { *ptr++ = ','; } if (fmt) { *ptr++ = '\n'; } *ptr = '\0'; cJSON_free(names[i]); cJSON_free(entries[i]); } cJSON_free(names); cJSON_free(entries); if (fmt) { for (i = 0; i < (depth - 1); i++) { *ptr++ = '\t'; } } *ptr++ = '}'; *ptr++ = '\0'; } return out; }
void jsonFree(cJSON* j) { cJSON_free(j); }
/* Render an array to text */ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *p) { char **entries; char *out = NULL; char *ptr = NULL; char *ret = NULL; int len = 5; cJSON *child = item->child; int numentries = 0; int i = 0; cjbool fail = false; size_t tmplen = 0; /* How many entries in the array? */ while (child) { numentries++; child = child->next; } /* Explicitly handle numentries == 0 */ if (!numentries) { if (p) { out = ensure(p, 3); } else { out = (char*)cJSON_malloc(3); } if (out) { strcpy(out,"[]"); } return out; } if (p) { /* Compose the output array. */ /* opening square bracket */ i = p->offset; ptr = ensure(p, 1); if (!ptr) { return NULL; } *ptr = '['; p->offset++; child = item->child; while (child && !fail) { if (!print_value(child, depth + 1, fmt, p)) { return NULL; } p->offset = update(p); if (child->next) { len = fmt ? 2 : 1; ptr = ensure(p, len + 1); if (!ptr) { return NULL; } *ptr++ = ','; if(fmt) { *ptr++ = ' '; } *ptr = '\0'; p->offset += len; } child = child->next; } ptr = ensure(p, 2); if (!ptr) { return NULL; } *ptr++ = ']'; *ptr = '\0'; out = (p->buffer) + i; } else { /* Allocate an array to hold the pointers to all printed values */ entries = (char**)cJSON_malloc(numentries * sizeof(char*)); if (!entries) { return NULL; } memset(entries, '\0', numentries * sizeof(char*)); /* Retrieve all the results: */ child = item->child; while (child && !fail) { ret = print_value(child, depth + 1, fmt, 0); entries[i++] = ret; if (ret) { len += strlen(ret) + 2 + (fmt ? 1 : 0); } else { fail = true; } child = child->next; } /* If we didn't fail, try to malloc the output string */ if (!fail) { out = (char*)cJSON_malloc(len); } /* If that fails, we fail. */ if (!out) { fail = true; } /* Handle failure. */ if (fail) { /* free all the entries in the array */ for (i = 0; i < numentries; i++) { if (entries[i]) { cJSON_free(entries[i]); } } cJSON_free(entries); return NULL; } /* Compose the output array. */ *out='['; ptr = out + 1; *ptr = '\0'; for (i = 0; i < numentries; i++) { tmplen = strlen(entries[i]); memcpy(ptr, entries[i], tmplen); ptr += tmplen; if (i != (numentries - 1)) { *ptr++ = ','; if(fmt) { *ptr++ = ' '; } *ptr = '\0'; } cJSON_free(entries[i]); } cJSON_free(entries); *ptr++ = ']'; *ptr++ = '\0'; } return out; }
/* Render an array to text */ static char *print_2dfloat_array(cJSON *item,int fmt, ngx_pool_t *pool) { char **entries; char *out=0,*ptr,*ret;int len=5; int i=0,fail=0; /* 2d Array has no children!*/ /* How many entries in the array? */ if (!item->d2_len) { out=(char*)cJSON_malloc(pool, 3); if (out) strcpy(out,"[]"); return out; } /* Allocate an array to hold the values for each */ entries=(char**)cJSON_malloc(pool, item->d2_len*sizeof(char*)); if (!entries) return 0; memset(entries,0,item->d2_len*sizeof(char*)); /* Retrieve all the results: */ for(i = 0; i < item->d2_len; i++) { ret=print_number_2d(item, i, pool); entries[i]=ret; if(ret) len+=strlen(ret)+4+(fmt?1:0); else { fail = 1; break; } } /* If we didn't fail, try to malloc the output string */ if (!fail) out=(char*)cJSON_malloc(pool, len); /* If that fails, we fail. */ if (!out) fail=1; /* Handle failure. */ if (fail) { for (i=0;i<item->d2_len;i++) if (entries[i]) cJSON_free(pool, entries[i]); cJSON_free(pool, entries); return 0; } /* Compose the output array. */ *out='['; ptr=out+1;*ptr=0; for (i=0;i<item->d2_len;i++) { *ptr++='['; strcpy(ptr,entries[i]);ptr+=strlen(entries[i]); *ptr++=']'; if (i!=item->d2_len-1) { *ptr++=','; if(fmt) *ptr++=' '; *ptr=0; } cJSON_free(pool, entries[i]); } cJSON_free(pool, entries); *ptr++=']';*ptr++=0; return out; }
static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_sensitive) { cJSON *path = NULL; cJSON *value = NULL; cJSON *parent = NULL; enum patch_operation opcode = INVALID; unsigned char *parent_pointer = NULL; unsigned char *child_pointer = NULL; int status = 0; path = get_object_item(patch, "path", case_sensitive); if (!cJSON_IsString(path)) { /* malformed patch. */ status = 2; goto cleanup; } opcode = decode_patch_operation(patch, case_sensitive); if (opcode == INVALID) { status = 3; goto cleanup; } else if (opcode == TEST) { /* compare value: {...} with the given path */ status = !compare_json(get_item_from_pointer(object, path->valuestring, case_sensitive), get_object_item(patch, "value", case_sensitive), case_sensitive); goto cleanup; } /* special case for replacing the root */ if (path->valuestring[0] == '\0') { if (opcode == REMOVE) { static const cJSON invalid = { NULL, NULL, NULL, cJSON_Invalid, NULL, 0, 0, NULL}; overwrite_item(object, invalid); status = 0; goto cleanup; } if ((opcode == REPLACE) || (opcode == ADD)) { value = get_object_item(patch, "value", case_sensitive); if (value == NULL) { /* missing "value" for add/replace. */ status = 7; goto cleanup; } value = cJSON_Duplicate(value, 1); if (value == NULL) { /* out of memory for add/replace. */ status = 8; goto cleanup; } overwrite_item(object, *value); /* delete the duplicated value */ cJSON_free(value); value = NULL; /* the string "value" isn't needed */ if (object->string != NULL) { cJSON_free(object->string); object->string = NULL; } status = 0; goto cleanup; } } if ((opcode == REMOVE) || (opcode == REPLACE)) { /* Get rid of old. */ cJSON *old_item = detach_path(object, (unsigned char*)path->valuestring, case_sensitive); if (old_item == NULL) { status = 13; goto cleanup; } cJSON_Delete(old_item); if (opcode == REMOVE) { /* For Remove, this job is done. */ status = 0; goto cleanup; } } /* Copy/Move uses "from". */ if ((opcode == MOVE) || (opcode == COPY)) { cJSON *from = get_object_item(patch, "from", case_sensitive); if (from == NULL) { /* missing "from" for copy/move. */ status = 4; goto cleanup; } if (opcode == MOVE) { value = detach_path(object, (unsigned char*)from->valuestring, case_sensitive); } if (opcode == COPY) { value = get_item_from_pointer(object, from->valuestring, case_sensitive); } if (value == NULL) { /* missing "from" for copy/move. */ status = 5; goto cleanup; } if (opcode == COPY) { value = cJSON_Duplicate(value, 1); } if (value == NULL) { /* out of memory for copy/move. */ status = 6; goto cleanup; } } else /* Add/Replace uses "value". */ { value = get_object_item(patch, "value", case_sensitive); if (value == NULL) { /* missing "value" for add/replace. */ status = 7; goto cleanup; } value = cJSON_Duplicate(value, 1); if (value == NULL) { /* out of memory for add/replace. */ status = 8; goto cleanup; } } /* Now, just add "value" to "path". */ /* split pointer in parent and child */ parent_pointer = cJSONUtils_strdup((unsigned char*)path->valuestring); child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/'); if (child_pointer != NULL) { child_pointer[0] = '\0'; child_pointer++; } parent = get_item_from_pointer(object, (char*)parent_pointer, case_sensitive); decode_pointer_inplace(child_pointer); /* add, remove, replace, move, copy, test. */ if ((parent == NULL) || (child_pointer == NULL)) { /* Couldn't find object to add to. */ status = 9; goto cleanup; } else if (cJSON_IsArray(parent)) { if (strcmp((char*)child_pointer, "-") == 0) { cJSON_AddItemToArray(parent, value); value = NULL; } else { size_t index = 0; if (!decode_array_index_from_pointer(child_pointer, &index)) { status = 11; goto cleanup; } if (!insert_item_in_array(parent, index, value)) { status = 10; goto cleanup; } value = NULL; } } else if (cJSON_IsObject(parent)) { cJSON_DeleteItemFromObject(parent, (char*)child_pointer); cJSON_AddItemToObject(parent, (char*)child_pointer, value); value = NULL; } cleanup: if (value != NULL) { cJSON_Delete(value); } if (parent_pointer != NULL) { cJSON_free(parent_pointer); } return status; }
static void create_patches(cJSON * const patches, const unsigned char * const path, cJSON * const from, cJSON * const to, const cJSON_bool case_sensitive) { if ((from == NULL) || (to == NULL)) { return; } if ((from->type & 0xFF) != (to->type & 0xFF)) { compose_patch(patches, (const unsigned char*)"replace", path, 0, to); return; } switch (from->type & 0xFF) { case cJSON_Number: if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble)) { compose_patch(patches, (const unsigned char*)"replace", path, NULL, to); } return; case cJSON_String: if (strcmp(from->valuestring, to->valuestring) != 0) { compose_patch(patches, (const unsigned char*)"replace", path, NULL, to); } return; case cJSON_Array: { size_t index = 0; cJSON *from_child = from->child; cJSON *to_child = to->child; unsigned char *new_path = (unsigned char*)cJSON_malloc(strlen((const char*)path) + 20 + sizeof("/")); /* Allow space for 64bit int. log10(2^64) = 20 */ /* generate patches for all array elements that exist in both "from" and "to" */ for (index = 0; (from_child != NULL) && (to_child != NULL); (void)(from_child = from_child->next), (void)(to_child = to_child->next), index++) { /* check if conversion to unsigned long is valid * This should be eliminated at compile time by dead code elimination * if size_t is an alias of unsigned long, or if it is bigger */ if (index > ULONG_MAX) { cJSON_free(new_path); return; } sprintf((char*)new_path, "%s/%lu", path, (unsigned long)index); /* path of the current array element */ create_patches(patches, new_path, from_child, to_child, case_sensitive); } /* remove leftover elements from 'from' that are not in 'to' */ for (; (from_child != NULL); (void)(from_child = from_child->next)) { /* check if conversion to unsigned long is valid * This should be eliminated at compile time by dead code elimination * if size_t is an alias of unsigned long, or if it is bigger */ if (index > ULONG_MAX) { cJSON_free(new_path); return; } sprintf((char*)new_path, "%lu", (unsigned long)index); compose_patch(patches, (const unsigned char*)"remove", path, new_path, NULL); } /* add new elements in 'to' that were not in 'from' */ for (; (to_child != NULL); (void)(to_child = to_child->next), index++) { compose_patch(patches, (const unsigned char*)"add", path, (const unsigned char*)"-", to_child); } cJSON_free(new_path); return; } case cJSON_Object: { cJSON *from_child = NULL; cJSON *to_child = NULL; sort_object(from, case_sensitive); sort_object(to, case_sensitive); from_child = from->child; to_child = to->child; /* for all object values in the object with more of them */ while ((from_child != NULL) || (to_child != NULL)) { int diff; if (from_child == NULL) { diff = 1; } else if (to_child == NULL) { diff = -1; } else { diff = compare_strings((unsigned char*)from_child->string, (unsigned char*)to_child->string, case_sensitive); } if (diff == 0) { /* both object keys are the same */ size_t path_length = strlen((const char*)path); size_t from_child_name_length = pointer_encoded_length((unsigned char*)from_child->string); unsigned char *new_path = (unsigned char*)cJSON_malloc(path_length + from_child_name_length + sizeof("/")); sprintf((char*)new_path, "%s/", path); encode_string_as_pointer(new_path + path_length + 1, (unsigned char*)from_child->string); /* create a patch for the element */ create_patches(patches, new_path, from_child, to_child, case_sensitive); cJSON_free(new_path); from_child = from_child->next; to_child = to_child->next; } else if (diff < 0) { /* object element doesn't exist in 'to' --> remove it */ compose_patch(patches, (const unsigned char*)"remove", path, (unsigned char*)from_child->string, NULL); from_child = from_child->next; } else { /* object element doesn't exist in 'from' --> add it */ compose_patch(patches, (const unsigned char*)"add", path, (unsigned char*)to_child->string, to_child); to_child = to_child->next; } } return; } default: break; } }
/* Render an object to text. */ static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p) { char **entries=0,**names=0; char *out=0,*ptr,*ret,*str;int len=7,i=0,j; cJSON *child=item->child; int numentries=0,fail=0; size_t tmplen=0; /* Count the number of entries. */ while (child) numentries++,child=child->next; /* Explicitly handle empty object case */ if (!numentries) { if (p) out=ensure(p,fmt?depth+4:3); else out=(char*)cJSON_malloc(fmt?depth+4:3); if (!out) return 0; ptr=out;*ptr++='{'; if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';} *ptr++='}';*ptr++=0; return out; } if (p) { /* Compose the output: */ i=p->offset; len=fmt?2:1; ptr=ensure(p,len+1); if (!ptr) return 0; *ptr++='{'; if (fmt) *ptr++='\n'; *ptr=0; p->offset+=len; child=item->child;depth++; while (child) { if (fmt) { ptr=ensure(p,depth); if (!ptr) return 0; for (j=0;j<depth;j++) *ptr++='\t'; p->offset+=depth; } print_string_ptr(child->string,p); p->offset=update(p); len=fmt?2:1; ptr=ensure(p,len); if (!ptr) return 0; *ptr++=':';if (fmt) *ptr++='\t'; p->offset+=len; print_value(child,depth,fmt,p); p->offset=update(p); len=(fmt?1:0)+(child->next?1:0); ptr=ensure(p,len+1); if (!ptr) return 0; if (child->next) *ptr++=','; if (fmt) *ptr++='\n';*ptr=0; p->offset+=len; child=child->next; } ptr=ensure(p,fmt?(depth+1):2); if (!ptr) return 0; if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t'; *ptr++='}';*ptr=0; out=(p->buffer)+i; } else { /* Allocate space for the names and the objects */ 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); /* Collect all the results into our arrays: */ child=item->child;depth++;if (fmt) len+=depth; while (child) { names[i]=str=print_string_ptr(child->string,0); entries[i++]=ret=print_value(child,depth,fmt,0); if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; child=child->next; } /* Try to allocate the output string */ if (!fail) out=(char*)cJSON_malloc(len); if (!out) fail=1; /* Handle failure */ 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; } /* Compose the output: */ *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0; for (i=0;i<numentries;i++) { if (fmt) for (j=0;j<depth;j++) *ptr++='\t'; tmplen=strlen(names[i]);memcpy(ptr,names[i],tmplen);ptr+=tmplen; *ptr++=':';if (fmt) *ptr++='\t'; strcpy(ptr,entries[i]);ptr+=strlen(entries[i]); if (i!=numentries-1) *ptr++=','; if (fmt) *ptr++='\n';*ptr=0; cJSON_free(names[i]);cJSON_free(entries[i]); } cJSON_free(names);cJSON_free(entries); if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t'; *ptr++='}';*ptr++=0; } return out; }
/* Render an object to text. */ static char *print_object(cJSON *item,int32_t depth,int32_t fmt) { char **entries=0,**names=0; char *out=0,*ptr,*ret,*str;int32_t len=7,i=0,j; cJSON *child=item->child,*firstchild; int32_t numentries=0,fail=0; // Count the number of entries firstchild = child; while ( child ) { numentries++; child = child->next; if ( child == firstchild ) { printf("cJSON infinite loop detected\n"); break; } } /* Explicitly handle empty object case */ if (!numentries) { out=(char*)cJSON_malloc(fmt?depth+4+1:3+1); if (!out) return 0; ptr=out;*ptr++='{'; if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';} *ptr++='}';*ptr++=0; return out; } /* Allocate space for the names and the objects */ 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); /* Collect all the results into our arrays: */ 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 ( child == firstchild ) break; } /* Try to allocate the output string */ if (!fail) out=(char*)cJSON_malloc(len+1); if (!out) fail=1; /* Handle failure */ 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; } /* Compose the output: */ *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0; for (i=0;i<numentries;i++) { if (fmt) for (j=0;j<depth;j++) *ptr++='\t'; strcpy(ptr,names[i]);ptr+=strlen(names[i]); *ptr++=':';if (fmt) *ptr++='\t'; strcpy(ptr,entries[i]);ptr+=strlen(entries[i]); if (i!=numentries-1) *ptr++=','; if (fmt) *ptr++='\n';*ptr=0; cJSON_free(names[i]);cJSON_free(entries[i]); } cJSON_free(names);cJSON_free(entries); if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t'; *ptr++='}';*ptr++=0; return out; }
void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);}
/* Render an array to text */ static char *print_array( cJSON *item, int depth, int fmt ) { char **entries; char *out = 0, *ptr, *ret; int len = 5; cJSON *child = item->child; int numentries = 0, i = 0, fail = 0; /* How many entries in the array? */ while ( child ) { ++numentries; child = child->next; } /* Allocate an array to hold the values for each. */ if ( ! ( entries = (char**) cJSON_malloc( numentries * sizeof(char*) ) ) ) return 0; memset( entries, 0, numentries * sizeof(char*) ); /* Retrieve all the results. */ 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 we didn't fail, try to malloc the output string. */ if ( ! fail ) { out = (char*) cJSON_malloc( len ); if ( ! out ) fail = 1; } /* Handle failure. */ if ( fail ) { for ( i = 0; i < numentries; ++i ) if ( entries[i] ) cJSON_free( entries[i] ); cJSON_free( entries ); return 0; } /* Compose the output array. */ *out = '['; ptr = out + 1; *ptr = 0; for ( i = 0; i < numentries; ++i ) { strcpy( ptr, entries[i] ); ptr += strlen( entries[i] ); if ( i != numentries - 1 ) { *ptr++ = ','; if ( fmt ) *ptr++ = ' '; *ptr = 0; } cJSON_free( entries[i] ); } cJSON_free( entries ); *ptr++ = ']'; *ptr++ = 0; return out; }
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);}
/* Render an object to text. */ static char *print_object( cJSON *item, int depth, int fmt ) { char **entries = 0, **names = 0; char *out = 0, *ptr, *ret, *str; int len = 7, i = 0, j; cJSON *child = item->child; int numentries = 0, fail = 0; /* Count the number of entries. */ while ( child ) { ++numentries; child = child->next; } /* Allocate space for the names and the objects. */ if ( ! ( entries = (char**) cJSON_malloc( numentries * sizeof(char*) ) ) ) return 0; if ( ! ( names = (char**) cJSON_malloc( numentries * sizeof(char*) ) ) ) { cJSON_free( entries ); return 0; } memset( entries, 0, sizeof(char*) * numentries ); memset( names, 0, sizeof(char*) * numentries ); /* Collect all the results into our arrays. */ 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; } /* Try to allocate the output string. */ if ( ! fail ) { out = (char*) cJSON_malloc( len ); if ( ! out ) fail = 1; } /* Handle failure. */ 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; } /* Compose the output. */ *out = '{'; ptr = out + 1; if ( fmt ) *ptr++ = '\n'; *ptr = 0; for ( i = 0; i < numentries; ++i ) { if ( fmt ) for ( j = 0; j < depth; ++j ) *ptr++ = '\t'; strcpy( ptr, names[i] ); ptr += strlen( names[i] ); *ptr++ = ':'; if ( fmt ) *ptr++ = '\t'; strcpy( ptr, entries[i] ); ptr += strlen( entries[i] ); if ( i != numentries - 1 ) *ptr++ = ','; if ( fmt ) *ptr++ = '\n'; *ptr = 0; cJSON_free( names[i] ); cJSON_free( entries[i] ); } cJSON_free( names ); cJSON_free( entries ); if ( fmt ) for ( i = 0; i < depth - 1; ++i ) *ptr++ = '\t'; *ptr++ = '}'; *ptr++ = 0; return out; }
/* Render an object to text. */ static char *ICACHE_FLASH_ATTR print_object(cJSON *item, int depth, int fmt) { char **entries = 0, **names = 0; char *out = 0, *ptr, *ret, *str; int len = 7, i = 0, j; cJSON *child = item->child; int numentries = 0, fail = 0; /* Count the number of entries. */ while (child) { numentries++, child = child->next; } /* Explicitly handle empty object case */ if (!numentries) { out = (char *)cJSON_malloc(fmt ? depth + 4 : 3); if (!out) { return 0; } ptr = out; *ptr++ = '{'; if (fmt) { *ptr++ = '\n'; for (i = 0; i < depth - 1; i++) { *ptr++ = '\t'; } } *ptr++ = '}'; *ptr++ = 0; return out; } /* Allocate space for the names and the objects */ 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); /* Collect all the results into our arrays: */ 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; } /* Try to allocate the output string */ if (!fail) { out = (char *)cJSON_malloc(len); } if (!out) { fail = 1; } /* Handle failure */ 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; } /* Compose the output: */ *out = '{'; ptr = out + 1; if (fmt) { *ptr++ = '\n'; }*ptr = 0; for (i = 0; i < numentries; i++) { if (fmt) for (j = 0; j < depth; j++) { *ptr++ = '\t'; } strcpy(ptr, names[i]); ptr += strlen(names[i]); *ptr++ = ':'; if (fmt) { *ptr++ = '\t'; } strcpy(ptr, entries[i]); ptr += strlen(entries[i]); if (i != numentries - 1) { *ptr++ = ','; } if (fmt) { *ptr++ = '\n'; }*ptr = 0; cJSON_free(names[i]); cJSON_free(entries[i]); } cJSON_free(names); cJSON_free(entries); if (fmt) for (i = 0; i < depth - 1; i++) { *ptr++ = '\t'; } *ptr++ = '}'; *ptr++ = 0; return out; }
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=cJSON_GetObjectItemV2(object,string,&i);if(c){if(newitem->string) cJSON_free(newitem->string);newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}