浏览代码

changed to cJSON_PrintPreallocated, added flag in printbuffer

Kyle Chisholm 8 年之前
父节点
当前提交
de93d76d0b
共有 3 个文件被更改,包括 61 次插入5 次删除
  1. 13 2
      cJSON.c
  2. 1 1
      cJSON.h
  3. 47 2
      test.c

+ 13 - 2
cJSON.c

@@ -244,6 +244,7 @@ typedef struct
     char *buffer;
     int length;
     int offset;
+    cjbool noalloc;
 } printbuffer;
 
 /* 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;
     }
 
+    if (p->noalloc) {
+        return NULL;
+    }
+
     newsize = pow2gt(needed);
     newbuffer = (char*)cJSON_malloc(newsize);
     if (!newbuffer)
@@ -882,17 +887,19 @@ char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cjbool fmt)
     }
     p.length = prebuffer;
     p.offset = 0;
+    p.noalloc = false;
 
     return print_value(item, 0, fmt, &p);
 }
 
-int cJSON_PrintMallocedBuffer(cJSON *item,char *buf,const int len, cjbool fmt)
+int cJSON_PrintPreallocated(cJSON *item,char *buf, const int len, const cjbool fmt)
 {
     char *out;
     printbuffer p;
     p.buffer = buf;
     p.length = len;
     p.offset = 0;
+    p.noalloc = true;
     out = print_value(item,0,fmt,&p);
     return (out != buf ? -1 : 0);
 }
@@ -1147,7 +1154,11 @@ static char *print_array(const cJSON *item, int depth, cjbool fmt, printbuffer *
         child = item->child;
         while (child && !fail)
         {
-            print_value(child, depth + 1, fmt, p);
+            ptr = print_value(child, depth + 1, fmt, p);
+            if (!ptr)
+            {
+                return NULL;
+            }
             p->offset = update(p);
             if (child->next)
             {

+ 1 - 1
cJSON.h

@@ -84,7 +84,7 @@ 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);
 /* 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 int len, int fmt);
+extern int cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const int fmt);
 /* Delete a cJSON entity and all subentities. */
 extern void   cJSON_Delete(cJSON *c);
 

+ 47 - 2
test.c

@@ -22,6 +22,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include "cJSON.h"
 
 /* Parse text to JSON, then render back to text, and print! */
@@ -219,16 +220,60 @@ void create_objects(void)
     /* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */
 
     out = cJSON_Print(root);
-    cJSON_Delete(root);
     printf("%s\n", out);
+
+    printf("Test cJSON_PrintPreallocated:\n");
+    /* create buffer */
+    size_t len = strlen(out) + 1;
+    char *buf = malloc(len);
+
+    /* create buffer to fail */
+    size_t len_fail = strlen(out);
+    char *buf_fail = malloc(len_fail);
+
     free(out);
 
+    /* Print to buffer */
+    if (cJSON_PrintPreallocated(root, buf, len, 1) != 0) {
+        printf("cJSON_PrintPreallocated failed (but it should not have!)\n");
+        free(buf_fail);
+        free(buf);
+        exit(EXIT_FAILURE);
+    } else {
+        printf("cJSON_PrintPreallocated:\n%s\n", buf);
+    }
+
+    /* unformatted output */
+    if (cJSON_PrintPreallocated(root, buf, len, 0) != 0) {
+        printf("cJSON_PrintPreallocated failed (but it should not have!)\n");
+        free(buf_fail);
+        free(buf);
+        exit(EXIT_FAILURE);
+    } else {
+        printf("cJSON_PrintPreallocated (unformatted):\n%s\n", buf);
+    }
+
+    free(buf);
+
+    /* force it to fail */
+    if (cJSON_PrintPreallocated(root, buf_fail, len_fail, 1) != 0) {
+        printf("cJSON_PrintPreallocated failed (as expected)\n");
+    } else {
+        printf("cJSON_PrintPreallocated worked (but it should have failed!)\n");
+        printf("cJSON_PrintPreallocated:\n%s\n", buf_fail);
+    }
+
+    free(buf_fail);
+    cJSON_Delete(root);
+
     root = cJSON_CreateObject();
     cJSON_AddNumberToObject(root, "number", 1.0 / zero);
     out = cJSON_Print(root);
-    cJSON_Delete(root);
     printf("%s\n", out);
+    cJSON_Delete(root);
+
     free(out);
+
 }
 
 int main(void)