diff --git a/jsonpull.c b/jsonpull.c index e2ce043f..1845a83f 100644 --- a/jsonpull.c +++ b/jsonpull.c @@ -5,7 +5,9 @@ #include #include "jsonpull.h" -json_pull *json_begin(int (*read)(struct json_pull *), int (*peek)(struct json_pull *), void *source) { +#define BUFFER 10000 + +json_pull *json_begin(int (*read)(struct json_pull *, char *buffer, int n), void *source) { json_pull *j = malloc(sizeof(json_pull)); j->error = NULL; @@ -14,37 +16,49 @@ json_pull *json_begin(int (*read)(struct json_pull *), int (*peek)(struct json_p j->root = NULL; j->read = read; - j->peek = peek; j->source = source; - j->peeked = j->read(j); + j->buffer = malloc(BUFFER); + j->buffer_head = 0; + j->buffer_tail = 0; return j; } static inline int peek(json_pull *j) { - return j->peeked; + if (j->buffer_head < j->buffer_tail) { + return j->buffer[j->buffer_head]; + } else { + j->buffer_head = 0; + j->buffer_tail = j->read(j, j->buffer, BUFFER); + if (j->buffer_head >= j->buffer_tail) { + return EOF; + } + return j->buffer[j->buffer_head]; + } } static inline int next(json_pull *j) { - int ret = j->peeked; - j->peeked = j->read(j); - return ret; + if (j->buffer_head < j->buffer_tail) { + return j->buffer[j->buffer_head++]; + } else { + j->buffer_head = 0; + j->buffer_tail = j->read(j, j->buffer, BUFFER); + if (j->buffer_head >= j->buffer_tail) { + return EOF; + } + return j->buffer[j->buffer_head++]; + } } -static int read_file(json_pull *j) { - return fgetc(j->source); -} - -static int peek_file(json_pull *j) { - int c = getc(j->source); - ungetc(c, j->source); - return c; +static int read_file(json_pull *j, char *buffer, int n) { + return fread(buffer, 1, n, j->source); } json_pull *json_begin_file(FILE *f) { - return json_begin(read_file, peek_file, f); + return json_begin(read_file, f); } +#if 0 static int read_string(json_pull *j) { char *cp = j->source; if (*cp == '\0') { @@ -66,8 +80,10 @@ static int peek_string(json_pull *p) { json_pull *json_begin_string(char *s) { return json_begin(read_string, peek_string, s); } +#endif void json_end(json_pull *p) { + free(p->buffer); free(p); } diff --git a/jsonpull.h b/jsonpull.h index 36bf3c87..df6652ec 100644 --- a/jsonpull.h +++ b/jsonpull.h @@ -28,18 +28,23 @@ typedef struct json_pull { char *error; int line; - int (*read)(struct json_pull *); - int (*peek)(struct json_pull *); - int peeked; + int (*read)(struct json_pull *, char *buf, int n); void *source; + char *buffer; + int buffer_tail; + int buffer_head; json_object *container; json_object *root; } json_pull; json_pull *json_begin_file(FILE *f); + +#if 0 json_pull *json_begin_string(char *s); -json_pull *json_begin(int (*read)(struct json_pull *), int (*peek)(struct json_pull *), void *source); +#endif + +json_pull *json_begin(int (*read)(struct json_pull *, char *buffer, int n), void *source); void json_end(json_pull *p); typedef void (*json_separator_callback)(json_type type, json_pull *j, void *state);