/**
* lejp_construct - prepare a struct lejp_ctx for use
*
- * @ctx: pointer to your struct lejp_ctx
- * @callback: your user callback which will received parsed tokens
- * @user: optional user data pointer untouched by lejp
- * @paths: your array of name elements you are interested in
- * @count_paths: ARRAY_SIZE() of @paths
+ * \param ctx: pointer to your struct lejp_ctx
+ * \param callback: your user callback which will received parsed tokens
+ * \param user: optional user data pointer untouched by lejp
+ * \param paths: your array of name elements you are interested in
+ * \param count_paths: ARRAY_SIZE() of @paths
*
* Prepares your context struct for use with lejp
*/
/**
* lejp_destruct - retire a previously constructed struct lejp_ctx
*
- * @ctx: pointer to your struct lejp_ctx
+ * \param ctx: pointer to your struct lejp_ctx
*
* lejp does not perform any allocations, but since your user code might, this
* provides a one-time LEJPCB_DESTRUCTED callback at destruction time where
/**
* lejp_change_callback - switch to a different callback from now on
*
- * @ctx: pointer to your struct lejp_ctx
- * @callback: your user callback which will received parsed tokens
+ * \param ctx: pointer to your struct lejp_ctx
+ * \param callback: your user callback which will received parsed tokens
*
* This tells the old callback it was destroyed, in case you want to take any
* action because that callback "lost focus", then changes to the new
/**
* lejp_parse - interpret some more incoming data incrementally
*
- * @ctx: previously constructed parsing context
- * @json: char buffer with the new data to interpret
- * @len: amount of data in the buffer
+ * \param ctx: previously constructed parsing context
+ * \param json: char buffer with the new data to interpret
+ * \param len: amount of data in the buffer
*
* Because lejp is a stream parser, it incrementally parses as new data
* becomes available, maintaining all state in the context struct. So an
ret = LEJP_REJECT_IDLE_NO_BRACE;
goto reject;
}
- ctx->callback(ctx, LEJPCB_OBJECT_START);
+ if (ctx->callback(ctx, LEJPCB_OBJECT_START)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
ctx->st[ctx->sp].s = LEJP_MEMBERS;
break;
case LEJP_MEMBERS:
ctx->path[ctx->ppos] = '\0';
lejp_check_path_match(ctx);
- ctx->callback(ctx, LEJPCB_PAIR_NAME);
+ if (ctx->callback(ctx, LEJPCB_PAIR_NAME)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
break;
case LEJP_MP_VALUE:
c = LEJP_MP_STRING;
ctx->npos = 0;
ctx->buf[0] = '\0';
- ctx->callback(ctx, LEJPCB_VAL_STR_START);
+ if (ctx->callback(ctx, LEJPCB_VAL_STR_START)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
goto add_stack_level;
case '{':
ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END;
c = LEJP_MEMBERS;
lejp_check_path_match(ctx);
- ctx->callback(ctx, LEJPCB_OBJECT_START);
+ if (ctx->callback(ctx, LEJPCB_OBJECT_START)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
ctx->path_match = 0;
goto add_stack_level;
ctx->path[ctx->ppos++] = '[';
ctx->path[ctx->ppos++] = ']';
ctx->path[ctx->ppos] = '\0';
- ctx->callback(ctx, LEJPCB_ARRAY_START);
+ if (ctx->callback(ctx, LEJPCB_ARRAY_START)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
ctx->i[ctx->ipos++] = 0;
if (ctx->ipos > ARRAY_SIZE(ctx->i)) {
ret = LEJP_REJECT_MP_DELIM_ISTACK;
}
ctx->buf[ctx->npos] = '\0';
- if (ctx->f & LEJP_SEEN_POINT)
- ctx->callback(ctx, LEJPCB_VAL_NUM_FLOAT);
- else
- ctx->callback(ctx, LEJPCB_VAL_NUM_INT);
+ if (ctx->f & LEJP_SEEN_POINT) {
+ if (ctx->callback(ctx, LEJPCB_VAL_NUM_FLOAT)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
+ } else {
+ if (ctx->callback(ctx, LEJPCB_VAL_NUM_INT)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
+ }
/* then this is the post-number character, loop */
ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END;
case 3:
ctx->buf[0] = '1';
ctx->buf[1] = '\0';
- ctx->callback(ctx, LEJPCB_VAL_TRUE);
+ if (ctx->callback(ctx, LEJPCB_VAL_TRUE)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
break;
case 8:
ctx->buf[0] = '0';
ctx->buf[1] = '\0';
- ctx->callback(ctx, LEJPCB_VAL_FALSE);
+ if (ctx->callback(ctx, LEJPCB_VAL_FALSE)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
break;
case 12:
ctx->buf[0] = '\0';
- ctx->callback(ctx, LEJPCB_VAL_NULL);
+ if (ctx->callback(ctx, LEJPCB_VAL_NULL)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
break;
}
ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END;
if (c == '}') {
if (ctx->sp == 0) {
lejp_check_path_match(ctx);
- ctx->callback(ctx, LEJPCB_OBJECT_END);
+ if (ctx->callback(ctx, LEJPCB_OBJECT_END)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
ctx->callback(ctx, LEJPCB_COMPLETE);
/* done, return unused amount */
return len;
*/
ctx->path_match = 0;
lejp_check_path_match(ctx);
- ctx->callback(ctx, LEJPCB_OBJECT_END);
+ if (ctx->callback(ctx, LEJPCB_OBJECT_END)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
break;
}
/* assemble the string value into chunks */
ctx->buf[ctx->npos++] = c;
if (ctx->npos == sizeof(ctx->buf) - 1) {
- ctx->callback(ctx, LEJPCB_VAL_STR_CHUNK);
+ if (ctx->callback(ctx, LEJPCB_VAL_STR_CHUNK)) {
+ ret = LEJP_REJECT_CALLBACK;
+ goto reject;
+ }
ctx->npos = 0;
}
continue;