|
|
@ -328,6 +328,12 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p) |
|
|
|
{ |
|
|
|
unsigned char *str = NULL; |
|
|
|
double d = item->valuedouble; |
|
|
|
|
|
|
|
if (p == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* special case for 0. */ |
|
|
|
if (d == 0) |
|
|
|
{ |
|
|
@ -678,6 +684,11 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) |
|
|
|
cjbool flag = false; |
|
|
|
unsigned char token = '\0'; |
|
|
|
|
|
|
|
if (p == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* empty string */ |
|
|
|
if (!str) |
|
|
|
{ |
|
|
@ -1028,101 +1039,71 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
if (p) |
|
|
|
|
|
|
|
if (p == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
switch ((item->type) & 0xFF) |
|
|
|
{ |
|
|
|
switch ((item->type) & 0xFF) |
|
|
|
case cJSON_NULL: |
|
|
|
out = ensure(p, 5); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
strcpy((char*)out, "null"); |
|
|
|
} |
|
|
|
break; |
|
|
|
case cJSON_False: |
|
|
|
out = ensure(p, 6); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
strcpy((char*)out, "false"); |
|
|
|
} |
|
|
|
break; |
|
|
|
case cJSON_True: |
|
|
|
out = ensure(p, 5); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
strcpy((char*)out, "true"); |
|
|
|
} |
|
|
|
break; |
|
|
|
case cJSON_Number: |
|
|
|
out = print_number(item, p); |
|
|
|
break; |
|
|
|
case cJSON_Raw: |
|
|
|
{ |
|
|
|
case cJSON_NULL: |
|
|
|
out = ensure(p, 5); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
strcpy((char*)out, "null"); |
|
|
|
} |
|
|
|
break; |
|
|
|
case cJSON_False: |
|
|
|
out = ensure(p, 6); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
strcpy((char*)out, "false"); |
|
|
|
} |
|
|
|
break; |
|
|
|
case cJSON_True: |
|
|
|
out = ensure(p, 5); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
strcpy((char*)out, "true"); |
|
|
|
} |
|
|
|
break; |
|
|
|
case cJSON_Number: |
|
|
|
out = print_number(item, p); |
|
|
|
break; |
|
|
|
case cJSON_Raw: |
|
|
|
size_t raw_length = 0; |
|
|
|
if (item->valuestring == NULL) |
|
|
|
{ |
|
|
|
size_t raw_length = 0; |
|
|
|
if (item->valuestring == NULL) |
|
|
|
if (!p->noalloc) |
|
|
|
{ |
|
|
|
if (!p->noalloc) |
|
|
|
{ |
|
|
|
cJSON_free(p->buffer); |
|
|
|
} |
|
|
|
out = NULL; |
|
|
|
break; |
|
|
|
cJSON_free(p->buffer); |
|
|
|
} |
|
|
|
|
|
|
|
raw_length = strlen(item->valuestring) + sizeof('\0'); |
|
|
|
out = ensure(p, raw_length); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
memcpy(out, item->valuestring, raw_length); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
case cJSON_String: |
|
|
|
out = print_string(item, p); |
|
|
|
break; |
|
|
|
case cJSON_Array: |
|
|
|
out = print_array(item, depth, fmt, p); |
|
|
|
break; |
|
|
|
case cJSON_Object: |
|
|
|
out = print_object(item, depth, fmt, p); |
|
|
|
break; |
|
|
|
default: |
|
|
|
out = NULL; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
switch ((item->type) & 0xFF) |
|
|
|
{ |
|
|
|
case cJSON_NULL: |
|
|
|
out = cJSON_strdup((const unsigned char*)"null"); |
|
|
|
break; |
|
|
|
case cJSON_False: |
|
|
|
out = cJSON_strdup((const unsigned char*)"false"); |
|
|
|
break; |
|
|
|
case cJSON_True: |
|
|
|
out = cJSON_strdup((const unsigned char*)"true"); |
|
|
|
break; |
|
|
|
case cJSON_Number: |
|
|
|
out = print_number(item, 0); |
|
|
|
break; |
|
|
|
case cJSON_Raw: |
|
|
|
out = cJSON_strdup((unsigned char*)item->valuestring); |
|
|
|
break; |
|
|
|
case cJSON_String: |
|
|
|
out = print_string(item, 0); |
|
|
|
break; |
|
|
|
case cJSON_Array: |
|
|
|
out = print_array(item, depth, fmt, 0); |
|
|
|
break; |
|
|
|
case cJSON_Object: |
|
|
|
out = print_object(item, depth, fmt, 0); |
|
|
|
break; |
|
|
|
default: |
|
|
|
out = NULL; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
raw_length = strlen(item->valuestring) + sizeof('\0'); |
|
|
|
out = ensure(p, raw_length); |
|
|
|
if (out != NULL) |
|
|
|
{ |
|
|
|
memcpy(out, item->valuestring, raw_length); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
case cJSON_String: |
|
|
|
out = print_string(item, p); |
|
|
|
break; |
|
|
|
case cJSON_Array: |
|
|
|
out = print_array(item, depth, fmt, p); |
|
|
|
break; |
|
|
|
case cJSON_Object: |
|
|
|
out = print_object(item, depth, fmt, p); |
|
|
|
break; |
|
|
|
default: |
|
|
|
out = NULL; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
return out; |
|
|
@ -1209,16 +1190,18 @@ fail: |
|
|
|
/* Render an array to text */ |
|
|
|
static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p) |
|
|
|
{ |
|
|
|
unsigned char **entries; |
|
|
|
unsigned char *out = NULL; |
|
|
|
unsigned char *ptr = NULL; |
|
|
|
unsigned char *ret = NULL; |
|
|
|
size_t len = 5; |
|
|
|
cJSON *child = item->child; |
|
|
|
size_t numentries = 0; |
|
|
|
size_t i = 0; |
|
|
|
cjbool fail = false; |
|
|
|
size_t tmplen = 0; |
|
|
|
|
|
|
|
if (p == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* How many entries in the array? */ |
|
|
|
while (child) |
|
|
@ -1239,131 +1222,51 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p |
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
if (p) |
|
|
|
/* Compose the output array. */ |
|
|
|
/* opening square bracket */ |
|
|
|
i = p->offset; |
|
|
|
ptr = ensure(p, 1); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
/* Compose the output array. */ |
|
|
|
/* opening square bracket */ |
|
|
|
i = p->offset; |
|
|
|
ptr = ensure(p, 1); |
|
|
|
if (ptr == NULL) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
*ptr = '['; |
|
|
|
p->offset++; |
|
|
|
|
|
|
|
child = item->child; |
|
|
|
while (child && !fail) |
|
|
|
{ |
|
|
|
if (!print_value(child, depth + 1, fmt, p)) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
*ptr = '['; |
|
|
|
p->offset++; |
|
|
|
|
|
|
|
child = item->child; |
|
|
|
while (child && !fail) |
|
|
|
p->offset = update(p); |
|
|
|
if (child->next) |
|
|
|
{ |
|
|
|
if (!print_value(child, depth + 1, fmt, p)) |
|
|
|
len = fmt ? 2 : 1; |
|
|
|
ptr = ensure(p, len + 1); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
p->offset = update(p); |
|
|
|
if (child->next) |
|
|
|
*ptr++ = ','; |
|
|
|
if(fmt) |
|
|
|
{ |
|
|
|
len = fmt ? 2 : 1; |
|
|
|
ptr = ensure(p, len + 1); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
*ptr++ = ','; |
|
|
|
if(fmt) |
|
|
|
{ |
|
|
|
*ptr++ = ' '; |
|
|
|
} |
|
|
|
*ptr = '\0'; |
|
|
|
p->offset += len; |
|
|
|
*ptr++ = ' '; |
|
|
|
} |
|
|
|
child = child->next; |
|
|
|
} |
|
|
|
ptr = ensure(p, 2); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
*ptr = '\0'; |
|
|
|
p->offset += len; |
|
|
|
} |
|
|
|
*ptr++ = ']'; |
|
|
|
*ptr = '\0'; |
|
|
|
out = (p->buffer) + i; |
|
|
|
child = child->next; |
|
|
|
} |
|
|
|
else |
|
|
|
ptr = ensure(p, 2); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
/* Allocate an array to hold the pointers to all printed values */ |
|
|
|
entries = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*)); |
|
|
|
if (!entries) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
memset(entries, '\0', numentries * sizeof(unsigned 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((char*)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 = (unsigned 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((char*)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 NULL; |
|
|
|
} |
|
|
|
*ptr++ = ']'; |
|
|
|
*ptr = '\0'; |
|
|
|
out = (p->buffer) + i; |
|
|
|
|
|
|
|
return out; |
|
|
|
} |
|
|
@ -1466,19 +1369,18 @@ fail: |
|
|
|
/* Render an object to text. */ |
|
|
|
static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p) |
|
|
|
{ |
|
|
|
unsigned char **entries = NULL; |
|
|
|
unsigned char **names = NULL; |
|
|
|
unsigned char *out = NULL; |
|
|
|
unsigned char *ptr = NULL; |
|
|
|
unsigned char *ret = NULL; |
|
|
|
unsigned char *str = NULL; |
|
|
|
size_t len = 7; |
|
|
|
size_t i = 0; |
|
|
|
size_t j = 0; |
|
|
|
cJSON *child = item->child; |
|
|
|
size_t numentries = 0; |
|
|
|
cjbool fail = false; |
|
|
|
size_t tmplen = 0; |
|
|
|
|
|
|
|
if (p == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* Count the number of entries. */ |
|
|
|
while (child) |
|
|
@ -1510,229 +1412,105 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, |
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
if (p) |
|
|
|
/* Compose the output: */ |
|
|
|
i = p->offset; |
|
|
|
len = fmt ? 2 : 1; /* fmt: {\n */ |
|
|
|
ptr = ensure(p, len + 1); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
/* Compose the output: */ |
|
|
|
i = p->offset; |
|
|
|
len = fmt ? 2 : 1; /* fmt: {\n */ |
|
|
|
ptr = ensure(p, len + 1); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
*ptr++ = '{'; |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
*ptr++ = '\n'; |
|
|
|
} |
|
|
|
*ptr = '\0'; |
|
|
|
p->offset += len; |
|
|
|
*ptr++ = '{'; |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
*ptr++ = '\n'; |
|
|
|
} |
|
|
|
*ptr = '\0'; |
|
|
|
p->offset += len; |
|
|
|
|
|
|
|
child = item->child; |
|
|
|
depth++; |
|
|
|
while (child) |
|
|
|
child = item->child; |
|
|
|
depth++; |
|
|
|
while (child) |
|
|
|
{ |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
ptr = ensure(p, depth); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
for (j = 0; j < depth; j++) |
|
|
|
{ |
|
|
|
*ptr++ = '\t'; |
|
|
|
} |
|
|
|
p->offset += depth; |
|
|
|
} |
|
|
|
|
|
|
|
/* print key */ |
|
|
|
if (!print_string_ptr((unsigned char*)child->string, p)) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
p->offset = update(p); |
|
|
|
|
|
|
|
len = fmt ? 2 : 1; |
|
|
|
ptr = ensure(p, len); |
|
|
|
ptr = ensure(p, depth); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
*ptr++ = ':'; |
|
|
|
if (fmt) |
|
|
|
for (j = 0; j < depth; j++) |
|
|
|
{ |
|
|
|
*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 = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0); |
|
|
|
ptr = ensure(p, len + 1); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
if (child->next) |
|
|
|
{ |
|
|
|
*ptr++ = ','; |
|
|
|
} |
|
|
|
|
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
*ptr++ = '\n'; |
|
|
|
} |
|
|
|
*ptr = '\0'; |
|
|
|
p->offset += len; |
|
|
|
|
|
|
|
child = child->next; |
|
|
|
p->offset += depth; |
|
|
|
} |
|
|
|
|
|
|
|
ptr = ensure(p, fmt ? (depth + 1) : 2); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
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 = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*)); |
|
|
|
if (!entries) |
|
|
|
/* print key */ |
|
|
|
if (!print_string_ptr((unsigned char*)child->string, p)) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
names = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*)); |
|
|
|
if (!names) |
|
|
|
p->offset = update(p); |
|
|
|
|
|
|
|
len = fmt ? 2 : 1; |
|
|
|
ptr = ensure(p, len); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
cJSON_free(entries); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
memset(entries, '\0', sizeof(unsigned char*) * numentries); |
|
|
|
memset(names, '\0', sizeof(unsigned char*) * numentries); |
|
|
|
|
|
|
|
/* Collect all the results into our arrays: */ |
|
|
|
child = item->child; |
|
|
|
depth++; |
|
|
|
*ptr++ = ':'; |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
len += depth; |
|
|
|
} |
|
|
|
while (child && !fail) |
|
|
|
{ |
|
|
|
names[i] = str = print_string_ptr((unsigned char*)child->string, 0); /* print key */ |
|
|
|
entries[i++] = ret = print_value(child, depth, fmt, 0); |
|
|
|
if (str && ret) |
|
|
|
{ |
|
|
|
len += strlen((char*)ret) + strlen((char*)str) + 2 + (fmt ? 2 + depth : 0); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
fail = true; |
|
|
|
} |
|
|
|
child = child->next; |
|
|
|
*ptr++ = '\t'; |
|
|
|
} |
|
|
|
p->offset+=len; |
|
|
|
|
|
|
|
/* Try to allocate the output string */ |
|
|
|
if (!fail) |
|
|
|
{ |
|
|
|
out = (unsigned char*)cJSON_malloc(len); |
|
|
|
} |
|
|
|
if (!out) |
|
|
|
/* print value */ |
|
|
|
if (!print_value(child, depth, fmt, p)) |
|
|
|
{ |
|
|
|
fail = true; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
p->offset = update(p); |
|
|
|
|
|
|
|
/* Handle failure */ |
|
|
|
if (fail) |
|
|
|
/* print comma if not last */ |
|
|
|
len = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0); |
|
|
|
ptr = ensure(p, len + 1); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
/* 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; |
|
|
|
} |
|
|
|
if (child->next) |
|
|
|
{ |
|
|
|
*ptr++ = ','; |
|
|
|
} |
|
|
|
|
|
|
|
/* 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((char*)names[i]); |
|
|
|
memcpy(ptr, names[i], tmplen); |
|
|
|
ptr += tmplen; |
|
|
|
*ptr++ = ':'; |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
*ptr++ = '\t'; |
|
|
|
} |
|
|
|
strcpy((char*)ptr, (char*)entries[i]); |
|
|
|
ptr += strlen((char*)entries[i]); |
|
|
|
if (i != (numentries - 1)) |
|
|
|
{ |
|
|
|
*ptr++ = ','; |
|
|
|
} |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
*ptr++ = '\n'; |
|
|
|
} |
|
|
|
*ptr = '\0'; |
|
|
|
cJSON_free(names[i]); |
|
|
|
cJSON_free(entries[i]); |
|
|
|
} |
|
|
|
p->offset += len; |
|
|
|
|
|
|
|
cJSON_free(names); |
|
|
|
cJSON_free(entries); |
|
|
|
if (fmt) |
|
|
|
child = child->next; |
|
|
|
} |
|
|
|
|
|
|
|
ptr = ensure(p, fmt ? (depth + 1) : 2); |
|
|
|
if (ptr == NULL) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
if (fmt) |
|
|
|
{ |
|
|
|
for (i = 0; i < (depth - 1); i++) |
|
|
|
{ |
|
|
|
for (i = 0; i < (depth - 1); i++) |
|
|
|
{ |
|
|
|
*ptr++ = '\t'; |
|
|
|
} |
|
|
|
*ptr++ = '\t'; |
|
|
|
} |
|
|
|
*ptr++ = '}'; |
|
|
|
*ptr++ = '\0'; |
|
|
|
} |
|
|
|
*ptr++ = '}'; |
|
|
|
*ptr = '\0'; |
|
|
|
out = (p->buffer) + i; |
|
|
|
|
|
|
|
return out; |
|
|
|
} |
|
|
|