From 646b8b82ce5441db3d11b98a1049e1fcb50fe776 Mon Sep 17 00:00:00 2001 From: Lloyd Hilaiel Date: Thu, 24 Sep 2015 13:11:40 -0600 Subject: add a way to reset a yajl parser without full re-allocation --- src/api/yajl_parse.h | 5 +++++ src/yajl.c | 22 +++++++++++++++++++++- src/yajl_bytestack.h | 5 ++++- src/yajl_lex.c | 9 +++++++++ src/yajl_lex.h | 3 +++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/api/yajl_parse.h b/src/api/yajl_parse.h index 1c25a60..4455df4 100644 --- a/src/api/yajl_parse.h +++ b/src/api/yajl_parse.h @@ -108,6 +108,11 @@ extern "C" { yajl_alloc_funcs * afs, void * ctx); + /** reset a parser handle to a pristine state. the parser will be minimally + * re-initialized. This should be faster when parsing multiple documents + * than freeing and re-allocating a YAJL parser. + */ + YAJL_API void yajl_reset(yajl_handle h); /** configuration parameters for the parser, these may be passed to * yajl_config() along with option specific argument(s). In general, diff --git a/src/yajl.c b/src/yajl.c index d477893..65fc123 100644 --- a/src/yajl.c +++ b/src/yajl.c @@ -68,7 +68,7 @@ yajl_alloc(const yajl_callbacks * callbacks, hand->callbacks = callbacks; hand->ctx = ctx; - hand->lexer = NULL; + hand->lexer = NULL; hand->bytesConsumed = 0; hand->decodeBuf = yajl_buf_alloc(&(hand->alloc)); hand->flags = 0; @@ -78,6 +78,26 @@ yajl_alloc(const yajl_callbacks * callbacks, return hand; } +void +yajl_reset(yajl_handle h) +{ + // reset the state stack to start + yajl_bs_flush(h->stateStack); + yajl_bs_push(h->stateStack, yajl_state_start); + + // reset bytesConsumed + h->bytesConsumed = 0; + + // clear decoding buf (note: not strictly neccesary, as + // this buffer is cleared on demand and reused) + yajl_buf_clear(h->decodeBuf); + + // reset lexer state + if (h->lexer != NULL) { + yajl_lex_reset(h->lexer); + } +} + int yajl_config(yajl_handle h, yajl_option opt, ...) { diff --git a/src/yajl_bytestack.h b/src/yajl_bytestack.h index 9ea7d15..4e3d3df 100644 --- a/src/yajl_bytestack.h +++ b/src/yajl_bytestack.h @@ -43,10 +43,13 @@ typedef struct yajl_bytestack_t } \ -/* initialize a bytestack */ +/* free dynamically allocated memory inside a byte stack */ #define yajl_bs_free(obs) \ if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack); +#define yajl_bs_flush(obs) \ + (obs).used = 0; + #define yajl_bs_current(obs) \ (assert((obs).used > 0), (obs).stack[(obs).used - 1]) diff --git a/src/yajl_lex.c b/src/yajl_lex.c index 0b6f7cc..7a070b5 100644 --- a/src/yajl_lex.c +++ b/src/yajl_lex.c @@ -113,6 +113,15 @@ yajl_lex_alloc(yajl_alloc_funcs * alloc, return lxr; } +void +yajl_lex_reset(yajl_lexer l) { + l->lineOff = 0; + l->charOff = 0; + l->error = yajl_lex_e_ok; + yajl_buf_clear(l->buf); + l->bufOff = 0; +} + void yajl_lex_free(yajl_lexer lxr) { diff --git a/src/yajl_lex.h b/src/yajl_lex.h index fd17c00..b0ccd42 100644 --- a/src/yajl_lex.h +++ b/src/yajl_lex.h @@ -51,6 +51,9 @@ yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc, unsigned int allowComments, unsigned int validateUTF8); +void yajl_lex_reset(yajl_lexer l); + + void yajl_lex_free(yajl_lexer lexer); /** -- cgit v1.2.1