Skip to content

add a way to reset a yajl parser without full re-allocation #197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/api/yajl_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
22 changes: 21 additions & 1 deletion src/yajl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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, ...)
{
Expand Down
5 changes: 4 additions & 1 deletion src/yajl_bytestack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand Down
9 changes: 9 additions & 0 deletions src/yajl_lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
3 changes: 3 additions & 0 deletions src/yajl_lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand Down