From 61921498d0842a2372766ca4ef158a9505acbd8f Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 11:32:53 +0100 Subject: [PATCH 01/12] print_number: remove special case for 0 Now that printbuffer is used for everything, it's not needed anymore. --- cJSON.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/cJSON.c b/cJSON.c index 598f9cf0..06b4c09a 100644 --- a/cJSON.c +++ b/cJSON.c @@ -330,17 +330,8 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p) return NULL; } - /* special case for 0. */ - if (d == 0) - { - str = ensure(p, 2); - if (str != NULL) - { - strcpy((char*)str,"0"); - } - } /* value is an int */ - else if ((fabs(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) + if ((fabs(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) { /* 2^64+1 can be represented in 21 chars. */ str = ensure(p, 21); @@ -375,6 +366,7 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p) } } } + return str; } From 6815d96617d4812e93430c0f38cc7b59554cfc72 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 11:41:40 +0100 Subject: [PATCH 02/12] print_number: rename variables --- cJSON.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cJSON.c b/cJSON.c index 06b4c09a..15b9d314 100644 --- a/cJSON.c +++ b/cJSON.c @@ -320,12 +320,12 @@ static size_t update(const printbuffer *p) } /* Render the number nicely from the given item into a string. */ -static unsigned char *print_number(const cJSON *item, printbuffer *p) +static unsigned char *print_number(const cJSON * const item, printbuffer * const output_buffer) { - unsigned char *str = NULL; + unsigned char *output_pointer = NULL; double d = item->valuedouble; - if (p == NULL) + if (output_buffer == NULL) { return NULL; } @@ -333,41 +333,41 @@ static unsigned char *print_number(const cJSON *item, printbuffer *p) /* value is an int */ if ((fabs(((double)item->valueint) - d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) { - /* 2^64+1 can be represented in 21 chars. */ - str = ensure(p, 21); - if (str != NULL) + /* 2^64+1 can be represented in 21 chars. */ + output_pointer = ensure(output_buffer, 21); + if (output_pointer != NULL) { - sprintf((char*)str, "%d", item->valueint); + sprintf((char*)output_pointer, "%d", item->valueint); } } /* value is a floating point number */ else { /* This is a nice tradeoff. */ - str = ensure(p, 64); - if (str != NULL) + output_pointer = ensure(output_buffer, 64); + if (output_pointer != NULL) { /* This checks for NaN and Infinity */ if ((d * 0) != 0) { - sprintf((char*)str, "null"); + sprintf((char*)output_pointer, "null"); } else if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60)) { - sprintf((char*)str, "%.0f", d); + sprintf((char*)output_pointer, "%.0f", d); } else if ((fabs(d) < 1.0e-6) || (fabs(d) > 1.0e9)) { - sprintf((char*)str, "%e", d); + sprintf((char*)output_pointer, "%e", d); } else { - sprintf((char*)str, "%f", d); + sprintf((char*)output_pointer, "%f", d); } } } - return str; + return output_pointer; } /* parse 4 digit hexadecimal number */ From 1e999352d3b3da36971797ce8ff155a95026367f Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 12:02:20 +0100 Subject: [PATCH 03/12] print_string_ptr: rename variables --- cJSON.c | 110 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/cJSON.c b/cJSON.c index 15b9d314..963b3893 100644 --- a/cJSON.c +++ b/cJSON.c @@ -236,7 +236,7 @@ typedef struct } printbuffer; /* realloc printbuffer if necessary to have at least "needed" bytes more */ -static unsigned char* ensure(printbuffer *p, size_t needed) +static unsigned char* ensure(printbuffer * const p, size_t needed) { unsigned char *newbuffer = NULL; size_t newsize = 0; @@ -663,134 +663,134 @@ static const unsigned char *parse_string(cJSON * const item, const unsigned char } /* Render the cstring provided to an escaped version that can be printed. */ -static unsigned char *print_string_ptr(const unsigned char *str, printbuffer *p) +static unsigned char *print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) { - const unsigned char *ptr = NULL; - unsigned char *ptr2 = NULL; - unsigned char *out = NULL; - size_t len = 0; - cjbool flag = false; + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t length = 0; + cjbool contains_special_char = false; unsigned char token = '\0'; - if (p == NULL) + if (output_buffer == NULL) { return NULL; } /* empty string */ - if (!str) + if (input == NULL) { - out = ensure(p, 3); - if (out == NULL) + output = ensure(output_buffer, 3); + if (output == NULL) { return NULL; } - strcpy((char*)out, "\"\""); + strcpy((char*)output, "\"\""); - return out; + return output; } /* set "flag" to 1 if something needs to be escaped */ - for (ptr = str; *ptr; ptr++) + for (input_pointer = input; *input_pointer; input_pointer++) { - flag |= (((*ptr > 0) && (*ptr < 32)) /* unprintable characters */ - || (*ptr == '\"') /* double quote */ - || (*ptr == '\\')) /* backslash */ + contains_special_char |= (((*input_pointer > 0) && (*input_pointer < 32)) /* unprintable characters */ + || (*input_pointer == '\"') /* double quote */ + || (*input_pointer == '\\')) /* backslash */ ? 1 : 0; } /* no characters have to be escaped */ - if (!flag) + if (!contains_special_char) { - len = (size_t)(ptr - str); + length = (size_t)(input_pointer - input); - out = ensure(p, len + 3); - if (out == NULL) + output = ensure(output_buffer, length + 3); + if (output == NULL) { return NULL; } - ptr2 = out; - *ptr2++ = '\"'; - strcpy((char*)ptr2, (const char*)str); - ptr2[len] = '\"'; - ptr2[len + 1] = '\0'; + output_pointer = output; + *output_pointer++ = '\"'; + strcpy((char*)output_pointer, (const char*)input); + output_pointer[length] = '\"'; + output_pointer[length + 1] = '\0'; - return out; + return output; } - ptr = str; + input_pointer = input; /* calculate additional space that is needed for escaping */ - while ((token = *ptr)) + while ((token = *input_pointer)) { - ++len; + ++length; if (strchr("\"\\\b\f\n\r\t", token)) { - len++; /* +1 for the backslash */ + length++; /* +1 for the backslash */ } else if (token < 32) { - len += 5; /* +5 for \uXXXX */ + length += 5; /* +5 for \uXXXX */ } - ptr++; + input_pointer++; } - out = ensure(p, len + 3); - if (out == NULL) + output = ensure(output_buffer, length + 3); + if (output == NULL) { return NULL; } - ptr2 = out; - ptr = str; - *ptr2++ = '\"'; + output_pointer = output; + input_pointer = input; + *output_pointer++ = '\"'; /* copy the string */ - while (*ptr) + while (*input_pointer) { - if ((*ptr > 31) && (*ptr != '\"') && (*ptr != '\\')) + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) { /* normal character, copy */ - *ptr2++ = *ptr++; + *output_pointer++ = *input_pointer++; } else { /* character needs to be escaped */ - *ptr2++ = '\\'; - switch (token = *ptr++) + *output_pointer++ = '\\'; + switch (token = *input_pointer++) { case '\\': - *ptr2++ = '\\'; + *output_pointer++ = '\\'; break; case '\"': - *ptr2++ = '\"'; + *output_pointer++ = '\"'; break; case '\b': - *ptr2++ = 'b'; + *output_pointer++ = 'b'; break; case '\f': - *ptr2++ = 'f'; + *output_pointer++ = 'f'; break; case '\n': - *ptr2++ = 'n'; + *output_pointer++ = 'n'; break; case '\r': - *ptr2++ = 'r'; + *output_pointer++ = 'r'; break; case '\t': - *ptr2++ = 't'; + *output_pointer++ = 't'; break; default: /* escape and print as unicode codepoint */ - sprintf((char*)ptr2, "u%04x", token); - ptr2 += 5; + sprintf((char*)output_pointer, "u%04x", token); + output_pointer += 5; break; } } } - *ptr2++ = '\"'; - *ptr2++ = '\0'; + *output_pointer++ = '\"'; + *output_pointer++ = '\0'; - return out; + return output; } /* Invoke print_string_ptr (which is useful) on an item. */ From 6a746a230af20aad075cd0ebd1ae351baa16bc1f Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 12:02:56 +0100 Subject: [PATCH 04/12] print_string: Add more const --- cJSON.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cJSON.c b/cJSON.c index 963b3893..5a9f29bd 100644 --- a/cJSON.c +++ b/cJSON.c @@ -794,7 +794,7 @@ static unsigned char *print_string_ptr(const unsigned char * const input, printb } /* Invoke print_string_ptr (which is useful) on an item. */ -static unsigned char *print_string(const cJSON *item, printbuffer *p) +static unsigned char *print_string(const cJSON * const item, printbuffer * const p) { return print_string_ptr((unsigned char*)item->valuestring, p); } From 88e38d042f3c125d06e37d2ed72ad07e52259117 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 12:46:38 +0100 Subject: [PATCH 05/12] tests: print_string: test if NULL is printed as empty string --- tests/print_string.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/print_string.c b/tests/print_string.c index 03ea5046..1404160f 100644 --- a/tests/print_string.c +++ b/tests/print_string.c @@ -40,6 +40,7 @@ static void assert_print_string(const char *expected, const char *input) static void print_string_should_print_empty_strings(void) { assert_print_string("\"\"", ""); + assert_print_string("\"\"", NULL); } static void print_string_should_print_ascii(void) From 0ca8587acc6c569a890456ed9741b2ba1911ec84 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 13:03:51 +0100 Subject: [PATCH 06/12] print_string_ptr: simplify code --- cJSON.c | 97 +++++++++++++++++++++++---------------------------------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/cJSON.c b/cJSON.c index 5a9f29bd..2e3f4e8c 100644 --- a/cJSON.c +++ b/cJSON.c @@ -668,9 +668,9 @@ static unsigned char *print_string_ptr(const unsigned char * const input, printb const unsigned char *input_pointer = NULL; unsigned char *output = NULL; unsigned char *output_pointer = NULL; - size_t length = 0; - cjbool contains_special_char = false; - unsigned char token = '\0'; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; if (output_buffer == NULL) { @@ -680,7 +680,7 @@ static unsigned char *print_string_ptr(const unsigned char * const input, printb /* empty string */ if (input == NULL) { - output = ensure(output_buffer, 3); + output = ensure(output_buffer, sizeof("\"\"")); if (output == NULL) { return NULL; @@ -693,102 +693,83 @@ static unsigned char *print_string_ptr(const unsigned char * const input, printb /* set "flag" to 1 if something needs to be escaped */ for (input_pointer = input; *input_pointer; input_pointer++) { - contains_special_char |= (((*input_pointer > 0) && (*input_pointer < 32)) /* unprintable characters */ - || (*input_pointer == '\"') /* double quote */ - || (*input_pointer == '\\')) /* backslash */ - ? 1 - : 0; - } - /* no characters have to be escaped */ - if (!contains_special_char) - { - length = (size_t)(input_pointer - input); - - output = ensure(output_buffer, length + 3); - if (output == NULL) - { - return NULL; - } - - output_pointer = output; - *output_pointer++ = '\"'; - strcpy((char*)output_pointer, (const char*)input); - output_pointer[length] = '\"'; - output_pointer[length + 1] = '\0'; - - return output; - } - - input_pointer = input; - /* calculate additional space that is needed for escaping */ - while ((token = *input_pointer)) - { - ++length; - if (strchr("\"\\\b\f\n\r\t", token)) + if (strchr("\"\\\b\f\n\r\t", *input_pointer)) { - length++; /* +1 for the backslash */ + /* one character escape sequence */ + escape_characters++; } - else if (token < 32) + else if (*input_pointer < 32) { - length += 5; /* +5 for \uXXXX */ + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; } - input_pointer++; } + output_length = (size_t)(input_pointer - input) + escape_characters; - output = ensure(output_buffer, length + 3); + output = ensure(output_buffer, output_length + sizeof("\"\"")); if (output == NULL) { return NULL; } - output_pointer = output; - input_pointer = input; - *output_pointer++ = '\"'; + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return output; + } + + output[0] = '\"'; + output_pointer = output + 1; /* copy the string */ - while (*input_pointer) + for (input_pointer = input; *input_pointer != '\0'; input_pointer++, output_pointer++) { if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) { /* normal character, copy */ - *output_pointer++ = *input_pointer++; + *output_pointer = *input_pointer; } else { /* character needs to be escaped */ *output_pointer++ = '\\'; - switch (token = *input_pointer++) + switch (*input_pointer) { case '\\': - *output_pointer++ = '\\'; + *output_pointer = '\\'; break; case '\"': - *output_pointer++ = '\"'; + *output_pointer = '\"'; break; case '\b': - *output_pointer++ = 'b'; + *output_pointer = 'b'; break; case '\f': - *output_pointer++ = 'f'; + *output_pointer = 'f'; break; case '\n': - *output_pointer++ = 'n'; + *output_pointer = 'n'; break; case '\r': - *output_pointer++ = 'r'; + *output_pointer = 'r'; break; case '\t': - *output_pointer++ = 't'; + *output_pointer = 't'; break; default: /* escape and print as unicode codepoint */ - sprintf((char*)output_pointer, "u%04x", token); - output_pointer += 5; + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; break; } } } - *output_pointer++ = '\"'; - *output_pointer++ = '\0'; + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; return output; } From 08770fc246fd8993f007acba38ab9e9dd919e403 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 13:30:40 +0100 Subject: [PATCH 07/12] print_value: rename variables --- cJSON.c | 55 +++++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/cJSON.c b/cJSON.c index 2e3f4e8c..af707cff 100644 --- a/cJSON.c +++ b/cJSON.c @@ -782,7 +782,7 @@ static unsigned char *print_string(const cJSON * const item, printbuffer * const /* Predeclare these prototypes. */ static const unsigned char *parse_value(cJSON * const item, const unsigned char * const input, const unsigned char ** const ep); -static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); +static unsigned char *print_value(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer); static const unsigned char *parse_array(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); static const unsigned char *parse_object(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); @@ -1000,16 +1000,11 @@ static const unsigned char *parse_value(cJSON * const item, const unsigned char } /* Render a value to text. */ -static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p) +static unsigned char *print_value(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer) { - unsigned char *out = NULL; - - if (!item) - { - return NULL; - } + unsigned char *output = NULL; - if (p == NULL) + if ((item == NULL) || (output_buffer == NULL)) { return NULL; } @@ -1017,65 +1012,65 @@ static unsigned char *print_value(const cJSON *item, size_t depth, cjbool fmt, p switch ((item->type) & 0xFF) { case cJSON_NULL: - out = ensure(p, 5); - if (out != NULL) + output = ensure(output_buffer, 5); + if (output != NULL) { - strcpy((char*)out, "null"); + strcpy((char*)output, "null"); } break; case cJSON_False: - out = ensure(p, 6); - if (out != NULL) + output = ensure(output_buffer, 6); + if (output != NULL) { - strcpy((char*)out, "false"); + strcpy((char*)output, "false"); } break; case cJSON_True: - out = ensure(p, 5); - if (out != NULL) + output = ensure(output_buffer, 5); + if (output != NULL) { - strcpy((char*)out, "true"); + strcpy((char*)output, "true"); } break; case cJSON_Number: - out = print_number(item, p); + output = print_number(item, output_buffer); break; case cJSON_Raw: { size_t raw_length = 0; if (item->valuestring == NULL) { - if (!p->noalloc) + if (!output_buffer->noalloc) { - cJSON_free(p->buffer); + cJSON_free(output_buffer->buffer); } - out = NULL; + output = NULL; break; } raw_length = strlen(item->valuestring) + sizeof('\0'); - out = ensure(p, raw_length); - if (out != NULL) + output = ensure(output_buffer, raw_length); + if (output != NULL) { - memcpy(out, item->valuestring, raw_length); + memcpy(output, item->valuestring, raw_length); } break; } case cJSON_String: - out = print_string(item, p); + output = print_string(item, output_buffer); break; case cJSON_Array: - out = print_array(item, depth, fmt, p); + output = print_array(item, depth, format, output_buffer); break; case cJSON_Object: - out = print_object(item, depth, fmt, p); + output = print_object(item, depth, format, output_buffer); break; default: - out = NULL; + output = NULL; break; } - return out; + return output; } /* Build an array from input text. */ From f16dd7e028a7fa9609dfd0dce8883fa4c9cdf9e7 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 13:58:13 +0100 Subject: [PATCH 08/12] print_array: rename variables --- cJSON.c | 84 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/cJSON.c b/cJSON.c index af707cff..b9eaa2ca 100644 --- a/cJSON.c +++ b/cJSON.c @@ -784,7 +784,7 @@ static unsigned char *print_string(const cJSON * const item, printbuffer * const static const unsigned char *parse_value(cJSON * const item, const unsigned char * const input, const unsigned char ** const ep); static unsigned char *print_value(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer); static const unsigned char *parse_array(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); -static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); +static unsigned char *print_array(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer); static const unsigned char *parse_object(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); @@ -1152,87 +1152,87 @@ static const unsigned char *parse_array(cJSON * const item, const unsigned char } /* 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 * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer) { - unsigned char *out = NULL; - unsigned char *ptr = NULL; - size_t len = 5; - cJSON *child = item->child; - size_t numentries = 0; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t length = 5; + cJSON *current_element = item->child; + size_t array_length = 0; size_t i = 0; cjbool fail = false; - if (p == NULL) + if (output_buffer == NULL) { return NULL; } /* How many entries in the array? */ - while (child) + while (current_element) { - numentries++; - child = child->next; + array_length++; + current_element = current_element->next; } - /* Explicitly handle numentries == 0 */ - if (!numentries) + /* Explicitly handle empty arrays */ + if (array_length == 0) { - out = ensure(p, 3); - if (out != NULL) + output = ensure(output_buffer, 3); + if (output != NULL) { - strcpy((char*)out, "[]"); + strcpy((char*)output, "[]"); } - return out; + return output; } /* Compose the output array. */ /* opening square bracket */ - i = p->offset; - ptr = ensure(p, 1); - if (ptr == NULL) + i = output_buffer->offset; + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) { return NULL; } - *ptr = '['; - p->offset++; + *output_pointer = '['; + output_buffer->offset++; - child = item->child; - while (child && !fail) + current_element = item->child; + while (current_element && !fail) { - if (!print_value(child, depth + 1, fmt, p)) + if (!print_value(current_element, depth + 1, format, output_buffer)) { return NULL; } - p->offset = update(p); - if (child->next) + output_buffer->offset = update(output_buffer); + if (current_element->next) { - len = fmt ? 2 : 1; - ptr = ensure(p, len + 1); - if (ptr == NULL) + length = format ? 2 : 1; + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) { return NULL; } - *ptr++ = ','; - if(fmt) + *output_pointer++ = ','; + if(format) { - *ptr++ = ' '; + *output_pointer++ = ' '; } - *ptr = '\0'; - p->offset += len; + *output_pointer = '\0'; + output_buffer->offset += length; } - child = child->next; + current_element = current_element->next; } - ptr = ensure(p, 2); - if (ptr == NULL) + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) { return NULL; } - *ptr++ = ']'; - *ptr = '\0'; - out = (p->buffer) + i; + *output_pointer++ = ']'; + *output_pointer = '\0'; + output = (output_buffer->buffer) + i; - return out; + return output; } /* Build an object from the text. */ From 8c1ed3ab82a04ff494370b8a28eee7f970043b74 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 15:02:49 +0100 Subject: [PATCH 09/12] update: rename to update_offset and change offset directly --- cJSON.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cJSON.c b/cJSON.c index b9eaa2ca..4f6cac5f 100644 --- a/cJSON.c +++ b/cJSON.c @@ -306,17 +306,17 @@ static unsigned char* ensure(printbuffer * const p, size_t needed) return newbuffer + p->offset; } -/* calculate the new length of the string in a printbuffer */ -static size_t update(const printbuffer *p) +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) { - const unsigned char *str = NULL; - if (!p || !p->buffer) + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) { - return 0; + return; } - str = p->buffer + p->offset; + buffer_pointer = buffer->buffer + buffer->offset; - return p->offset + strlen((const char*)str); + buffer->offset += strlen((const char*)buffer_pointer); } /* Render the number nicely from the given item into a string. */ @@ -866,7 +866,7 @@ static unsigned char *print(const cJSON * const item, cjbool format) { goto fail; } - buffer->offset = update(buffer); /* update the length of the string */ + update_offset(buffer); /* copy the buffer over to a new one */ printed = (unsigned char*) cJSON_malloc(buffer->offset + 1); @@ -1204,7 +1204,7 @@ static unsigned char *print_array(const cJSON * const item, const size_t depth, { return NULL; } - output_buffer->offset = update(output_buffer); + update_offset(output_buffer); if (current_element->next) { length = format ? 2 : 1; @@ -1416,7 +1416,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, { return NULL; } - p->offset = update(p); + update_offset(p); len = fmt ? 2 : 1; ptr = ensure(p, len); @@ -1436,7 +1436,7 @@ static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, { return NULL; } - p->offset = update(p); + update_offset(p); /* print comma if not last */ len = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0); From 6d5a7c8c404521d8a51176a5db79b203e52ad3ce Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 15:12:10 +0100 Subject: [PATCH 10/12] print_array: simplify code --- cJSON.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/cJSON.c b/cJSON.c index 4f6cac5f..bc40d08a 100644 --- a/cJSON.c +++ b/cJSON.c @@ -1156,51 +1156,31 @@ static unsigned char *print_array(const cJSON * const item, const size_t depth, { unsigned char *output = NULL; unsigned char *output_pointer = NULL; - size_t length = 5; + size_t length = 0; cJSON *current_element = item->child; - size_t array_length = 0; - size_t i = 0; - cjbool fail = false; + size_t output_offset = 0; if (output_buffer == NULL) { return NULL; } - /* How many entries in the array? */ - while (current_element) - { - array_length++; - current_element = current_element->next; - } - - /* Explicitly handle empty arrays */ - if (array_length == 0) - { - output = ensure(output_buffer, 3); - if (output != NULL) - { - strcpy((char*)output, "[]"); - } - - return output; - } - /* Compose the output array. */ /* opening square bracket */ - i = output_buffer->offset; + output_offset = output_buffer->offset; output_pointer = ensure(output_buffer, 1); if (output_pointer == NULL) { return NULL; } + *output_pointer = '['; output_buffer->offset++; current_element = item->child; - while (current_element && !fail) + while (current_element != NULL) { - if (!print_value(current_element, depth + 1, format, output_buffer)) + if (print_value(current_element, depth + 1, format, output_buffer) == NULL) { return NULL; } @@ -1223,6 +1203,7 @@ static unsigned char *print_array(const cJSON * const item, const size_t depth, } current_element = current_element->next; } + output_pointer = ensure(output_buffer, 2); if (output_pointer == NULL) { @@ -1230,7 +1211,7 @@ static unsigned char *print_array(const cJSON * const item, const size_t depth, } *output_pointer++ = ']'; *output_pointer = '\0'; - output = (output_buffer->buffer) + i; + output = output_buffer->buffer + output_offset; return output; } From b71db93e0373ae361d3d5d42b8e8da3ab932c3c7 Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 15:57:22 +0100 Subject: [PATCH 11/12] print_object: rename variables --- cJSON.c | 134 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/cJSON.c b/cJSON.c index bc40d08a..4fe5a954 100644 --- a/cJSON.c +++ b/cJSON.c @@ -786,7 +786,7 @@ static unsigned char *print_value(const cJSON * const item, const size_t depth, static const unsigned char *parse_array(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); static unsigned char *print_array(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer); static const unsigned char *parse_object(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); -static unsigned char *print_object(const cJSON *item, size_t depth, cjbool fmt, printbuffer *p); +static unsigned char *print_object(const cJSON * const item, size_t depth, const cjbool format, printbuffer * const output_buffer); /* Utility to jump whitespace and cr/lf */ static const unsigned char *skip_whitespace(const unsigned char *in) @@ -1312,152 +1312,152 @@ static const unsigned char *parse_object(cJSON * const item, const unsigned char } /* 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 * const item, size_t depth, const cjbool format, printbuffer * const output_buffer) { - unsigned char *out = NULL; - unsigned char *ptr = NULL; - size_t len = 7; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t length = 7; size_t i = 0; size_t j = 0; - cJSON *child = item->child; - size_t numentries = 0; + cJSON *current_item = item->child; + size_t object_length = 0; - if (p == NULL) + if (output_buffer == NULL) { return NULL; } /* Count the number of entries. */ - while (child) + while (current_item) { - numentries++; - child = child->next; + object_length++; + current_item = current_item->next; } /* Explicitly handle empty object case */ - if (!numentries) + if (!object_length) { - out = ensure(p, fmt ? depth + 4 : 3); - if (out == NULL) + output = ensure(output_buffer, format ? depth + 4 : 3); + if (output == NULL) { return NULL; } - ptr = out; - *ptr++ = '{'; - if (fmt) { - *ptr++ = '\n'; + output_pointer = output; + *output_pointer++ = '{'; + if (format) { + *output_pointer++ = '\n'; for (i = 0; i < depth; i++) { - *ptr++ = '\t'; + *output_pointer++ = '\t'; } } - *ptr++ = '}'; - *ptr++ = '\0'; + *output_pointer++ = '}'; + *output_pointer++ = '\0'; - return out; + return output; } /* Compose the output: */ - i = p->offset; - len = fmt ? 2 : 1; /* fmt: {\n */ - ptr = ensure(p, len + 1); - if (ptr == NULL) + i = output_buffer->offset; + length = format ? 2 : 1; /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) { return NULL; } - *ptr++ = '{'; - if (fmt) + *output_pointer++ = '{'; + if (format) { - *ptr++ = '\n'; + *output_pointer++ = '\n'; } - *ptr = '\0'; - p->offset += len; + *output_pointer = '\0'; + output_buffer->offset += length; - child = item->child; + current_item = item->child; depth++; - while (child) + while (current_item) { - if (fmt) + if (format) { - ptr = ensure(p, depth); - if (ptr == NULL) + output_pointer = ensure(output_buffer, depth); + if (output_pointer == NULL) { return NULL; } for (j = 0; j < depth; j++) { - *ptr++ = '\t'; + *output_pointer++ = '\t'; } - p->offset += depth; + output_buffer->offset += depth; } /* print key */ - if (!print_string_ptr((unsigned char*)child->string, p)) + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) { return NULL; } - update_offset(p); + update_offset(output_buffer); - len = fmt ? 2 : 1; - ptr = ensure(p, len); - if (ptr == NULL) + length = format ? 2 : 1; + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) { return NULL; } - *ptr++ = ':'; - if (fmt) + *output_pointer++ = ':'; + if (format) { - *ptr++ = '\t'; + *output_pointer++ = '\t'; } - p->offset+=len; + output_buffer->offset += length; /* print value */ - if (!print_value(child, depth, fmt, p)) + if (!print_value(current_item, depth, format, output_buffer)) { return NULL; } - update_offset(p); + update_offset(output_buffer); /* print comma if not last */ - len = (size_t) (fmt ? 1 : 0) + (child->next ? 1 : 0); - ptr = ensure(p, len + 1); - if (ptr == NULL) + length = (size_t) (format ? 1 : 0) + (current_item->next ? 1 : 0); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) { return NULL; } - if (child->next) + if (current_item->next) { - *ptr++ = ','; + *output_pointer++ = ','; } - if (fmt) + if (format) { - *ptr++ = '\n'; + *output_pointer++ = '\n'; } - *ptr = '\0'; - p->offset += len; + *output_pointer = '\0'; + output_buffer->offset += length; - child = child->next; + current_item = current_item->next; } - ptr = ensure(p, fmt ? (depth + 1) : 2); - if (ptr == NULL) + output_pointer = ensure(output_buffer, format ? (depth + 1) : 2); + if (output_pointer == NULL) { return NULL; } - if (fmt) + if (format) { for (i = 0; i < (depth - 1); i++) { - *ptr++ = '\t'; + *output_pointer++ = '\t'; } } - *ptr++ = '}'; - *ptr = '\0'; - out = (p->buffer) + i; + *output_pointer++ = '}'; + *output_pointer = '\0'; + output = (output_buffer->buffer) + i; - return out; + return output; } /* Get Array size/item / object item. */ From 1d42c9bc603cbc36191711867272e5d7b7af9e8a Mon Sep 17 00:00:00 2001 From: Max Bruckner Date: Mon, 20 Feb 2017 16:58:22 +0100 Subject: [PATCH 12/12] print_object: simplify code --- cJSON.c | 62 ++++++++++++++------------------------------------------- 1 file changed, 15 insertions(+), 47 deletions(-) diff --git a/cJSON.c b/cJSON.c index 4fe5a954..46187c69 100644 --- a/cJSON.c +++ b/cJSON.c @@ -786,7 +786,7 @@ static unsigned char *print_value(const cJSON * const item, const size_t depth, static const unsigned char *parse_array(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); static unsigned char *print_array(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer); static const unsigned char *parse_object(cJSON * const item, const unsigned char *input, const unsigned char ** const ep); -static unsigned char *print_object(const cJSON * const item, size_t depth, const cjbool format, printbuffer * const output_buffer); +static unsigned char *print_object(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer); /* Utility to jump whitespace and cr/lf */ static const unsigned char *skip_whitespace(const unsigned char *in) @@ -1312,53 +1312,21 @@ static const unsigned char *parse_object(cJSON * const item, const unsigned char } /* Render an object to text. */ -static unsigned char *print_object(const cJSON * const item, size_t depth, const cjbool format, printbuffer * const output_buffer) +static unsigned char *print_object(const cJSON * const item, const size_t depth, const cjbool format, printbuffer * const output_buffer) { unsigned char *output = NULL; unsigned char *output_pointer = NULL; - size_t length = 7; - size_t i = 0; - size_t j = 0; + size_t length = 0; + size_t output_offset = 0; cJSON *current_item = item->child; - size_t object_length = 0; if (output_buffer == NULL) { return NULL; } - /* Count the number of entries. */ - while (current_item) - { - object_length++; - current_item = current_item->next; - } - - /* Explicitly handle empty object case */ - if (!object_length) - { - output = ensure(output_buffer, format ? depth + 4 : 3); - if (output == NULL) - { - return NULL; - } - output_pointer = output; - *output_pointer++ = '{'; - if (format) { - *output_pointer++ = '\n'; - for (i = 0; i < depth; i++) - { - *output_pointer++ = '\t'; - } - } - *output_pointer++ = '}'; - *output_pointer++ = '\0'; - - return output; - } - /* Compose the output: */ - i = output_buffer->offset; + output_offset = output_buffer->offset; length = format ? 2 : 1; /* fmt: {\n */ output_pointer = ensure(output_buffer, length + 1); if (output_pointer == NULL) @@ -1371,29 +1339,28 @@ static unsigned char *print_object(const cJSON * const item, size_t depth, const { *output_pointer++ = '\n'; } - *output_pointer = '\0'; output_buffer->offset += length; current_item = item->child; - depth++; while (current_item) { if (format) { - output_pointer = ensure(output_buffer, depth); + size_t i; + output_pointer = ensure(output_buffer, depth + 1); if (output_pointer == NULL) { return NULL; } - for (j = 0; j < depth; j++) + for (i = 0; i < depth + 1; i++) { *output_pointer++ = '\t'; } - output_buffer->offset += depth; + output_buffer->offset += depth + 1; } /* print key */ - if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + if (print_string_ptr((unsigned char*)current_item->string, output_buffer) == NULL) { return NULL; } @@ -1413,7 +1380,7 @@ static unsigned char *print_object(const cJSON * const item, size_t depth, const output_buffer->offset += length; /* print value */ - if (!print_value(current_item, depth, format, output_buffer)) + if (!print_value(current_item, depth + 1, format, output_buffer)) { return NULL; } @@ -1441,21 +1408,22 @@ static unsigned char *print_object(const cJSON * const item, size_t depth, const current_item = current_item->next; } - output_pointer = ensure(output_buffer, format ? (depth + 1) : 2); + output_pointer = ensure(output_buffer, format ? (depth + 2) : 2); if (output_pointer == NULL) { return NULL; } if (format) { - for (i = 0; i < (depth - 1); i++) + size_t i; + for (i = 0; i < (depth); i++) { *output_pointer++ = '\t'; } } *output_pointer++ = '}'; *output_pointer = '\0'; - output = (output_buffer->buffer) + i; + output = (output_buffer->buffer) + output_offset; return output; }