From 2e27de52aaeef64f7e462fa5bad4a1bbd6a9bf94 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Sun, 31 Jan 2016 16:03:55 -0500 Subject: [PATCH] json-input iterate --- c/input/json.c | 30 +++++++++++++++++++----------- c/input/json.h | 16 +++++++--------- c/input/test_json.c | 45 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/c/input/json.c b/c/input/json.c index 40ff1f603..fb4fbcece 100644 --- a/c/input/json.c +++ b/c/input/json.c @@ -209,12 +209,20 @@ static const long flag_line_comment = 1 << 13, flag_block_comment = 1 << 14; +// ================================================================ +json_value_t * json_parse(const json_char * json, size_t length, char* error_buf) { + json_settings_t settings = { 0 }; + json_char* prename_me = 0; + return json_parse_ex(json, length, error_buf, &prename_me, &settings); +} + // ---------------------------------------------------------------- json_value_t * json_parse_ex( - json_settings_t * settings, const json_char * json, size_t length, - char * error_buf) + char * error_buf, + json_char** pprename_me, + json_settings_t* settings) { json_char error [JSON_ERROR_MAX]; const json_char * end; @@ -223,6 +231,7 @@ json_value_t * json_parse_ex( long flags; long num_digits = 0, num_e = 0; json_int_t num_fraction = 0; + *pprename_me = NULL; // Skip UTF-8 BOM if (length >= 3 && ((unsigned char) json [0]) == 0xEF @@ -262,7 +271,8 @@ json_value_t * json_parse_ex( state.cur_line = 1; for (state.ptr = json ;; ++state.ptr) { - json_char b = (state.ptr == end ? 0 : *state.ptr); + json_char* pb = (json_char*)((state.ptr == end) ? NULL : state.ptr); + json_char b = (state.ptr == end) ? 0 : *state.ptr; if (flags & flag_string) { if (!b) { @@ -407,7 +417,7 @@ json_value_t * json_parse_ex( } } - if (state.settings.settings & JSON_ENABLE_COMMENTS) { + if (state.settings.setting_flags & JSON_ENABLE_COMMENTS) { if (flags & (flag_line_comment | flag_block_comment)) { if (flags & flag_line_comment) { if (b == '\r' || b == '\n' || !b) { @@ -461,6 +471,10 @@ json_value_t * json_parse_ex( if (flags & flag_done) { if (!b) break; + if (state.settings.setting_flags & JSON_ENABLE_SEQUENTIAL_OBJECTS) { + *pprename_me = pb + 1; + break; + } switch (b) { WHITESPACE: @@ -608,7 +622,7 @@ json_value_t * json_parse_ex( flags |= flag_num_negative; continue; } else { - sprintf(error, "%d:%d: Unexpected %c when seeking value", LINE_AND_COL, b); + sprintf(error, "%d:%d: Unexpected `%c` when seeking value", LINE_AND_COL, b); goto e_failed; } }; @@ -836,12 +850,6 @@ e_failed: return 0; } -// ---------------------------------------------------------------- -json_value_t * json_parse(const json_char * json, size_t length, char* error_buf) { - json_settings_t settings = { 0 }; - return json_parse_ex(&settings, json, length, error_buf); -} - // ---------------------------------------------------------------- void json_value_free_ex(json_settings_t * settings, json_value_t * value) { json_value_t * cur_value; diff --git a/c/input/json.h b/c/input/json.h index cb991633f..96d503d7b 100644 --- a/c/input/json.h +++ b/c/input/json.h @@ -45,23 +45,20 @@ #include // ---------------------------------------------------------------- +#define JSON_ENABLE_COMMENTS 0x01 +#define JSON_ENABLE_SEQUENTIAL_OBJECTS 0x02 + typedef struct { + int setting_flags; unsigned long max_memory; - int settings; // Custom allocator support (leave null to use malloc/free) - void * (* mem_alloc) (size_t, int zero, void * user_data); void (* mem_free) (void *, void * user_data); - void * user_data; /* will be passed to mem_alloc and mem_free */ - size_t value_extra; /* how much extra space to allocate for values? */ - } json_settings_t; -#define JSON_ENABLE_COMMENTS 0x01 - typedef enum { json_none, json_object, @@ -128,10 +125,11 @@ json_value_t * json_parse( char* error_buf); json_value_t * json_parse_ex( - json_settings_t * settings, const json_char * json, size_t length, - char * error); + char * error_buf, + json_char** pprename_me, + json_settings_t * settings); void json_value_free(json_value_t *); diff --git a/c/input/test_json.c b/c/input/test_json.c index 11fea13db..d8524cb8c 100644 --- a/c/input/test_json.c +++ b/c/input/test_json.c @@ -76,6 +76,9 @@ static void process_array(json_value_t* value, int depth) { } } +// xxx Miller top-levels will be JSON "object" (i.e. Miller hashmap) +// or JSON "array" (i.e. Miller list of hashmap). In the latter case +// all second-level objects must be objects. static void process_value(json_value_t* value, int depth) { if (value == NULL) { return; @@ -153,23 +156,45 @@ int notmain(int argc, char** argv) { } fclose(fp); - //printf("%s\n", file_contents); - //printf("--------------------------------\n\n"); json_char error_buf[JSON_ERROR_MAX]; json = (json_char*)file_contents; - value = json_parse(json,file_size, error_buf); + json_settings_t settings = { + .setting_flags = JSON_ENABLE_SEQUENTIAL_OBJECTS, + .max_memory = 0 + }; + json_char* prename_me = json; + int length = file_size; - if (value == NULL) { - fprintf(stderr, "Unable to parse data: %s\n", error_buf); - free(file_contents); - exit(1); + while (1) { + + //printf("--------------------------------\n\n"); + //printf("[%s]\n", prename_me); + //printf("--------------------------------\n\n"); + value = json_parse_ex(prename_me, length, error_buf, &prename_me, &settings); + + if (value == NULL) { + fprintf(stderr, "Unable to parse data: \"%s\"\n", error_buf); + free(file_contents); + exit(1); + } + + process_value(value, 0); + + json_value_free(value); + + if (prename_me == NULL) + break; + if (*prename_me == 0) + break; + //printf("\n"); + //printf("PAGE\n"); + //printf("\n"); + length -= (prename_me - json); + json = prename_me; } - process_value(value, 0); - - json_value_free(value); free(file_contents); return 0; }