mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Remove printing without buffer
This commit is contained in:
parent
80354bdb06
commit
9bf531ca05
608
cJSON.c
608
cJSON.c
@ -328,6 +328,12 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p)
|
|||||||
{
|
{
|
||||||
unsigned char *str = NULL;
|
unsigned char *str = NULL;
|
||||||
double d = item->valuedouble;
|
double d = item->valuedouble;
|
||||||
|
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* special case for 0. */
|
/* special case for 0. */
|
||||||
if (d == 0)
|
if (d == 0)
|
||||||
{
|
{
|
||||||
@ -678,6 +684,11 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p)
|
|||||||
cjbool flag = false;
|
cjbool flag = false;
|
||||||
unsigned char token = '\0';
|
unsigned char token = '\0';
|
||||||
|
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* empty string */
|
/* empty string */
|
||||||
if (!str)
|
if (!str)
|
||||||
{
|
{
|
||||||
@ -1028,101 +1039,71 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p
|
|||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
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:
|
|
||||||
{
|
|
||||||
size_t raw_length = 0;
|
|
||||||
if (item->valuestring == NULL)
|
|
||||||
{
|
|
||||||
if (!p->noalloc)
|
|
||||||
{
|
|
||||||
cJSON_free(p->buffer);
|
|
||||||
}
|
|
||||||
out = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
raw_length = strlen(item->valuestring) + sizeof('\0');
|
if (p == NULL)
|
||||||
out = ensure(p, raw_length);
|
{
|
||||||
if (out != NULL)
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
{
|
||||||
|
size_t raw_length = 0;
|
||||||
|
if (item->valuestring == NULL)
|
||||||
|
{
|
||||||
|
if (!p->noalloc)
|
||||||
{
|
{
|
||||||
memcpy(out, item->valuestring, raw_length);
|
cJSON_free(p->buffer);
|
||||||
}
|
}
|
||||||
|
out = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case cJSON_String:
|
|
||||||
out = print_string(item, p);
|
raw_length = strlen(item->valuestring) + sizeof('\0');
|
||||||
break;
|
out = ensure(p, raw_length);
|
||||||
case cJSON_Array:
|
if (out != NULL)
|
||||||
out = print_array(item, depth, fmt, p);
|
{
|
||||||
break;
|
memcpy(out, item->valuestring, raw_length);
|
||||||
case cJSON_Object:
|
}
|
||||||
out = print_object(item, depth, fmt, p);
|
break;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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;
|
return out;
|
||||||
@ -1209,16 +1190,18 @@ fail:
|
|||||||
/* Render an array to text */
|
/* Render an array to text */
|
||||||
static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p)
|
static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p)
|
||||||
{
|
{
|
||||||
unsigned char **entries;
|
|
||||||
unsigned char *out = NULL;
|
unsigned char *out = NULL;
|
||||||
unsigned char *ptr = NULL;
|
unsigned char *ptr = NULL;
|
||||||
unsigned char *ret = NULL;
|
|
||||||
size_t len = 5;
|
size_t len = 5;
|
||||||
cJSON *child = item->child;
|
cJSON *child = item->child;
|
||||||
size_t numentries = 0;
|
size_t numentries = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
cjbool fail = false;
|
cjbool fail = false;
|
||||||
size_t tmplen = 0;
|
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* How many entries in the array? */
|
/* How many entries in the array? */
|
||||||
while (child)
|
while (child)
|
||||||
@ -1239,131 +1222,51 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
|
|||||||
return out;
|
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. */
|
return NULL;
|
||||||
/* opening square bracket */
|
}
|
||||||
i = p->offset;
|
*ptr = '[';
|
||||||
ptr = ensure(p, 1);
|
p->offset++;
|
||||||
if (ptr == NULL)
|
|
||||||
|
child = item->child;
|
||||||
|
while (child && !fail)
|
||||||
|
{
|
||||||
|
if (!print_value(child, depth + 1, fmt, p))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
*ptr = '[';
|
p->offset = update(p);
|
||||||
p->offset++;
|
if (child->next)
|
||||||
|
|
||||||
child = item->child;
|
|
||||||
while (child && !fail)
|
|
||||||
{
|
{
|
||||||
if (!print_value(child, depth + 1, fmt, p))
|
len = fmt ? 2 : 1;
|
||||||
|
ptr = ensure(p, len + 1);
|
||||||
|
if (ptr == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
p->offset = update(p);
|
*ptr++ = ',';
|
||||||
if (child->next)
|
if(fmt)
|
||||||
{
|
{
|
||||||
len = fmt ? 2 : 1;
|
*ptr++ = ' ';
|
||||||
ptr = ensure(p, len + 1);
|
|
||||||
if (ptr == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*ptr++ = ',';
|
|
||||||
if(fmt)
|
|
||||||
{
|
|
||||||
*ptr++ = ' ';
|
|
||||||
}
|
|
||||||
*ptr = '\0';
|
|
||||||
p->offset += len;
|
|
||||||
}
|
}
|
||||||
child = child->next;
|
*ptr = '\0';
|
||||||
|
p->offset += len;
|
||||||
}
|
}
|
||||||
ptr = ensure(p, 2);
|
child = child->next;
|
||||||
if (ptr == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*ptr++ = ']';
|
|
||||||
*ptr = '\0';
|
|
||||||
out = (p->buffer) + i;
|
|
||||||
}
|
}
|
||||||
else
|
ptr = ensure(p, 2);
|
||||||
|
if (ptr == NULL)
|
||||||
{
|
{
|
||||||
/* Allocate an array to hold the pointers to all printed values */
|
return NULL;
|
||||||
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';
|
|
||||||
}
|
}
|
||||||
|
*ptr++ = ']';
|
||||||
|
*ptr = '\0';
|
||||||
|
out = (p->buffer) + i;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -1466,19 +1369,18 @@ fail:
|
|||||||
/* Render an object to text. */
|
/* Render an object to text. */
|
||||||
static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p)
|
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 *out = NULL;
|
||||||
unsigned char *ptr = NULL;
|
unsigned char *ptr = NULL;
|
||||||
unsigned char *ret = NULL;
|
|
||||||
unsigned char *str = NULL;
|
|
||||||
size_t len = 7;
|
size_t len = 7;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
cJSON *child = item->child;
|
cJSON *child = item->child;
|
||||||
size_t numentries = 0;
|
size_t numentries = 0;
|
||||||
cjbool fail = false;
|
|
||||||
size_t tmplen = 0;
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Count the number of entries. */
|
/* Count the number of entries. */
|
||||||
while (child)
|
while (child)
|
||||||
@ -1510,18 +1412,80 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
|
|||||||
return out;
|
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: */
|
return NULL;
|
||||||
i = p->offset;
|
}
|
||||||
len = fmt ? 2 : 1; /* fmt: {\n */
|
|
||||||
|
*ptr++ = '{';
|
||||||
|
if (fmt)
|
||||||
|
{
|
||||||
|
*ptr++ = '\n';
|
||||||
|
}
|
||||||
|
*ptr = '\0';
|
||||||
|
p->offset += len;
|
||||||
|
|
||||||
|
child = item->child;
|
||||||
|
depth++;
|
||||||
|
while (child)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
if (ptr == NULL)
|
||||||
|
{
|
||||||
|
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 = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0);
|
||||||
ptr = ensure(p, len + 1);
|
ptr = ensure(p, len + 1);
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (child->next)
|
||||||
|
{
|
||||||
|
*ptr++ = ',';
|
||||||
|
}
|
||||||
|
|
||||||
*ptr++ = '{';
|
|
||||||
if (fmt)
|
if (fmt)
|
||||||
{
|
{
|
||||||
*ptr++ = '\n';
|
*ptr++ = '\n';
|
||||||
@ -1529,210 +1493,24 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
|
|||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
p->offset += len;
|
p->offset += len;
|
||||||
|
|
||||||
child = item->child;
|
child = child->next;
|
||||||
depth++;
|
|
||||||
while (child)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
if (ptr == NULL)
|
|
||||||
{
|
|
||||||
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 = (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
ptr = ensure(p, fmt ? (depth + 1) : 2);
|
||||||
|
if (ptr == NULL)
|
||||||
{
|
{
|
||||||
/* Allocate space for the names and the objects */
|
return NULL;
|
||||||
entries = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*));
|
|
||||||
if (!entries)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
names = (unsigned char**)cJSON_malloc(numentries * sizeof(unsigned char*));
|
|
||||||
if (!names)
|
|
||||||
{
|
|
||||||
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++;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to allocate the output string */
|
|
||||||
if (!fail)
|
|
||||||
{
|
|
||||||
out = (unsigned 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((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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
cJSON_free(names);
|
|
||||||
cJSON_free(entries);
|
|
||||||
if (fmt)
|
|
||||||
{
|
|
||||||
for (i = 0; i < (depth - 1); i++)
|
|
||||||
{
|
|
||||||
*ptr++ = '\t';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*ptr++ = '}';
|
|
||||||
*ptr++ = '\0';
|
|
||||||
}
|
}
|
||||||
|
if (fmt)
|
||||||
|
{
|
||||||
|
for (i = 0; i < (depth - 1); i++)
|
||||||
|
{
|
||||||
|
*ptr++ = '\t';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr++ = '}';
|
||||||
|
*ptr = '\0';
|
||||||
|
out = (p->buffer) + i;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user