From 263adf537abb02300738bb96e551f7002a8582df Mon Sep 17 00:00:00 2001 From: Lloyd Hilaiel Date: Fri, 14 Mar 2014 12:48:33 +0200 Subject: add generator reset, and ability to verify and reformat streams --- reformatter/json_reformat.c | 40 ++++++++++++++++++++++++++++------------ src/api/yajl_gen.h | 8 ++++++++ src/yajl_gen.c | 8 ++++++++ verify/json_verify.c | 6 +++--- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/reformatter/json_reformat.c b/reformatter/json_reformat.c index ca7af87..2ed4f39 100644 --- a/reformatter/json_reformat.c +++ b/reformatter/json_reformat.c @@ -21,61 +21,73 @@ #include #include +/* non-zero when we're reformatting a stream */ +static int s_streamReformat = 0; + +#define GEN_AND_RETURN(func) \ + { \ + yajl_gen_status __stat = func; \ + if (__stat == yajl_gen_generation_complete && s_streamReformat) { \ + yajl_gen_reset(g, "\n"); \ + __stat = func; \ + } \ + return __stat == yajl_gen_status_ok; } + static int reformat_null(void * ctx) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_null(g); + GEN_AND_RETURN(yajl_gen_null(g)); } static int reformat_boolean(void * ctx, int boolean) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_bool(g, boolean); + GEN_AND_RETURN(yajl_gen_bool(g, boolean)); } static int reformat_number(void * ctx, const char * s, size_t l) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_number(g, s, l); + GEN_AND_RETURN(yajl_gen_number(g, s, l)); } static int reformat_string(void * ctx, const unsigned char * stringVal, size_t stringLen) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen); + GEN_AND_RETURN(yajl_gen_string(g, stringVal, stringLen)); } static int reformat_map_key(void * ctx, const unsigned char * stringVal, size_t stringLen) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen); + GEN_AND_RETURN(yajl_gen_string(g, stringVal, stringLen)); } static int reformat_start_map(void * ctx) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_map_open(g); + GEN_AND_RETURN(yajl_gen_map_open(g)); } static int reformat_end_map(void * ctx) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_map_close(g); + GEN_AND_RETURN(yajl_gen_map_close(g)); } static int reformat_start_array(void * ctx) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_array_open(g); + GEN_AND_RETURN(yajl_gen_array_open(g)); } static int reformat_end_array(void * ctx) { yajl_gen g = (yajl_gen) ctx; - return yajl_gen_status_ok == yajl_gen_array_close(g); + GEN_AND_RETURN(yajl_gen_array_close(g)); } static yajl_callbacks callbacks = { @@ -97,14 +109,14 @@ usage(const char * progname) { fprintf(stderr, "%s: reformat json from stdin\n" "usage: json_reformat [options]\n" + " -e escape any forward slashes (for embedding in HTML)\n" " -m minimize json rather than beautify (default)\n" - " -u allow invalid UTF8 inside strings during parsing\n" - " -e escape any forward slashes (for embedding in HTML)\n", + " -s reformat a stream of multiple json entites\n" + " -u allow invalid UTF8 inside strings during parsing\n", progname); exit(1); } - int main(int argc, char ** argv) { @@ -134,6 +146,10 @@ main(int argc, char ** argv) case 'm': yajl_gen_config(g, yajl_gen_beautify, 0); break; + case 's': + yajl_config(hand, yajl_allow_multiple_values, 1); + s_streamReformat = 1; + break; case 'u': yajl_config(hand, yajl_dont_validate_strings, 1); break; diff --git a/src/api/yajl_gen.h b/src/api/yajl_gen.h index 4962e06..ddd1527 100644 --- a/src/api/yajl_gen.h +++ b/src/api/yajl_gen.h @@ -150,6 +150,14 @@ extern "C" { * intended to enable incremental JSON outputing. */ YAJL_API void yajl_gen_clear(yajl_gen hand); + /** Reset the generator state. Allows a client to generate multiple + * json entities in a stream. The "sep" string will be inserted to + * separate the previously generated entity from the current, + * NULL means *no separation* of entites (clients beware, generating + * multiple JSON numbers, for instance, will result in inscrutable + * output) */ + YAJL_API void yajl_gen_reset(yajl_gen hand, const char * sep); + #ifdef __cplusplus } #endif diff --git a/src/yajl_gen.c b/src/yajl_gen.c index eccfa42..0f5c68e 100644 --- a/src/yajl_gen.c +++ b/src/yajl_gen.c @@ -125,6 +125,14 @@ yajl_gen_alloc(const yajl_alloc_funcs * afs) return g; } +void +yajl_gen_reset(yajl_gen g, const char * sep) +{ + g->depth = 0; + memset((void *) &(g->state), 0, sizeof(g->state)); + if (sep != NULL) g->print(g->ctx, sep, strlen(sep)); +} + void yajl_gen_free(yajl_gen g) { diff --git a/verify/json_verify.c b/verify/json_verify.c index 211efe3..01849e0 100644 --- a/verify/json_verify.c +++ b/verify/json_verify.c @@ -25,9 +25,9 @@ usage(const char * progname) { fprintf(stderr, "%s: validate json from stdin\n" "usage: json_verify [options]\n" - " -q quiet mode\n" " -c allow comments\n" - " -m verify a stream of multiple json entities\n", + " -q quiet mode\n" + " -s verify a stream of multiple json entities\n" " -u allow invalid utf8 inside strings\n", progname); exit(1); @@ -61,7 +61,7 @@ main(int argc, char ** argv) case 'u': yajl_config(hand, yajl_dont_validate_strings, 1); break; - case 'm': + case 's': yajl_config(hand, yajl_allow_multiple_values, 1); break; default: -- cgit v1.2.1