From 0da30555bd95642063390306e215b13b3513ad8a Mon Sep 17 00:00:00 2001 From: liquidaty Date: Tue, 24 Jan 2023 17:17:23 -0800 Subject: [PATCH] add jsonwriter_write_raw(), jsonwriter_object_size_t(), jsonwriter_size_t(). fix misc bugs --- jsonwriter.c | 28 +++++++++++++++++++++++++--- jsonwriter.h | 10 ++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/jsonwriter.c b/jsonwriter.c index 085a54b..906e4e7 100644 --- a/jsonwriter.c +++ b/jsonwriter.c @@ -40,9 +40,11 @@ struct jsonwriter_data { }; static inline void jsonwriter_output_buff_flush(struct jsonwriter_output_buff *b) { - if(b->used) - b->write(b->buff, b->used, 1, b->write_arg); - b->used = 0; + if(b) { + if(b->used) + b->write(b->buff, b->used, 1, b->write_arg); + b->used = 0; + } } #ifndef JSONWRITER_NO_BUFF @@ -113,6 +115,8 @@ void jsonwriter_flush(jsonwriter_handle data) { } void jsonwriter_delete(jsonwriter_handle data) { + if(!data) return; + jsonwriter_flush(data); if(data->out.buff) free(data->out.buff); @@ -155,6 +159,11 @@ static int jsonwriter_indent(struct jsonwriter_data *data, unsigned char closing return 0; } +size_t jsonwriter_write_raw(jsonwriter_handle jsw, const unsigned char *s, size_t len) { + jsonwriter_indent(jsw, 0); + return jsonwriter_output_buff_write(&jsw->out, s, len); +} + static enum jsonwriter_status jsonwriter_end_aux(jsonwriter_handle data, unsigned char close_bracket) { // return 0 on success if(data->depth > 0) { if(close_bracket && data->close_brackets[data->depth-1] != close_bracket) @@ -299,6 +308,7 @@ int jsonwriter_dblf(jsonwriter_handle data, long double d, const char *format_st jsonwriter_indent(data, 0); format_string = format_string ? format_string : "%Lf"; int len = snprintf(data->tmp, sizeof(data->tmp), format_string, d); + // TO DO: check if len < 0 or len > sizeof(data->tmp) if(len && trim_trailing_zeros_after_dec && memchr(data->tmp, '.', len)) { while(len && data->tmp[len-1] == '0') len--; @@ -319,10 +329,22 @@ int jsonwriter_dbl(jsonwriter_handle data, long double d) { return jsonwriter_dblf(data, d, NULL, 1); } +int jsonwriter_size_t(jsonwriter_handle data, size_t sz) { + if(data->depth < JSONWRITER_MAX_NESTING) { + jsonwriter_indent(data, 0); + int len = snprintf(data->tmp, sizeof(data->tmp), "%zu", sz); + // TO DO: check if len < 0 or len > sizeof(data->tmp) + jsonwriter_output_buff_write(&data->out, (unsigned char *)data->tmp, len); + return 0; + } + return 1; +} + int jsonwriter_int(jsonwriter_handle data, jsw_int64 i) { if(data->depth < JSONWRITER_MAX_NESTING) { jsonwriter_indent(data, 0); int len = snprintf(data->tmp, sizeof(data->tmp), JSW_INT64_PRINTF_FMT, i); + // TO DO: check if len < 0 or len > sizeof(data->tmp) jsonwriter_output_buff_write(&data->out, (unsigned char *)data->tmp, len); return 0; } diff --git a/jsonwriter.h b/jsonwriter.h index ca7e7de..0b642cd 100644 --- a/jsonwriter.h +++ b/jsonwriter.h @@ -21,7 +21,7 @@ extern "C" { # define jsw_int64 int64_t # define JSW_INT64_MIN INT64_MIN # define JSW_INT64_MAX INT64_MAX -# define JSW_INT64_PRINTF_FMT "%"PRId64 +# define JSW_INT64_PRINTF_FMT "%" PRId64 # endif enum jsonwriter_option { @@ -69,8 +69,9 @@ extern "C" { #define jsonwriter_object_cstrn(h, key, v, len) jsonwriter_object_key(h, key), jsonwriter_cstrn(h, v, len) #define jsonwriter_object_bool(h, key, v) jsonwriter_object_key(h, key), jsonwriter_bool(h, v) #define jsonwriter_object_dbl(h, key, v) jsonwriter_object_key(h, key), jsonwriter_dbl(h, v) - #define jsonwriter_object_dblf(h, key, v, fmt, t) jsonwriter_object_key(h, key), jsonwriter_dblf(h, v, f, t) + #define jsonwriter_object_dblf(h, key, v, fmt, t) jsonwriter_object_key(h, key), jsonwriter_dblf(h, v, fmt, t) #define jsonwriter_object_int(h, key, v) jsonwriter_object_key(h, key), jsonwriter_int(h, v) + #define jsonwriter_object_size_t(h, key, v) jsonwriter_object_key(h, key), jsonwriter_size_t(h, v) #define jsonwriter_object_null(h, key) jsonwriter_object_key(h, key), jsonwriter_null(h) #define jsonwriter_object_array(h, key) jsonwriter_object_key(h, key), jsonwriter_start_array(h) #define jsonwriter_object_object(h, key) jsonwriter_object_key(h, key), jsonwriter_start_object(h) @@ -83,6 +84,7 @@ extern "C" { int jsonwriter_dbl(jsonwriter_handle h, long double d); int jsonwriter_dblf(jsonwriter_handle h, long double d, const char *format_string, unsigned char trim_trailing_zeros_after_dec); + int jsonwriter_size_t(jsonwriter_handle data, size_t sz); int jsonwriter_int(jsonwriter_handle h, jsw_int64 i); int jsonwriter_null(jsonwriter_handle h); @@ -122,6 +124,10 @@ extern "C" { // write a variant. will use custom to_jsw_variant() to convert data to jsonwriter_variant enum jsonwriter_status jsonwriter_variant(jsonwriter_handle h, void *data); + // write raw data to the output stream. Note: caller is responsible for ensuring that + // the raw data is valid JSON + size_t jsonwriter_write_raw(jsonwriter_handle jsw, const unsigned char *s, size_t len); + #ifdef __cplusplus } #endif