提交 44512f64 编写于 作者: M Max Bruckner 提交者: GitHub

Merge pull request #110 from DaveGamble/ensure-improvements

ensure improvements
...@@ -81,6 +81,7 @@ static int cJSON_strcasecmp(const unsigned char *s1, const unsigned char *s2) ...@@ -81,6 +81,7 @@ static int cJSON_strcasecmp(const unsigned char *s1, const unsigned char *s2)
static void *(*cJSON_malloc)(size_t sz) = malloc; static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free; static void (*cJSON_free)(void *ptr) = free;
static void *(*cJSON_realloc)(void *pointer, size_t size) = realloc;
static unsigned char* cJSON_strdup(const unsigned char* str) static unsigned char* cJSON_strdup(const unsigned char* str)
{ {
...@@ -104,16 +105,33 @@ static unsigned char* cJSON_strdup(const unsigned char* str) ...@@ -104,16 +105,33 @@ static unsigned char* cJSON_strdup(const unsigned char* str)
void cJSON_InitHooks(cJSON_Hooks* hooks) void cJSON_InitHooks(cJSON_Hooks* hooks)
{ {
if (!hooks) if (hooks == NULL)
{ {
/* Reset hooks */ /* Reset hooks */
cJSON_malloc = malloc; cJSON_malloc = malloc;
cJSON_free = free; cJSON_free = free;
cJSON_realloc = realloc;
return; return;
} }
cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc; cJSON_malloc = malloc;
cJSON_free = (hooks->free_fn) ? hooks->free_fn : free; if (hooks->malloc_fn != NULL)
{
cJSON_malloc = hooks->malloc_fn;
}
cJSON_free = free;
if (hooks->free_fn != NULL)
{
cJSON_free = hooks->free_fn;
}
/* use realloc only if both free and malloc are used */
cJSON_realloc = NULL;
if ((cJSON_malloc == malloc) && (cJSON_free == free))
{
cJSON_realloc = realloc;
}
} }
/* Internal constructor. */ /* Internal constructor. */
...@@ -223,13 +241,18 @@ static unsigned char* ensure(printbuffer *p, size_t needed) ...@@ -223,13 +241,18 @@ static unsigned char* ensure(printbuffer *p, size_t needed)
unsigned char *newbuffer = NULL; unsigned char *newbuffer = NULL;
size_t newsize = 0; size_t newsize = 0;
if (p == NULL)
{
return (unsigned char*)cJSON_malloc(needed);
}
if (needed > INT_MAX) if (needed > INT_MAX)
{ {
/* sizes bigger than INT_MAX are currently not supported */ /* sizes bigger than INT_MAX are currently not supported */
return NULL; return NULL;
} }
if (!p || !p->buffer) if (p->buffer == NULL)
{ {
return NULL; return NULL;
} }
...@@ -258,6 +281,14 @@ static unsigned char* ensure(printbuffer *p, size_t needed) ...@@ -258,6 +281,14 @@ static unsigned char* ensure(printbuffer *p, size_t needed)
} }
} }
if (cJSON_realloc != NULL)
{
/* reallocate with realloc if available */
newbuffer = (unsigned char*)cJSON_realloc(p->buffer, newsize);
}
else
{
/* otherwise reallocate manually */
newbuffer = (unsigned char*)cJSON_malloc(newsize); newbuffer = (unsigned char*)cJSON_malloc(newsize);
if (!newbuffer) if (!newbuffer)
{ {
...@@ -269,9 +300,10 @@ static unsigned char* ensure(printbuffer *p, size_t needed) ...@@ -269,9 +300,10 @@ static unsigned char* ensure(printbuffer *p, size_t needed)
} }
if (newbuffer) if (newbuffer)
{ {
memcpy(newbuffer, p->buffer, p->length); memcpy(newbuffer, p->buffer, p->offset + 1);
} }
cJSON_free(p->buffer); cJSON_free(p->buffer);
}
p->length = newsize; p->length = newsize;
p->buffer = newbuffer; p->buffer = newbuffer;
...@@ -298,51 +330,29 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p) ...@@ -298,51 +330,29 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p)
double d = item->valuedouble; double d = item->valuedouble;
/* special case for 0. */ /* special case for 0. */
if (d == 0) if (d == 0)
{
if (p)
{ {
str = ensure(p, 2); str = ensure(p, 2);
} if (str != NULL)
else
{
str = (unsigned char*)cJSON_malloc(2);
}
if (str)
{ {
strcpy((char*)str,"0"); strcpy((char*)str,"0");
} }
} }
/* value is an int */ /* value is an int */
else if ((fabs(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) else if ((fabs(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN))
{
if (p)
{
str = ensure(p, 21);
}
else
{ {
/* 2^64+1 can be represented in 21 chars. */ /* 2^64+1 can be represented in 21 chars. */
str = (unsigned char*)cJSON_malloc(21); str = ensure(p, 21);
} if (str != NULL)
if (str)
{ {
sprintf((char*)str, "%d", item->valueint); sprintf((char*)str, "%d", item->valueint);
} }
} }
/* value is a floating point number */ /* value is a floating point number */
else else
{
if (p)
{ {
/* This is a nice tradeoff. */ /* This is a nice tradeoff. */
str = ensure(p, 64); str = ensure(p, 64);
} if (str != NULL)
else
{
/* This is a nice tradeoff. */
str = (unsigned char*)cJSON_malloc(64);
}
if (str)
{ {
/* This checks for NaN and Infinity */ /* This checks for NaN and Infinity */
if ((d * 0) != 0) if ((d * 0) != 0)
...@@ -670,16 +680,9 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) ...@@ -670,16 +680,9 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p)
/* empty string */ /* empty string */
if (!str) if (!str)
{
if (p)
{ {
out = ensure(p, 3); out = ensure(p, 3);
} if (out == NULL)
else
{
out = (unsigned char*)cJSON_malloc(3);
}
if (!out)
{ {
return NULL; return NULL;
} }
...@@ -701,15 +704,9 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) ...@@ -701,15 +704,9 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p)
if (!flag) if (!flag)
{ {
len = (size_t)(ptr - str); len = (size_t)(ptr - str);
if (p)
{
out = ensure(p, len + 3); out = ensure(p, len + 3);
} if (out == NULL)
else
{
out = (unsigned char*)cJSON_malloc(len + 3);
}
if (!out)
{ {
return NULL; return NULL;
} }
...@@ -739,15 +736,8 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) ...@@ -739,15 +736,8 @@ static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p)
ptr++; ptr++;
} }
if (p)
{
out = ensure(p, len + 3); out = ensure(p, len + 3);
} if (out == NULL)
else
{
out = (unsigned char*)cJSON_malloc(len + 3);
}
if (!out)
{ {
return NULL; return NULL;
} }
...@@ -993,21 +983,21 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p ...@@ -993,21 +983,21 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p
{ {
case cJSON_NULL: case cJSON_NULL:
out = ensure(p, 5); out = ensure(p, 5);
if (out) if (out != NULL)
{ {
strcpy((char*)out, "null"); strcpy((char*)out, "null");
} }
break; break;
case cJSON_False: case cJSON_False:
out = ensure(p, 6); out = ensure(p, 6);
if (out) if (out != NULL)
{ {
strcpy((char*)out, "false"); strcpy((char*)out, "false");
} }
break; break;
case cJSON_True: case cJSON_True:
out = ensure(p, 5); out = ensure(p, 5);
if (out) if (out != NULL)
{ {
strcpy((char*)out, "true"); strcpy((char*)out, "true");
} }
...@@ -1030,7 +1020,7 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p ...@@ -1030,7 +1020,7 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p
raw_length = strlen(item->valuestring) + sizeof('\0'); raw_length = strlen(item->valuestring) + sizeof('\0');
out = ensure(p, raw_length); out = ensure(p, raw_length);
if (out) if (out != NULL)
{ {
memcpy(out, item->valuestring, raw_length); memcpy(out, item->valuestring, raw_length);
} }
...@@ -1188,16 +1178,9 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p ...@@ -1188,16 +1178,9 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
/* Explicitly handle numentries == 0 */ /* Explicitly handle numentries == 0 */
if (!numentries) if (!numentries)
{
if (p)
{ {
out = ensure(p, 3); out = ensure(p, 3);
} if (out != NULL)
else
{
out = (unsigned char*)cJSON_malloc(3);
}
if (out)
{ {
strcpy((char*)out, "[]"); strcpy((char*)out, "[]");
} }
...@@ -1211,7 +1194,7 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p ...@@ -1211,7 +1194,7 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
/* opening square bracket */ /* opening square bracket */
i = p->offset; i = p->offset;
ptr = ensure(p, 1); ptr = ensure(p, 1);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
...@@ -1230,7 +1213,7 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p ...@@ -1230,7 +1213,7 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
{ {
len = fmt ? 2 : 1; len = fmt ? 2 : 1;
ptr = ensure(p, len + 1); ptr = ensure(p, len + 1);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
...@@ -1245,7 +1228,7 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p ...@@ -1245,7 +1228,7 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
child = child->next; child = child->next;
} }
ptr = ensure(p, 2); ptr = ensure(p, 2);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
...@@ -1455,16 +1438,9 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, ...@@ -1455,16 +1438,9 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
/* Explicitly handle empty object case */ /* Explicitly handle empty object case */
if (!numentries) if (!numentries)
{
if (p)
{ {
out = ensure(p, fmt ? depth + 4 : 3); out = ensure(p, fmt ? depth + 4 : 3);
} if (out == NULL)
else
{
out = (unsigned char*)cJSON_malloc(fmt ? depth + 4 : 3);
}
if (!out)
{ {
return NULL; return NULL;
} }
...@@ -1489,7 +1465,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, ...@@ -1489,7 +1465,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
i = p->offset; i = p->offset;
len = fmt ? 2 : 1; /* fmt: {\n */ len = fmt ? 2 : 1; /* fmt: {\n */
ptr = ensure(p, len + 1); ptr = ensure(p, len + 1);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
...@@ -1509,7 +1485,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, ...@@ -1509,7 +1485,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
if (fmt) if (fmt)
{ {
ptr = ensure(p, depth); ptr = ensure(p, depth);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
...@@ -1529,7 +1505,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, ...@@ -1529,7 +1505,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
len = fmt ? 2 : 1; len = fmt ? 2 : 1;
ptr = ensure(p, len); ptr = ensure(p, len);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
...@@ -1550,7 +1526,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, ...@@ -1550,7 +1526,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
/* print comma if not last */ /* print comma if not last */
len = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0); len = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0);
ptr = ensure(p, len + 1); ptr = ensure(p, len + 1);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
...@@ -1570,7 +1546,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, ...@@ -1570,7 +1546,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt,
} }
ptr = ensure(p, fmt ? (depth + 1) : 2); ptr = ensure(p, fmt ? (depth + 1) : 2);
if (!ptr) if (ptr == NULL)
{ {
return NULL; return NULL;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册