json-input iterate

This commit is contained in:
John Kerl 2016-01-31 16:03:55 -05:00
parent 8463365aa2
commit 2e27de52aa
3 changed files with 61 additions and 30 deletions

View file

@ -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;

View file

@ -45,23 +45,20 @@
#include <stdlib.h>
// ----------------------------------------------------------------
#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 *);

View file

@ -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;
}