/* Render the number nicely from the given item into a string. */ static char *print_number(cJSON *item) { char *str; double d = item->valuedouble; if ( fabs(((double)item->valueint) - d) <= DBL_EPSILON && d >= (1. - DBL_EPSILON) && d < (1LL << 62) )//d <= INT_MAX && d >= INT_MIN ) { str = (char *)cJSON_malloc(24); /* 2^64+1 can be represented in 21 chars + sign. */ if ( str != 0 ) sprintf(str,"%lld",(long long)item->valueint); } else { str = (char *)cJSON_malloc(64); /* This is a nice tradeoff. */ if ( str != 0 ) { 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,"%.8f",d); } } return str; }
/* Render the number nicely from the given item into a string. */ static char * print_number(cJSON * item) { char *str; double d = item->valuedouble; 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); /* This is a nice tradeoff. */ if (str) { if (fabs(floor(d) - d) <= DBL_EPSILON) 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; }
/* Render the number nicely from the given item into a string. */ static char *print_number(cJSON * item, printbuffer * p) { char *str = 0; double d = item->valuedouble; if (d == 0) { if (p) str = ensure(p, 2); else str = (char *) cJSON_malloc(2); /* special case for 0. */ if (str) strcpy(str, "0"); } else if (fabs(((double) item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) { if (p) str = ensure(p, 21); else str = (char *) cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ if (str) sprintf(str, "%d", item->valueint); } else { if (p) str = ensure(p, 64); else str = (char *) cJSON_malloc(64); /* This is a nice tradeoff. */ 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 char* cJSONUtils_strdup(const unsigned char* const string) { size_t length = 0; unsigned char *copy = NULL; length = strlen((const char*)string) + sizeof(""); copy = (unsigned char*) cJSON_malloc(length); if (copy == NULL) { return NULL; } memcpy(copy, string, length); return copy; }
static char *ICACHE_FLASH_ATTR cJSON_strdup(const char *str) { size_t len; char *copy; len = strlen(str) + 1; if (!(copy = (char *)cJSON_malloc(len))) { return 0; } memcpy(copy, str, len); return copy; }
static char* ensure(printbuffer *p,int needed) { char *newbuffer;int newsize; if (!p || !p->buffer) return 0; needed+=p->offset; if (needed<=p->length) return p->buffer+p->offset; newsize=pow2gt(needed); newbuffer=(char*)cJSON_malloc(newsize); if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;} if (newbuffer) memcpy(newbuffer,p->buffer,p->length); cJSON_free(p->buffer); p->length=newsize; p->buffer=newbuffer; return newbuffer+p->offset; }
static const char *parse_string(cJSON *item,const char *str) { const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc; if (*str!='\"') return 0; /* not a string! */ while (*ptr!='\"' && (unsigned char)*ptr>31 && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ if (!out) return 0; ptr=str+1;ptr2=out; while (*ptr!='\"' && (unsigned char)*ptr>31) { if (*ptr!='\\') *ptr2++=*ptr++; else { ptr++; switch (*ptr) { case 'b': *ptr2++='\b'; break; case 'f': *ptr2++='\f'; break; case 'n': *ptr2++='\n'; break; case 'r': *ptr2++='\r'; break; case 't': *ptr2++='\t'; break; case 'u': /* transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY. */ sscanf(ptr+1,"%4x",&uc); /* get the unicode char. */ len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len; switch (len) { case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 1: *--ptr2 =(uc | firstByteMark[len]); } ptr2+=len;ptr+=4; break; default: *ptr2++=*ptr; break; } ptr++; } } *ptr2=0; if (*ptr=='\"') ptr++; item->valuestring=out; item->type=cJSON_String; return ptr; }
/* This will create an allocation pool */ static cJSON_Pool * cJSON_New_Pool() { if (CJSON_POOL_ALLOC_SIZE <= 0) { return 0; } else { cJSON_Pool * pool = (cJSON_Pool*)cJSON_malloc(sizeof(cJSON_Pool)); if (!pool) { return 0; } memset(pool, 0, sizeof(cJSON_Pool)); pool->free_items = 0; pool->blocks = 0; pool->refcount = 0; return pool; } }
/* Render the number nicely from the given item into a string. */ static char *print_number( cJSON *item ) { char *str; double f, f2; int64_t i; str = (char*) cJSON_malloc( 64 ); if ( str ) { f = item->valuefloat; i = f; f2 = i; if ( f2 == f && item->valueint >= LLONG_MIN && item->valueint <= LLONG_MAX ) sprintf( str, "%lld", (long long) item->valueint ); else sprintf( str, "%g", item->valuefloat ); } return str; }
/* Render the number nicely from the given item into a string. */ static char *print_number_2d(cJSON *item, int sample, ngx_pool_t *pool) { char *str; double d1 = 0,d2 = 0; if(sample >= item->d2_len) return NULL; if(item->d2_val1) d1 = item->d2_val1[sample]; if(item->d2_val2) d2 = item->d2_val2[sample]; /* This is a nice tradeoff. */ str=(char*)cJSON_malloc(pool, 64+64); if (str) { if(item->d2_val1) { if (fabs(floor(d1)-d1)<=DBL_EPSILON && fabs(d1)<1.0e60) sprintf(str,"%.04f",d1); else if (fabs(d1)<1.0e-2 || fabs(d1)>1.0e9) sprintf(str,"%.04e",d1); else sprintf(str,"%.04f",d1); } if(item->d2_val1 && item->d2_val2) { if (fabs(floor(d2)-d2)<=DBL_EPSILON && fabs(d2)<1.0e60) sprintf(str,"%s,%.04f",str, d2); else if (fabs(d2)<1.0e-2 || fabs(d2)>1.0e9) sprintf(str,"%s,%.04e",str, d2); else sprintf(str,"%s,%.04f",str, d2); } else if(item->d2_val2) { if (fabs(floor(d2)-d2)<=DBL_EPSILON && fabs(d2)<1.0e60) sprintf(str,"%.04f",d2); else if (fabs(d2)<1.0e-2 || fabs(d2)>1.0e9) sprintf(str,"%.04e",d2); else sprintf(str,"%.04f",d2); } } return str; }
/* Render the cstring provided to an escaped version that can be printed. */ static char *print_string_ptr(const char *str) { const char *ptr;char *ptr2,*out;int len=0;unsigned char token; int quote = 0; if (!str) return cJSON_strdup(""); ptr=str; while ((token=*ptr) && ++len) { if (strchr("\"\\\b\f\n\r\t",token)){ len++; quote = 1; } else if (token<32){ len+=5; quote = 1; } ptr++; } out=(char*)cJSON_malloc(len+3); if (!out) return 0; ptr2=out;ptr=str; if( quote ) *ptr2++='\"'; while (*ptr) { if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; else { *ptr2++='\\'; switch (token=*ptr++) { case '\\': *ptr2++='\\'; break; case '\"': *ptr2++='\"'; break; case '\b': *ptr2++='b'; break; case '\f': *ptr2++='f'; break; case '\n': *ptr2++='n'; break; case '\r': *ptr2++='r'; break; case '\t': *ptr2++='t'; break; default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ } } } if( quote )*ptr2++='\"'; *ptr2++=0; return out; }
static char *print_float(cJSON *item) { char *str = NULL; if (item && (item->type == cJSON_Float)) { double d=item->valuedouble; str=(char*)cJSON_malloc(64); // This is a nice tradeoff. if (str) { if (fabs(floor(d)-d)<=DBL_EPSILON) { 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; }
/* realloc printbuffer if necessary to have at least "needed" bytes more */ static char* ensure(printbuffer *p, int needed) { char *newbuffer = NULL; int newsize = 0; if (!p || !p->buffer) { return NULL; } needed += p->offset; if (needed <= p->length) { return p->buffer + p->offset; } if (p->noalloc) { return NULL; } newsize = pow2gt(needed); newbuffer = (char*)cJSON_malloc(newsize); if (!newbuffer) { cJSON_free(p->buffer); p->length = 0; p->buffer = NULL; return NULL; } if (newbuffer) { memcpy(newbuffer, p->buffer, p->length); } cJSON_free(p->buffer); p->length = newsize; p->buffer = newbuffer; return newbuffer + p->offset; }
static const char *ICACHE_FLASH_ATTR parse_string(cJSON *item, const char *str) { const char *ptr = str + 1; char *ptr2; char *out; int len = 0; unsigned uc, uc2; if (*str != '\"') { ep = str; /* not a string! */ return 0; } while (*ptr != '\"' && *ptr && ++len) if (*ptr++ == '\\') { ptr++; /* Skip escaped quotes. */ } out = (char *)cJSON_malloc(len + 1); /* This is how long we need for the string, roughly. */ if (!out) { return 0; } ptr = str + 1; ptr2 = out; while (*ptr != '\"' && *ptr) { if (*ptr != '\\') { *ptr2++ = *ptr++; } else { ptr++; switch (*ptr) { case 'b': *ptr2++ = '\b'; break; case 'f': *ptr2++ = '\f'; break; case 'n': *ptr2++ = '\n'; break; case 'r': *ptr2++ = '\r'; break; case 't': *ptr2++ = '\t'; break; case 'u': /* transcode utf16 to utf8. */ uc = parse_hex4(ptr + 1); ptr += 4; /* get the unicode char. */ if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) { break; /* check for invalid. */ } if (uc >= 0xD800 && uc <= 0xDBFF) { /* UTF16 surrogate pairs. */ if (ptr[1] != '\\' || ptr[2] != 'u') { break; /* missing second-half of surrogate. */ } uc2 = parse_hex4(ptr + 3); ptr += 6; if (uc2 < 0xDC00 || uc2 > 0xDFFF) { break; /* invalid second-half of surrogate. */ } 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; } ptr2 += len; switch (len) { case 4: *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; case 3: *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; case 2: *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; case 1: *--ptr2 = (uc | firstByteMark[len]); } ptr2 += len; break; default: *ptr2++ = *ptr; break; } ptr++; } } *ptr2 = 0; if (*ptr == '\"') { ptr++; } item->valuestring = out; item->type = cJSON_String; return ptr; }
/* Internal constructor. */ static cJSON *cJSON_New_Item() { cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); if (node) memset(node,0,sizeof(cJSON)); return node; }
/* 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 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; }
/* Render the cstring provided to an escaped version that can be printed. */ static char *print_string_ptr(const char *str, printbuffer *p) { const char *ptr; char *ptr2, *out; int len = 0, flag = 0; unsigned char token; for(ptr = str; *ptr; ptr++) flag |= ((*ptr > 0 && *ptr < 32) || (*ptr == '\"') || (*ptr == '\\')) ? 1 : 0; if(!flag) { len = ptr - str; if(p) out = ensure(p, len + 3); else out = (char*) cJSON_malloc(len + 3); if(!out) return 0; ptr2 = out; *ptr2++ = '\"'; strcpy(ptr2, str); ptr2[len] = '\"'; ptr2[len + 1] = 0; return out; } if(!str) { if(p) out = ensure(p, 3); else out = (char*) cJSON_malloc(3); if(!out) return 0; strcpy(out, "\"\""); return out; } ptr = str; while((token = *ptr) && ++len) { if(strchr("\"\\\b\f\n\r\t", token)) len++; else if(token < 32) len += 5; ptr++; } if(p) out = ensure(p, len + 3); else out = (char*) cJSON_malloc(len + 3); if(!out) return 0; ptr2 = out; ptr = str; *ptr2++ = '\"'; while(*ptr) { if((unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\') *ptr2++ = *ptr++; else { *ptr2++ = '\\'; switch(token = *ptr++) { case '\\': *ptr2++ = '\\'; break; case '\"': *ptr2++ = '\"'; break; case '\b': *ptr2++ = 'b'; break; case '\f': *ptr2++ = 'f'; break; case '\n': *ptr2++ = 'n'; break; case '\r': *ptr2++ = 'r'; break; case '\t': *ptr2++ = 't'; break; default: sprintf(ptr2, "u%04x", token); ptr2 += 5; break; // escape and print } } } *ptr2++ = '\"'; *ptr2++ = 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 the cstring provided to an escaped version that can be printed. */ static char *print_string_ptr(const char *str, printbuffer *p) { const char *ptr = NULL; char *ptr2 = NULL; char *out = NULL; int len = 0; cjbool flag = false; unsigned char token = '\0'; /* empty string */ if (!str) { if (p) { out = ensure(p, 3); } else { out = (char*)cJSON_malloc(3); } if (!out) { return NULL; } strcpy(out, "\"\""); return out; } /* set "flag" to 1 if something needs to be escaped */ for (ptr = str; *ptr; ptr++) { flag |= (((*ptr > 0) && (*ptr < 32)) /* unprintable characters */ || (*ptr == '\"') /* double quote */ || (*ptr == '\\')) /* backslash */ ? 1 : 0; } /* no characters have to be escaped */ if (!flag) { len = ptr - str; if (p) { out = ensure(p, len + 3); } else { out = (char*)cJSON_malloc(len + 3); } if (!out) { return NULL; } ptr2 = out; *ptr2++ = '\"'; strcpy(ptr2, str); ptr2[len] = '\"'; ptr2[len + 1] = '\0'; return out; } ptr = str; /* calculate additional space that is needed for escaping */ while ((token = *ptr)) { ++len; if (strchr("\"\\\b\f\n\r\t", token)) { len++; /* +1 for the backslash */ } else if (token < 32) { len += 5; /* +5 for \uXXXX */ } ptr++; } if (p) { out = ensure(p, len + 3); } else { out = (char*)cJSON_malloc(len + 3); } if (!out) { return NULL; } ptr2 = out; ptr = str; *ptr2++ = '\"'; /* copy the string */ while (*ptr) { if (((unsigned char)*ptr > 31) && (*ptr != '\"') && (*ptr != '\\')) { /* normal character, copy */ *ptr2++ = *ptr++; } else { /* character needs to be escaped */ *ptr2++ = '\\'; switch (token = *ptr++) { case '\\': *ptr2++ = '\\'; break; case '\"': *ptr2++ = '\"'; break; case '\b': *ptr2++ = 'b'; break; case '\f': *ptr2++ = 'f'; break; case '\n': *ptr2++ = 'n'; break; case '\r': *ptr2++ = 'r'; break; case '\t': *ptr2++ = 't'; break; default: /* escape and print as unicode codepoint */ sprintf(ptr2, "u%04x", token); ptr2 += 5; break; } } } *ptr2++ = '\"'; *ptr2++ = '\0'; return out; }
/* Parse the input text into an unescaped cstring, and populate item. */ static const char *parse_string(cJSON *item, const char *str, const char **ep) { const char *ptr = str + 1; const char *end_ptr =str + 1; char *ptr2 = NULL; char *out = NULL; int len = 0; unsigned uc = 0; unsigned uc2 = 0; /* not a string! */ if (*str != '\"') { *ep = str; return NULL; } while ((*end_ptr != '\"') && *end_ptr && ++len) { if (*end_ptr++ == '\\') { if (*end_ptr == '\0') { /* prevent buffer overflow when last input character is a backslash */ return NULL; } /* Skip escaped quotes. */ end_ptr++; } } /* This is at most how long we need for the string, roughly. */ out = (char*)cJSON_malloc(len + 1); if (!out) { return NULL; } item->valuestring = out; /* assign here so out will be deleted during cJSON_Delete() later */ item->type = cJSON_String; ptr = str + 1; ptr2 = out; /* loop through the string literal */ while (ptr < end_ptr) { if (*ptr != '\\') { *ptr2++ = *ptr++; } /* escape sequence */ else { ptr++; switch (*ptr) { case 'b': *ptr2++ = '\b'; break; case 'f': *ptr2++ = '\f'; break; case 'n': *ptr2++ = '\n'; break; case 'r': *ptr2++ = '\r'; break; case 't': *ptr2++ = '\t'; break; case '\"': case '\\': case '/': *ptr2++ = *ptr; break; case 'u': /* transcode utf16 to utf8. See RFC2781 and RFC3629. */ uc = parse_hex4(ptr + 1); /* get the unicode char. */ ptr += 4; if (ptr >= end_ptr) { /* invalid */ *ep = str; return NULL; } /* check for invalid. */ if (((uc >= 0xDC00) && (uc <= 0xDFFF)) || (uc == 0)) { *ep = str; return NULL; } /* UTF16 surrogate pairs. */ if ((uc >= 0xD800) && (uc<=0xDBFF)) { if ((ptr + 6) > end_ptr) { /* invalid */ *ep = str; return NULL; } if ((ptr[1] != '\\') || (ptr[2] != 'u')) { /* missing second-half of surrogate. */ *ep = str; return NULL; } uc2 = parse_hex4(ptr + 3); ptr += 6; /* \uXXXX */ if ((uc2 < 0xDC00) || (uc2 > 0xDFFF)) { /* invalid second-half of surrogate. */ *ep = str; return NULL; } /* calculate unicode codepoint from the surrogate pair */ uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF)); } /* encode as UTF8 * takes at maximum 4 bytes to encode: * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ len = 4; if (uc < 0x80) { /* normal ascii, encoding 0xxxxxxx */ len = 1; } else if (uc < 0x800) { /* two bytes, encoding 110xxxxx 10xxxxxx */ len = 2; } else if (uc < 0x10000) { /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ len = 3; } ptr2 += len; switch (len) { case 4: /* 10xxxxxx */ *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; case 3: /* 10xxxxxx */ *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; case 2: /* 10xxxxxx */ *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; case 1: /* depending on the length in bytes this determines the * encoding ofthe first UTF8 byte */ *--ptr2 = (uc | firstByteMark[len]); } ptr2 += len; break; default: *ep = str; return NULL; } ptr++; } } *ptr2 = '\0'; if (*ptr == '\"') { ptr++; } return ptr; }
/* 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; }
static const char *parse_string(cJSON *item,const char *str) { const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; if (*str!='\"') {ep=str;return 0;} /* not a string! */ while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ if (!out) return 0; ptr=str+1;ptr2=out; while (*ptr!='\"' && *ptr) { if (*ptr!='\\') *ptr2++=*ptr++; else { ptr++; switch (*ptr) { case 'b': *ptr2++='\b'; break; case 'f': *ptr2++='\f'; break; case 'n': *ptr2++='\n'; break; case 'r': *ptr2++='\r'; break; case 't': *ptr2++='\t'; break; case 'u': /* transcode utf16 to utf8. */ if (sscanf(ptr+1,"%4x",&uc) < 1) break; ptr+=4; /* get the unicode char. */ if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid. if (uc>=0xD800 && uc<=0xDBFF) // UTF16 surrogate pairs. { if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate. if (sscanf(ptr+3,"%4x",&uc2) < 1) break; ptr+=6; if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate. 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; ptr2+=len; switch (len) { case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; case 1: *--ptr2 =(char)(uc | firstByteMark[len]); } ptr2+=len; break; default: *ptr2++=*ptr; break; } ptr++; } } *ptr2=0; if (*ptr=='\"') ptr++; item->valuestring=out; item->type=cJSON_String; return ptr; }
/* 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; }
/* Internal constructor. */ static cJSON *cJSON_New_Item(mp_pool_t *p) { cJSON* node = (cJSON*)cJSON_malloc(p,sizeof(cJSON)); if (node) {memset(node,0,sizeof(cJSON)); node->pool = p;} return node; }
/* 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; }
/* 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 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; }
/* 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; }
/* 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; }