summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLloyd Hilaiel <lloyd@hilaiel.com>2015-09-24 13:11:40 -0600
committerLloyd Hilaiel <lloyd@hilaiel.com>2015-09-24 13:11:40 -0600
commit646b8b82ce5441db3d11b98a1049e1fcb50fe776 (patch)
tree3d236a66acafaa223b6634cb08ad0911f27eb0dd
parent12ee82ae5138ac86252c41f3ae8f9fd9880e4284 (diff)
downloadyajl_reset.tar.gz
add a way to reset a yajl parser without full re-allocationyajl_reset
-rw-r--r--src/api/yajl_parse.h5
-rw-r--r--src/yajl.c22
-rw-r--r--src/yajl_bytestack.h5
-rw-r--r--src/yajl_lex.c9
-rw-r--r--src/yajl_lex.h3
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
@@ -114,6 +114,15 @@ yajl_lex_alloc(yajl_alloc_funcs * alloc,
}
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)
{
yajl_buf_free(lxr->buf);
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);
/**