mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Merge branch 'print_preallocated'
This commit is contained in:
13
Makefile
13
Makefile
@@ -5,6 +5,9 @@ UTILS_LIBNAME = libcjson_utils
|
|||||||
CJSON_TEST = cJSON_test
|
CJSON_TEST = cJSON_test
|
||||||
UTILS_TEST = cJSON_test_utils
|
UTILS_TEST = cJSON_test_utils
|
||||||
|
|
||||||
|
CJSON_TEST_SRC = cJSON.c test.c
|
||||||
|
UTILS_TEST_SRC = cJSON.c cJSON_Utils.c test_utils.c
|
||||||
|
|
||||||
LDLIBS = -lm
|
LDLIBS = -lm
|
||||||
|
|
||||||
LIBVERSION = 1.0.2
|
LIBVERSION = 1.0.2
|
||||||
@@ -27,7 +30,7 @@ uname := $(shell sh -c 'uname -s 2>/dev/null || echo false')
|
|||||||
#library file extensions
|
#library file extensions
|
||||||
SHARED = so
|
SHARED = so
|
||||||
STATIC = a
|
STATIC = a
|
||||||
|
|
||||||
## create dynamic (shared) library on Darwin (base OS for MacOSX and IOS)
|
## create dynamic (shared) library on Darwin (base OS for MacOSX and IOS)
|
||||||
ifeq (Darwin, $(uname))
|
ifeq (Darwin, $(uname))
|
||||||
SHARED = dylib
|
SHARED = dylib
|
||||||
@@ -66,11 +69,11 @@ test: tests
|
|||||||
|
|
||||||
#tests
|
#tests
|
||||||
#cJSON
|
#cJSON
|
||||||
$(CJSON_TEST): cJSON.c cJSON.h test.c
|
$(CJSON_TEST): $(CJSON_TEST_SRC) cJSON.h
|
||||||
$(CC) $(R_CFLAGS) $^ -o $@ $(LDLIBS) -I.
|
$(CC) $(R_CFLAGS) $(CJSON_TEST_SRC) -o $@ $(LDLIBS) -I.
|
||||||
#cJSON_Utils
|
#cJSON_Utils
|
||||||
$(UTILS_TEST): cJSON.c cJSON.h test.c
|
$(UTILS_TEST): $(UTILS_TEST_SRC) cJSON.h cJSON_Utils.h
|
||||||
$(CC) $(R_CFLAGS) $^ -o $@ $(LDLIBS) -I.
|
$(CC) $(R_CFLAGS) $(UTILS_TEST_SRC) -o $@ $(LDLIBS) -I.
|
||||||
|
|
||||||
#static libraries
|
#static libraries
|
||||||
#cJSON
|
#cJSON
|
||||||
|
30
cJSON.c
30
cJSON.c
@@ -244,6 +244,7 @@ typedef struct
|
|||||||
char *buffer;
|
char *buffer;
|
||||||
int length;
|
int length;
|
||||||
int offset;
|
int offset;
|
||||||
|
cjbool noalloc;
|
||||||
} printbuffer;
|
} printbuffer;
|
||||||
|
|
||||||
/* realloc printbuffer if necessary to have at least "needed" bytes more */
|
/* realloc printbuffer if necessary to have at least "needed" bytes more */
|
||||||
@@ -261,6 +262,10 @@ static char* ensure(printbuffer *p, int needed)
|
|||||||
return p->buffer + p->offset;
|
return p->buffer + p->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->noalloc) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
newsize = pow2gt(needed);
|
newsize = pow2gt(needed);
|
||||||
newbuffer = (char*)cJSON_malloc(newsize);
|
newbuffer = (char*)cJSON_malloc(newsize);
|
||||||
if (!newbuffer)
|
if (!newbuffer)
|
||||||
@@ -883,10 +888,20 @@ char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt)
|
|||||||
}
|
}
|
||||||
p.length = prebuffer;
|
p.length = prebuffer;
|
||||||
p.offset = 0;
|
p.offset = 0;
|
||||||
|
p.noalloc = false;
|
||||||
|
|
||||||
return print_value(item, 0, fmt, &p);
|
return print_value(item, 0, fmt, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cJSON_PrintPreallocated(cJSON *item,char *buf, const int len, const cjbool fmt)
|
||||||
|
{
|
||||||
|
printbuffer p;
|
||||||
|
p.buffer = buf;
|
||||||
|
p.length = len;
|
||||||
|
p.offset = 0;
|
||||||
|
p.noalloc = true;
|
||||||
|
return print_value(item,0,fmt,&p) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parser core - when encountering text, process appropriately. */
|
/* Parser core - when encountering text, process appropriately. */
|
||||||
static const char *parse_value(cJSON *item, const char *value, const char **ep)
|
static const char *parse_value(cJSON *item, const char *value, const char **ep)
|
||||||
@@ -1138,7 +1153,10 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *
|
|||||||
child = item->child;
|
child = item->child;
|
||||||
while (child && !fail)
|
while (child && !fail)
|
||||||
{
|
{
|
||||||
print_value(child, depth + 1, fmt, p);
|
if (!print_value(child, depth + 1, fmt, p))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
p->offset = update(p);
|
p->offset = update(p);
|
||||||
if (child->next)
|
if (child->next)
|
||||||
{
|
{
|
||||||
@@ -1435,7 +1453,10 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* print key */
|
/* print key */
|
||||||
print_string_ptr(child->string, p);
|
if (!print_string_ptr(child->string, p))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
p->offset = update(p);
|
p->offset = update(p);
|
||||||
|
|
||||||
len = fmt ? 2 : 1;
|
len = fmt ? 2 : 1;
|
||||||
@@ -1452,7 +1473,10 @@ static char *print_object(const cJSON *item, int depth, cjbool fmt, printbuffer
|
|||||||
p->offset+=len;
|
p->offset+=len;
|
||||||
|
|
||||||
/* print value */
|
/* print value */
|
||||||
print_value(child, depth, fmt, p);
|
if (!print_value(child, depth, fmt, p))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
p->offset = update(p);
|
p->offset = update(p);
|
||||||
|
|
||||||
/* print comma if not last */
|
/* print comma if not last */
|
||||||
|
2
cJSON.h
2
cJSON.h
@@ -83,6 +83,8 @@ extern char *cJSON_Print(const cJSON *item);
|
|||||||
extern char *cJSON_PrintUnformatted(const cJSON *item);
|
extern char *cJSON_PrintUnformatted(const cJSON *item);
|
||||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||||
extern char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, int fmt);
|
extern char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, int fmt);
|
||||||
|
/* Render a cJSON entity to text using a buffer already allocated in memory with length buf_len */
|
||||||
|
extern int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const int fmt);
|
||||||
/* Delete a cJSON entity and all subentities. */
|
/* Delete a cJSON entity and all subentities. */
|
||||||
extern void cJSON_Delete(cJSON *c);
|
extern void cJSON_Delete(cJSON *c);
|
||||||
|
|
||||||
|
107
test.c
107
test.c
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
|
|
||||||
/* Parse text to JSON, then render back to text, and print! */
|
/* Parse text to JSON, then render back to text, and print! */
|
||||||
@@ -83,6 +84,63 @@ struct record
|
|||||||
const char *country;
|
const char *country;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a bunch of objects as demonstration. */
|
||||||
|
int print_preallocated(cJSON *root)
|
||||||
|
{
|
||||||
|
/* declarations */
|
||||||
|
char *out = NULL;
|
||||||
|
char *buf = NULL;
|
||||||
|
char *buf_fail = NULL;
|
||||||
|
int len = 0;
|
||||||
|
int len_fail = 0;
|
||||||
|
|
||||||
|
/* formatted print */
|
||||||
|
out = cJSON_Print(root);
|
||||||
|
|
||||||
|
/* create buffer to succeed */
|
||||||
|
/* the extra 64 bytes are in case a floating point value is printed */
|
||||||
|
len = strlen(out) + 64;
|
||||||
|
buf = malloc(len);
|
||||||
|
|
||||||
|
/* create buffer to fail */
|
||||||
|
len_fail = strlen(out);
|
||||||
|
buf_fail = malloc(len_fail);
|
||||||
|
|
||||||
|
/* Print to buffer */
|
||||||
|
if (cJSON_PrintPreallocated(root, buf, len, 1) != 0) {
|
||||||
|
printf("cJSON_PrintPreallocated failed!\n");
|
||||||
|
if (strcmp(out, buf) != 0) {
|
||||||
|
printf("cJSON_PrintPreallocated not the same as cJSON_Print!\n");
|
||||||
|
printf("cJSON_Print result:\n%s\n", out);
|
||||||
|
printf("cJSON_PrintPreallocated result:\n%s\n", buf);
|
||||||
|
}
|
||||||
|
free(out);
|
||||||
|
free(buf_fail);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
printf("%s\n", buf);
|
||||||
|
|
||||||
|
/* force it to fail */
|
||||||
|
if (cJSON_PrintPreallocated(root, buf_fail, len_fail, 1) == 0) {
|
||||||
|
printf("cJSON_PrintPreallocated failed to show error with insufficient memory!\n");
|
||||||
|
printf("cJSON_Print result:\n%s\n", out);
|
||||||
|
printf("cJSON_PrintPreallocated result:\n%s\n", buf_fail);
|
||||||
|
free(out);
|
||||||
|
free(buf_fail);
|
||||||
|
free(buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(out);
|
||||||
|
free(buf_fail);
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a bunch of objects as demonstration. */
|
/* Create a bunch of objects as demonstration. */
|
||||||
static void create_objects(void)
|
static void create_objects(void)
|
||||||
{
|
{
|
||||||
@@ -92,7 +150,6 @@ static void create_objects(void)
|
|||||||
cJSON *img = NULL;
|
cJSON *img = NULL;
|
||||||
cJSON *thm = NULL;
|
cJSON *thm = NULL;
|
||||||
cJSON *fld = NULL;
|
cJSON *fld = NULL;
|
||||||
char *out = NULL;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* Our "days of the week" array: */
|
/* Our "days of the week" array: */
|
||||||
@@ -154,21 +211,20 @@ static void create_objects(void)
|
|||||||
cJSON_AddNumberToObject(fmt, "frame rate", 24);
|
cJSON_AddNumberToObject(fmt, "frame rate", 24);
|
||||||
|
|
||||||
/* Print to text */
|
/* Print to text */
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
/* Delete the cJSON */
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
/* print it */
|
|
||||||
printf("%s\n",out);
|
|
||||||
/* release the string */
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
/* Our "days of the week" array: */
|
/* Our "days of the week" array: */
|
||||||
root = cJSON_CreateStringArray(strings, 7);
|
root = cJSON_CreateStringArray(strings, 7);
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
/* Our matrix: */
|
/* Our matrix: */
|
||||||
root = cJSON_CreateArray();
|
root = cJSON_CreateArray();
|
||||||
@@ -179,11 +235,11 @@ static void create_objects(void)
|
|||||||
|
|
||||||
/* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */
|
/* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
|
|
||||||
/* Our "gallery" item: */
|
/* Our "gallery" item: */
|
||||||
root = cJSON_CreateObject();
|
root = cJSON_CreateObject();
|
||||||
@@ -197,13 +253,13 @@ static void create_objects(void)
|
|||||||
cJSON_AddStringToObject(thm, "Width", "100");
|
cJSON_AddStringToObject(thm, "Width", "100");
|
||||||
cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));
|
cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
/* Our array of "records": */
|
/* Our array of "records": */
|
||||||
|
|
||||||
root = cJSON_CreateArray();
|
root = cJSON_CreateArray();
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
@@ -220,17 +276,20 @@ static void create_objects(void)
|
|||||||
|
|
||||||
/* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */
|
/* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */
|
||||||
|
|
||||||
out = cJSON_Print(root);
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
|
|
||||||
root = cJSON_CreateObject();
|
root = cJSON_CreateObject();
|
||||||
cJSON_AddNumberToObject(root, "number", 1.0 / zero);
|
cJSON_AddNumberToObject(root, "number", 1.0 / zero);
|
||||||
out = cJSON_Print(root);
|
|
||||||
|
if (print_preallocated(root) != 0) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
printf("%s\n", out);
|
|
||||||
free(out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
|
Reference in New Issue
Block a user