Speed up reading further by reading buffers instead of characters

This commit is contained in:
Eric Fischer 2014-10-19 15:35:28 -07:00
parent 84b9dea51e
commit 4bb441ce41
2 changed files with 41 additions and 20 deletions

View File

@ -5,7 +5,9 @@
#include <stdarg.h> #include <stdarg.h>
#include "jsonpull.h" #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)); json_pull *j = malloc(sizeof(json_pull));
j->error = NULL; 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->root = NULL;
j->read = read; j->read = read;
j->peek = peek;
j->source = source; j->source = source;
j->peeked = j->read(j); j->buffer = malloc(BUFFER);
j->buffer_head = 0;
j->buffer_tail = 0;
return j; return j;
} }
static inline int peek(json_pull *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) { static inline int next(json_pull *j) {
int ret = j->peeked; if (j->buffer_head < j->buffer_tail) {
j->peeked = j->read(j); return j->buffer[j->buffer_head++];
return ret; } 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) { static int read_file(json_pull *j, char *buffer, int n) {
return fgetc(j->source); return fread(buffer, 1, n, j->source);
}
static int peek_file(json_pull *j) {
int c = getc(j->source);
ungetc(c, j->source);
return c;
} }
json_pull *json_begin_file(FILE *f) { 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) { static int read_string(json_pull *j) {
char *cp = j->source; char *cp = j->source;
if (*cp == '\0') { if (*cp == '\0') {
@ -66,8 +80,10 @@ static int peek_string(json_pull *p) {
json_pull *json_begin_string(char *s) { json_pull *json_begin_string(char *s) {
return json_begin(read_string, peek_string, s); return json_begin(read_string, peek_string, s);
} }
#endif
void json_end(json_pull *p) { void json_end(json_pull *p) {
free(p->buffer);
free(p); free(p);
} }

View File

@ -28,18 +28,23 @@ typedef struct json_pull {
char *error; char *error;
int line; int line;
int (*read)(struct json_pull *); int (*read)(struct json_pull *, char *buf, int n);
int (*peek)(struct json_pull *);
int peeked;
void *source; void *source;
char *buffer;
int buffer_tail;
int buffer_head;
json_object *container; json_object *container;
json_object *root; json_object *root;
} json_pull; } json_pull;
json_pull *json_begin_file(FILE *f); json_pull *json_begin_file(FILE *f);
#if 0
json_pull *json_begin_string(char *s); 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); void json_end(json_pull *p);
typedef void (*json_separator_callback)(json_type type, json_pull *j, void *state); typedef void (*json_separator_callback)(json_type type, json_pull *j, void *state);