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, | |||
| str + 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; | |||
| } else | |||
| pos++; | |||
| @@ -585,7 +589,10 @@ static int json_object_int_to_json_string(struct json_object* jso, | |||
| int level, | |||
| 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) | |||
| @@ -85,6 +85,7 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size) | |||
| if (printbuf_extend(p, p->bpos + size + 1) < 0) | |||
| return -1; | |||
| } | |||
| memcpy(p->buf + p->bpos, buf, size); | |||
| p->bpos += size; | |||
| p->buf[p->bpos]= '\0'; | |||
| @@ -111,34 +112,6 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) | |||
| 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) | |||
| { | |||
| p->buf[0] = '\0'; | |||
| @@ -152,3 +125,8 @@ void printbuf_free(struct printbuf *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); | |||
| extern int | |||
| sprintbuf(struct printbuf *p, const char *msg, ...); | |||
| sprintbuf(struct printbuf *p, const char *msg); | |||
| extern void | |||
| printbuf_reset(struct printbuf *p); | |||
| @@ -17,7 +17,7 @@ static void test_basic_printbuf_memset() | |||
| printf("%s: starting test\n", __func__); | |||
| pb = printbuf_new(); | |||
| sprintbuf(pb, "blue:%d", 1); | |||
| sprintbuf(pb, "blue:1"); | |||
| printbuf_memset(pb, -1, 'x', 52); | |||
| printf("Buffer contents:%.*s\n", printbuf_length(pb), pb->buf); | |||
| printbuf_free(pb); | |||
| @@ -111,42 +111,6 @@ static void test_printbuf_memappend(int *before_resize) | |||
| 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 before_resize = 0; | |||
| @@ -159,8 +123,6 @@ int main(int argc, char **argv) | |||
| printf("========================================\n"); | |||
| test_printbuf_memappend(&before_resize); | |||
| printf("========================================\n"); | |||
| test_sprintbuf(before_resize); | |||
| printf("========================================\n"); | |||
| return 0; | |||
| } | |||
| @@ -20,13 +20,3 @@ Append to just before resize: 31, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] | |||
| Append to just after resize: 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] | |||
| 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 | |||
| ======================================== | |||