Removes variadic prints for ~3x performance improvement.tags/json-c-0.13-20171207
| @@ -147,9 +147,13 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl | |||||
| printbuf_memappend(pb, | printbuf_memappend(pb, | ||||
| str + start_offset, | str + start_offset, | ||||
| pos - start_offset); | pos - start_offset); | ||||
| sprintbuf(pb, "\\u00%c%c", | |||||
| json_hex_chars[c >> 4], | |||||
| json_hex_chars[c & 0xf]); | |||||
| static char sbuf[7]; | |||||
| snprintf(sbuf, sizeof(sbuf), | |||||
| "\\u00%c%c", | |||||
| json_hex_chars[c >> 4], | |||||
| json_hex_chars[c & 0xf]); | |||||
| printbuf_memappend (pb, sbuf, sizeof(sbuf) - 1); | |||||
| start_offset = ++pos; | start_offset = ++pos; | ||||
| } else | } else | ||||
| pos++; | pos++; | ||||
| @@ -585,7 +589,10 @@ static int json_object_int_to_json_string(struct json_object* jso, | |||||
| int level, | int level, | ||||
| int flags) | int flags) | ||||
| { | { | ||||
| return sprintbuf(pb, "%" PRId64, jso->o.c_int64); | |||||
| /* room for 19 digits, the sign char, and a null term */ | |||||
| static char sbuf[21]; | |||||
| snprintf(sbuf, sizeof(sbuf), "%"PRId64, jso->o.c_int64); | |||||
| return sprintbuf(pb, sbuf); | |||||
| } | } | ||||
| struct json_object* json_object_new_int(int32_t i) | struct json_object* json_object_new_int(int32_t i) | ||||
| @@ -85,6 +85,7 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size) | |||||
| if (printbuf_extend(p, p->bpos + size + 1) < 0) | if (printbuf_extend(p, p->bpos + size + 1) < 0) | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| memcpy(p->buf + p->bpos, buf, size); | memcpy(p->buf + p->bpos, buf, size); | ||||
| p->bpos += size; | p->bpos += size; | ||||
| p->buf[p->bpos]= '\0'; | p->buf[p->bpos]= '\0'; | ||||
| @@ -111,34 +112,6 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| int sprintbuf(struct printbuf *p, const char *msg, ...) | |||||
| { | |||||
| va_list ap; | |||||
| char *t; | |||||
| int size; | |||||
| char buf[128]; | |||||
| /* user stack buffer first */ | |||||
| va_start(ap, msg); | |||||
| size = vsnprintf(buf, 128, msg, ap); | |||||
| va_end(ap); | |||||
| /* if string is greater than stack buffer, then use dynamic string | |||||
| with vasprintf. Note: some implementation of vsnprintf return -1 | |||||
| if output is truncated whereas some return the number of bytes that | |||||
| would have been written - this code handles both cases. */ | |||||
| if(size == -1 || size > 127) { | |||||
| va_start(ap, msg); | |||||
| if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; } | |||||
| va_end(ap); | |||||
| printbuf_memappend(p, t, size); | |||||
| free(t); | |||||
| return size; | |||||
| } else { | |||||
| printbuf_memappend(p, buf, size); | |||||
| return size; | |||||
| } | |||||
| } | |||||
| void printbuf_reset(struct printbuf *p) | void printbuf_reset(struct printbuf *p) | ||||
| { | { | ||||
| p->buf[0] = '\0'; | p->buf[0] = '\0'; | ||||
| @@ -152,3 +125,8 @@ void printbuf_free(struct printbuf *p) | |||||
| free(p); | free(p); | ||||
| } | } | ||||
| } | } | ||||
| inline int sprintbuf(struct printbuf *p, const char *buf) | |||||
| { | |||||
| return printbuf_memappend(p, buf, strlen(buf)); | |||||
| } | |||||
| @@ -62,7 +62,7 @@ extern int | |||||
| printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len); | printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len); | ||||
| extern int | extern int | ||||
| sprintbuf(struct printbuf *p, const char *msg, ...); | |||||
| sprintbuf(struct printbuf *p, const char *msg); | |||||
| extern void | extern void | ||||
| printbuf_reset(struct printbuf *p); | printbuf_reset(struct printbuf *p); | ||||
| @@ -17,7 +17,7 @@ static void test_basic_printbuf_memset() | |||||
| printf("%s: starting test\n", __func__); | printf("%s: starting test\n", __func__); | ||||
| pb = printbuf_new(); | pb = printbuf_new(); | ||||
| sprintbuf(pb, "blue:%d", 1); | |||||
| sprintbuf(pb, "blue:1"); | |||||
| printbuf_memset(pb, -1, 'x', 52); | printbuf_memset(pb, -1, 'x', 52); | ||||
| printf("Buffer contents:%.*s\n", printbuf_length(pb), pb->buf); | printf("Buffer contents:%.*s\n", printbuf_length(pb), pb->buf); | ||||
| printbuf_free(pb); | printbuf_free(pb); | ||||
| @@ -111,42 +111,6 @@ static void test_printbuf_memappend(int *before_resize) | |||||
| printf("%s: end test\n", __func__); | printf("%s: end test\n", __func__); | ||||
| } | } | ||||
| static void test_sprintbuf(int before_resize); | |||||
| static void test_sprintbuf(int before_resize) | |||||
| { | |||||
| struct printbuf *pb; | |||||
| printf("%s: starting test\n", __func__); | |||||
| pb = printbuf_new(); | |||||
| printf("Buffer length: %d\n", printbuf_length(pb)); | |||||
| char *data = malloc(before_resize + 1 + 1); | |||||
| memset(data, 'X', before_resize + 1 + 1); | |||||
| data[before_resize + 1] = '\0'; | |||||
| sprintbuf(pb, "%s", data); | |||||
| free(data); | |||||
| printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf)); | |||||
| printbuf_reset(pb); | |||||
| sprintbuf(pb, "plain"); | |||||
| printf("%d, [%s]\n", printbuf_length(pb), pb->buf); | |||||
| sprintbuf(pb, "%d", 1); | |||||
| printf("%d, [%s]\n", printbuf_length(pb), pb->buf); | |||||
| sprintbuf(pb, "%d", INT_MAX); | |||||
| printf("%d, [%s]\n", printbuf_length(pb), pb->buf); | |||||
| sprintbuf(pb, "%d", INT_MIN); | |||||
| printf("%d, [%s]\n", printbuf_length(pb), pb->buf); | |||||
| sprintbuf(pb, "%s", "%s"); | |||||
| printf("%d, [%s]\n", printbuf_length(pb), pb->buf); | |||||
| printbuf_free(pb); | |||||
| printf("%s: end test\n", __func__); | |||||
| } | |||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
| { | { | ||||
| int before_resize = 0; | int before_resize = 0; | ||||
| @@ -159,8 +123,6 @@ int main(int argc, char **argv) | |||||
| printf("========================================\n"); | printf("========================================\n"); | ||||
| test_printbuf_memappend(&before_resize); | test_printbuf_memappend(&before_resize); | ||||
| printf("========================================\n"); | printf("========================================\n"); | ||||
| test_sprintbuf(before_resize); | |||||
| printf("========================================\n"); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -20,13 +20,3 @@ Append to just before resize: 31, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] | |||||
| Append to just after resize: 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] | Append to just after resize: 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] | ||||
| test_printbuf_memappend: end test | test_printbuf_memappend: end test | ||||
| ======================================== | ======================================== | ||||
| test_sprintbuf: starting test | |||||
| Buffer length: 0 | |||||
| sprintbuf to just after resize(31+1): 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX], strlen(buf)=32 | |||||
| 5, [plain] | |||||
| 6, [plain1] | |||||
| 16, [plain12147483647] | |||||
| 27, [plain12147483647-2147483648] | |||||
| 29, [plain12147483647-2147483648%s] | |||||
| test_sprintbuf: end test | |||||
| ======================================== | |||||