[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 16/31] libxl_json: Allow partial parsing
This set of function allow to parse a JSON string that is spread accross different memory location. This is usefull when a JSON string is received from a remote process, and in order to avoid using realloc, the message is recorded in multiple buffers. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- tools/libxl/libxl_internal.h | 6 +++ tools/libxl/libxl_json.c | 100 +++++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 22 deletions(-) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index d9eebfd98b..c87712c83a 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2039,6 +2039,12 @@ _hidden void libxl__json_object_free(libxl__gc *gc_opt, libxl__json_object *obj); _hidden libxl__json_object *libxl__json_parse(libxl__gc *gc_opt, const char *s); +/* allow to parse a json string store in multiple buffers */ +_hidden libxl__yajl_ctx *libxl__json_parse_alloc(libxl__gc *gc); +_hidden int libxl__json_parse_partial(libxl__gc *gc, libxl__yajl_ctx *yajl_ctx, + const char *s, size_t len); +_hidden libxl__json_object *libxl__json_complete_parse(libxl__gc *gc, + libxl__yajl_ctx *yajl_ctx); /* Based on /local/domain/$domid/dm-version xenstore key * default is qemu xen traditional */ diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c index b7f9077f0d..3727af34d8 100644 --- a/tools/libxl/libxl_json.c +++ b/tools/libxl/libxl_json.c @@ -912,47 +912,103 @@ static void yajl_ctx_free(libxl__yajl_ctx *yajl_ctx) DEBUG_GEN_FREE(yajl_ctx); } -libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s) +/* + * Only to use with: + * libxl__json_parse_partial + * libxl__json_complete_parse + * + * gc should be the same accross all functions. + * NOGC is not allowed unless called from libxl__json_parse() + */ +libxl__yajl_ctx *libxl__json_parse_alloc(libxl__gc *gc) { - yajl_status status; - libxl__yajl_ctx yajl_ctx; - libxl__json_object *o = NULL; - unsigned char *str = NULL; + libxl__yajl_ctx *yajl_ctx; - memset(&yajl_ctx, 0, sizeof (yajl_ctx)); - yajl_ctx.gc = gc; + GCNEW(yajl_ctx); - DEBUG_GEN_ALLOC(&yajl_ctx); + yajl_ctx->gc = gc; - if (yajl_ctx.hand == NULL) { - yajl_ctx.hand = libxl__yajl_alloc(&callbacks, NULL, &yajl_ctx); - } - status = yajl_parse(yajl_ctx.hand, (const unsigned char *)s, strlen(s)); + DEBUG_GEN_ALLOC(yajl_ctx); + + yajl_ctx->hand = libxl__yajl_alloc(&callbacks, NULL, yajl_ctx); + + return yajl_ctx; +} + +static void json_parse_error(libxl__gc *gc, libxl__yajl_ctx *yajl_ctx, + const char *s, size_t len) +{ + unsigned char *str; + str = yajl_get_error(yajl_ctx->hand, 1, (const unsigned char*)s, len); + LOGE(ERROR, "yajl error: %s", str); + yajl_free_error(yajl_ctx->hand, str); + yajl_ctx_free(yajl_ctx); +} + +int libxl__json_parse_partial(libxl__gc *gc, libxl__yajl_ctx *yajl_ctx, + const char *s, size_t len) +{ + yajl_status status; + + assert(gc == yajl_ctx->gc); + + status = yajl_parse(yajl_ctx->hand, (const unsigned char *)s, strlen(s)); if (status != yajl_status_ok) goto out; - status = yajl_complete_parse(yajl_ctx.hand); + return 0; + +out: + json_parse_error(gc, yajl_ctx, s, len); + return ERROR_FAIL; +} + +libxl__json_object *libxl__json_complete_parse(libxl__gc *gc, + libxl__yajl_ctx *yajl_ctx) +{ + yajl_status status; + libxl__json_object *o; + + assert(gc == yajl_ctx->gc); + + status = yajl_complete_parse(yajl_ctx->hand); if (status != yajl_status_ok) goto out; - o = yajl_ctx.head; + o = yajl_ctx->head; - DEBUG_GEN_REPORT(&yajl_ctx); + DEBUG_GEN_REPORT(yajl_ctx); - yajl_ctx.head = NULL; + yajl_ctx->head = NULL; - yajl_ctx_free(&yajl_ctx); + yajl_ctx_free(yajl_ctx); return o; out: - str = yajl_get_error(yajl_ctx.hand, 1, (const unsigned char*)s, strlen(s)); - - LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR, "yajl error: %s", str); - yajl_free_error(yajl_ctx.hand, str); - yajl_ctx_free(&yajl_ctx); + json_parse_error(gc, yajl_ctx, NULL, 0); return NULL; } +libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s) +{ + libxl__yajl_ctx *yajl_ctx; + int rc; + libxl__json_object *o = NULL; + + yajl_ctx = libxl__json_parse_alloc(gc); + + rc = libxl__json_parse_partial(gc, yajl_ctx, s, strlen(s)); + if (rc) + goto out; + + o = libxl__json_complete_parse(gc, yajl_ctx); + +out: + if (!libxl__gc_is_real(gc)) + free(yajl_ctx); + return o; +} + static const char *yajl_gen_status_to_string(yajl_gen_status s) { switch (s) { -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |