Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a function to print to pre-allocated buffer #72

Closed
wants to merge 12 commits into from
15 changes: 9 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ UTILS_LIBNAME = libcjson_utils
CJSON_TEST = cJSON_test
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

LIBVERSION = 1.0.2
Expand Down Expand Up @@ -66,11 +69,11 @@ test: tests

#tests
#cJSON
$(CJSON_TEST): cJSON.c cJSON.h test.c
$(CC) $^ -o $@ $(LDLIBS) -I.
$(CJSON_TEST): $(CJSON_TEST_SRC) cJSON.h
$(CC) $(CJSON_TEST_SRC) -o $@ $(LDLIBS) -I.
#cJSON_Utils
$(UTILS_TEST): cJSON.c cJSON.h test.c
$(CC) $^ -o $@ $(LDLIBS) -I.
$(UTILS_TEST): $(UTILS_TEST_SRC) cJSON.h cJSON_Utils.h
$(CC) $(UTILS_TEST_SRC) -o $@ $(LDLIBS) -I.

#static libraries
#cJSON
Expand All @@ -85,8 +88,8 @@ $(UTILS_STATIC): $(UTILS_OBJ)
$(CJSON_SHARED_VERSION): $(CJSON_OBJ)
$(CC) -shared -o $@ $< $(LDFLAGS)
#cJSON_Utils
$(UTILS_SHARED_VERSION): $(UTILS_OBJ)
$(CC) -shared -o $@ $< $(LDFLAGS)
$(UTILS_SHARED_VERSION): $(UTILS_OBJ) $(CJSON_OBJ)
$(CC) -shared -o $@ $< $(CJSON_OBJ) $(LDFLAGS)

#objects
#cJSON
Expand Down
10 changes: 10 additions & 0 deletions cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,16 @@ char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt)
return print_value(item, 0, fmt, &p);
}

int cJSON_PrintMallocedBuffer(cJSON *item,char *buf,const size_t len, cjbool fmt)
{
char *out;
printbuffer p;
p.buffer = buf;
p.length = len;
p.offset = 0;
out = print_value(item,0,fmt,&p);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By doing this you risk crashes, because print_value will try to reallocate the printbuffer when it is too short.

return (out != buf ? -1 : 0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return out like the other print functions. It will be NULL if it failed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this function returns a char pointer (effectively providing an alias to the input char *buf or a NULL pointer), it might falsely imply a new dynamically allocated string was created. Do you think it might be more intuitive to use the pointer to char* buf after the function is called if no error was returned, or is consistency of return values with all the cJSON_Print functions more important?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. Good point. Considering this, your way of returning true or false might actually be better. An API should be hard to misuse in a dangerous way (like having a double free because of the alias).
The question is how far one is willing to protect the users from themselves.

This will then not allow the use of cJSON_PrintPreallocated as an argument to another function (do_something(cJSON_PrintPreallocated(...)))

If you do it the way you suggested, you can just return print_value(...) != NULL;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be more concise. Made the change.

}

/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item, const char *value, const char **ep)
Expand Down
6 changes: 4 additions & 2 deletions cJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ extern char *cJSON_Print(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 */
extern char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, int fmt);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
/* Render a cJSON entity to text using a buffer already allocated in memory with length buf_len */
extern int cJSON_PrintMallocedBuffer(cJSON *item,char *buf,const size_t len, int fmt);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);

/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(const cJSON *array);
Expand Down