diff --git a/src/api/yajl_parse.h b/src/api/yajl_parse.h index 1c25a60d..4455df49 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 d477893f..65fc1232 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 9ea7d151..4e3d3df8 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 0b6f7ccf..7a070b5b 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 fd17c001..b0ccd428 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); /**