[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Re: [PATCH RESEND V8 6/7] libxl: Introduce JSON parsing stuff.



On Wed, 2011-09-21 at 13:59 +0100, Anthony PERARD wrote:
> We use the yajl parser, but we need to make a tree from the parse result
> to use it outside the parser.
> 
> So this patch include json_object struct that is used to hold the JSON
> data.
> 
> Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>

I didn't review this again but I recall being happy with it last time
round so:

Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>


> ---
>  README                       |    1 +
>  tools/libxl/Makefile         |    5 +-
>  tools/libxl/libxl_internal.h |  100 ++++++++
>  tools/libxl/libxl_json.c     |  560 
> ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 665 insertions(+), 1 deletions(-)
>  create mode 100644 tools/libxl/libxl_json.c
> 
> diff --git a/README b/README
> index ff154b2..c9bf699 100644
> --- a/README
> +++ b/README
> @@ -47,6 +47,7 @@ provided by your OS distributor:
>      * Development install of openssl (e.g., openssl-dev)
>      * Development install of x11 (e.g. xorg-x11-dev)
>      * Development install of uuid (e.g. uuid-dev)
> +    * Development install of yajl (e.g. libyajl-dev)
>      * bridge-utils package (/sbin/brctl)
>      * iproute package (/sbin/ip)
>      * hotplug or udev
> diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
> index 1f6b418..e50874e 100644
> --- a/tools/libxl/Makefile
> +++ b/tools/libxl/Makefile
> @@ -32,9 +32,12 @@ endif
>  LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
>  LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
> 
> +LIBXL_LIBS += -lyajl
> +
>  LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
>                         libxl_dom.o libxl_exec.o libxl_xshelp.o 
> libxl_device.o \
> -                       libxl_internal.o libxl_utils.o libxl_uuid.o 
> $(LIBXL_OBJS-y)
> +                       libxl_internal.o libxl_utils.o libxl_uuid.o 
> libxl_json.o \
> +                       $(LIBXL_OBJS-y)
>  LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
> 
>  $(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) 
> $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index d873243..f495e86 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -387,4 +387,104 @@ _hidden int libxl__e820_alloc(libxl_ctx *ctx, uint32_t 
> domid, libxl_domain_confi
>  #define STRINGIFY(x) #x
>  #define TOSTRING(x) STRINGIFY(x)
> 
> +/* from libxl_json */
> +#include <yajl/yajl_gen.h>
> +
> +_hidden yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char 
> *str);
> +
> +typedef enum {
> +    JSON_ERROR,
> +    JSON_NULL,
> +    JSON_TRUE,
> +    JSON_FALSE,
> +    JSON_INTEGER,
> +    JSON_DOUBLE,
> +    JSON_STRING,
> +    JSON_MAP,
> +    JSON_ARRAY,
> +    JSON_ANY
> +} libxl__json_node_type;
> +
> +typedef struct libxl__json_object {
> +    libxl__json_node_type type;
> +    union {
> +        long i;
> +        double d;
> +        char *string;
> +        /* List of libxl__json_object */
> +        flexarray_t *array;
> +        /* List of libxl__json_map_node */
> +        flexarray_t *map;
> +    } u;
> +    struct libxl__json_object *parent;
> +} libxl__json_object;
> +
> +typedef struct {
> +    char *map_key;
> +    libxl__json_object *obj;
> +} libxl__json_map_node;
> +
> +typedef struct libxl__yajl_ctx libxl__yajl_ctx;
> +
> +static inline bool libxl__json_object_is_string(const libxl__json_object *o)
> +{
> +    return o != NULL && o->type == JSON_STRING;
> +}
> +static inline bool libxl__json_object_is_integer(const libxl__json_object *o)
> +{
> +    return o != NULL && o->type == JSON_INTEGER;
> +}
> +static inline bool libxl__json_object_is_map(const libxl__json_object *o)
> +{
> +    return o != NULL && o->type == JSON_MAP;
> +}
> +static inline bool libxl__json_object_is_array(const libxl__json_object *o)
> +{
> +    return o != NULL && o->type == JSON_ARRAY;
> +}
> +
> +static inline
> +const char *libxl__json_object_get_string(const libxl__json_object *o)
> +{
> +    if (libxl__json_object_is_string(o))
> +        return o->u.string;
> +    else
> +        return NULL;
> +}
> +static inline
> +flexarray_t *libxl__json_object_get_map(const libxl__json_object *o)
> +{
> +    if (libxl__json_object_is_map(o))
> +        return o->u.map;
> +    else
> +        return NULL;
> +}
> +static inline
> +flexarray_t *libxl__json_object_get_array(const libxl__json_object *o)
> +{
> +    if (libxl__json_object_is_array(o))
> +        return o->u.array;
> +    else
> +        return NULL;
> +}
> +static inline long libxl__json_object_get_integer(const libxl__json_object 
> *o)
> +{
> +    if (libxl__json_object_is_integer(o))
> +        return o->u.i;
> +    else
> +        return -1;
> +}
> +
> +_hidden libxl__json_object *libxl__json_array_get(const libxl__json_object 
> *o,
> +                                                  int i);
> +_hidden
> +libxl__json_map_node *libxl__json_map_node_get(const libxl__json_object *o,
> +                                               int i);
> +_hidden const libxl__json_object *libxl__json_map_get(const char *key,
> +                                          const libxl__json_object *o,
> +                                          libxl__json_node_type 
> expected_type);
> +_hidden void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj);
> +
> +_hidden libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s);
> +
>  #endif
> diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
> new file mode 100644
> index 0000000..e771925
> --- /dev/null
> +++ b/tools/libxl/libxl_json.c
> @@ -0,0 +1,560 @@
> +/*
> + * Copyright (C) 2011      Citrix Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; version 2.1 only. with the special
> + * exception on linking described in file LICENSE.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU Lesser General Public License for more details.
> + */
> +
> +#include <assert.h>
> +#include <string.h>
> +
> +#include <yajl/yajl_parse.h>
> +#include <yajl/yajl_gen.h>
> +
> +#include "libxl_internal.h"
> +
> +/* #define DEBUG_ANSWER */
> +
> +struct libxl__yajl_ctx {
> +    libxl__gc *gc;
> +    yajl_handle hand;
> +    libxl__json_object *head;
> +    libxl__json_object *current;
> +#ifdef DEBUG_ANSWER
> +    yajl_gen g;
> +#endif
> +};
> +
> +#ifdef DEBUG_ANSWER
> +#  define DEBUG_GEN_ALLOC(ctx) \
> +    if ((ctx)->g == NULL) { \
> +        yajl_gen_config conf = { 1, "  " }; \
> +        (ctx)->g = yajl_gen_alloc(&conf, NULL); \
> +    }
> +#  define DEBUG_GEN_FREE(ctx) \
> +    if ((ctx)->g) yajl_gen_free((ctx)->g)
> +#  define DEBUG_GEN(ctx, type)              yajl_gen_##type(ctx->g)
> +#  define DEBUG_GEN_VALUE(ctx, type, value) yajl_gen_##type(ctx->g, value)
> +#  define DEBUG_GEN_STRING(ctx, str, n)     yajl_gen_string(ctx->g, str, n)
> +#  define DEBUG_GEN_REPORT(yajl_ctx) \
> +    do { \
> +        const unsigned char *buf = NULL; \
> +        unsigned int len = 0; \
> +        yajl_gen_get_buf((yajl_ctx)->g, &buf, &len); \
> +        LIBXL__LOG(libxl__gc_owner((yajl_ctx)->gc), \
> +                   LIBXL__LOG_DEBUG, "response:\n%s", buf); \
> +        yajl_gen_free((yajl_ctx)->g); \
> +        (yajl_ctx)->g = NULL; \
> +    } while (0)
> +#else
> +#  define DEBUG_GEN_ALLOC(ctx)                  ((void)0)
> +#  define DEBUG_GEN_FREE(ctx)                   ((void)0)
> +#  define DEBUG_GEN(ctx, type)                  ((void)0)
> +#  define DEBUG_GEN_VALUE(ctx, type, value)     ((void)0)
> +#  define DEBUG_GEN_STRING(ctx, value, lenght)  ((void)0)
> +#  define DEBUG_GEN_REPORT(ctx)                 ((void)0)
> +#endif
> +
> +/*
> + * YAJL Helper
> + */
> +
> +yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str)
> +{
> +    return yajl_gen_string(hand, (const unsigned char *)str, strlen(str));
> +}
> +
> +
> +/*
> + * libxl__json_object helper functions
> + */
> +
> +static libxl__json_object *json_object_alloc(libxl__gc *gc,
> +                                             libxl__json_node_type type)
> +{
> +    libxl__json_object *obj;
> +
> +    obj = calloc(1, sizeof (libxl__json_object));
> +    if (obj == NULL) {
> +        LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
> +                         "Failed to allocate a libxl__json_object");
> +        return NULL;
> +    }
> +
> +    obj->type = type;
> +
> +    if (type == JSON_MAP || type == JSON_ARRAY) {
> +        flexarray_t *array = flexarray_make(1, 1);
> +        if (array == NULL) {
> +            LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
> +                             "Failed to allocate a flexarray");
> +            free(obj);
> +            return NULL;
> +        }
> +        if (type == JSON_MAP)
> +            obj->u.map = array;
> +        else
> +            obj->u.array = array;
> +    }
> +
> +    return obj;
> +}
> +
> +static int json_object_append_to(libxl__gc *gc,
> +                                 libxl__json_object *obj,
> +                                 libxl__json_object *dst)
> +{
> +    assert(dst != NULL);
> +
> +    switch (dst->type) {
> +    case JSON_MAP: {
> +        libxl__json_map_node *last;
> +
> +        if (dst->u.map->count == 0) {
> +            LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
> +                       "Try to add a value to an empty map (with no key)");
> +            return -1;
> +        }
> +        flexarray_get(dst->u.map, dst->u.map->count - 1, (void**)&last);
> +        last->obj = obj;
> +        break;
> +    }
> +    case JSON_ARRAY:
> +        if (flexarray_append(dst->u.array, obj) == 2) {
> +            LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
> +                             "Failed to grow a flexarray");
> +            return -1;
> +        }
> +        break;
> +    default:
> +        LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
> +                   "Try append an object is not a map/array (%i)\n",
> +                   dst->type);
> +        return -1;
> +    }
> +
> +    obj->parent = dst;
> +    return 0;
> +}
> +
> +void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj)
> +{
> +    int index = 0;
> +
> +    if (obj == NULL)
> +        return;
> +    switch (obj->type) {
> +    case JSON_STRING:
> +        free(obj->u.string);
> +        break;
> +    case JSON_MAP: {
> +        libxl__json_map_node *node = NULL;
> +
> +        for (index = 0; index < obj->u.map->count; index++) {
> +            if (flexarray_get(obj->u.map, index, (void**)&node) != 0)
> +                break;
> +            libxl__json_object_free(gc, node->obj);
> +            free(node->map_key);
> +            free(node);
> +            node = NULL;
> +        }
> +        flexarray_free(obj->u.map);
> +        break;
> +    }
> +    case JSON_ARRAY: {
> +        libxl__json_object *node = NULL;
> +        break;
> +
> +        for (index = 0; index < obj->u.array->count; index++) {
> +            if (flexarray_get(obj->u.array, index, (void**)&node) != 0)
> +                break;
> +            libxl__json_object_free(gc, node);
> +            node = NULL;
> +        }
> +        flexarray_free(obj->u.array);
> +        break;
> +    }
> +    default:
> +        break;
> +    }
> +    free(obj);
> +}
> +
> +libxl__json_object *libxl__json_array_get(const libxl__json_object *o, int i)
> +{
> +    flexarray_t *array = NULL;
> +    libxl__json_object *obj = NULL;
> +
> +    if ((array = libxl__json_object_get_array(o)) == NULL) {
> +        return NULL;
> +    }
> +
> +    if (i >= array->count)
> +        return NULL;
> +
> +    if (flexarray_get(array, i, (void**)&obj) != 0)
> +        return NULL;
> +
> +    return obj;
> +}
> +
> +libxl__json_map_node *libxl__json_map_node_get(const libxl__json_object *o,
> +                                               int i)
> +{
> +    flexarray_t *array = NULL;
> +    libxl__json_map_node *obj = NULL;
> +
> +    if ((array = libxl__json_object_get_map(o)) == NULL) {
> +        return NULL;
> +    }
> +
> +    if (i >= array->count)
> +        return NULL;
> +
> +    if (flexarray_get(array, i, (void**)&obj) != 0)
> +        return NULL;
> +
> +    return obj;
> +}
> +
> +const libxl__json_object *libxl__json_map_get(const char *key,
> +                                          const libxl__json_object *o,
> +                                          libxl__json_node_type 
> expected_type)
> +{
> +    flexarray_t *maps = NULL;
> +    int index = 0;
> +
> +    if (libxl__json_object_is_map(o)) {
> +        libxl__json_map_node *node = NULL;
> +
> +        maps = o->u.map;
> +        for (index = 0; index < maps->count; index++) {
> +            if (flexarray_get(maps, index, (void**)&node) != 0)
> +                return NULL;
> +            if (strcmp(key, node->map_key) == 0) {
> +                if (expected_type == JSON_ANY
> +                    || (node->obj && node->obj->type == expected_type)) {
> +                    return node->obj;
> +                } else {
> +                    return NULL;
> +                }
> +            }
> +        }
> +    }
> +    return NULL;
> +}
> +
> +
> +/*
> + * JSON callbacks
> + */
> +
> +static int json_callback_null(void *opaque)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    libxl__json_object *obj;
> +
> +    DEBUG_GEN(ctx, null);
> +
> +    if ((obj = json_object_alloc(ctx->gc, JSON_NULL)) == NULL)
> +        return 0;
> +
> +    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
> +        libxl__json_object_free(ctx->gc, obj);
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_boolean(void *opaque, int boolean)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    libxl__json_object *obj;
> +
> +    DEBUG_GEN_VALUE(ctx, bool, boolean);
> +
> +    if ((obj = json_object_alloc(ctx->gc,
> +                                 boolean ? JSON_TRUE : JSON_FALSE)) == NULL)
> +        return 0;
> +
> +    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
> +        libxl__json_object_free(ctx->gc, obj);
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_integer(void *opaque, long value)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    libxl__json_object *obj;
> +
> +    DEBUG_GEN_VALUE(ctx, integer, value);
> +
> +    if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
> +        return 0;
> +    obj->u.i = value;
> +
> +    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
> +        libxl__json_object_free(ctx->gc, obj);
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_double(void *opaque, double value)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    libxl__json_object *obj;
> +
> +    DEBUG_GEN_VALUE(ctx, double, value);
> +
> +    if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL)
> +        return 0;
> +    obj->u.d = value;
> +
> +    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
> +        libxl__json_object_free(ctx->gc, obj);
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_string(void *opaque, const unsigned char *str,
> +                                unsigned int len)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    char *t = NULL;
> +    libxl__json_object *obj = NULL;
> +
> +    t = malloc(len + 1);
> +    if (t == NULL) {
> +        LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
> +                         "Failed to allocate");
> +        return 0;
> +    }
> +
> +    DEBUG_GEN_STRING(ctx, str, len);
> +
> +    strncpy(t, (const char *) str, len);
> +    t[len] = 0;
> +
> +    if ((obj = json_object_alloc(ctx->gc, JSON_STRING)) == NULL) {
> +        free(t);
> +        return 0;
> +    }
> +    obj->u.string = t;
> +
> +    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
> +        libxl__json_object_free(ctx->gc, obj);
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_map_key(void *opaque, const unsigned char *str,
> +                                 unsigned int len)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    char *t = NULL;
> +    libxl__json_object *obj = ctx->current;
> +
> +    t = malloc(len + 1);
> +    if (t == NULL) {
> +        LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
> +                         "Failed to allocate");
> +        return 0;
> +    }
> +
> +    DEBUG_GEN_STRING(ctx, str, len);
> +
> +    strncpy(t, (const char *) str, len);
> +    t[len] = 0;
> +
> +    if (libxl__json_object_is_map(obj)) {
> +        libxl__json_map_node *node = malloc(sizeof (libxl__json_map_node));
> +        if (node == NULL) {
> +            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
> +                             "Failed to allocate");
> +            return 0;
> +        }
> +
> +        node->map_key = t;
> +        node->obj = NULL;
> +
> +        if (flexarray_append(obj->u.map, node) == 2) {
> +            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
> +                             "Failed to grow a flexarray");
> +            return 0;
> +        }
> +    } else {
> +        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
> +                   "Current json object is not a map");
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_start_map(void *opaque)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    libxl__json_object *obj = NULL;
> +
> +    DEBUG_GEN(ctx, map_open);
> +
> +    if ((obj = json_object_alloc(ctx->gc, JSON_MAP)) == NULL)
> +        return 0;
> +
> +    if (ctx->current) {
> +        if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
> +            libxl__json_object_free(ctx->gc, obj);
> +            return 0;
> +        }
> +    }
> +
> +    ctx->current = obj;
> +    if (ctx->head == NULL) {
> +        ctx->head = obj;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_end_map(void *opaque)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +
> +    DEBUG_GEN(ctx, map_close);
> +
> +    if (ctx->current) {
> +        ctx->current = ctx->current->parent;
> +    } else {
> +        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
> +                   "No current libxl__json_object, cannot use his parent.");
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_start_array(void *opaque)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +    libxl__json_object *obj = NULL;
> +
> +    DEBUG_GEN(ctx, array_open);
> +
> +    if ((obj = json_object_alloc(ctx->gc, JSON_ARRAY)) == NULL)
> +        return 0;
> +
> +    if (ctx->current) {
> +        if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
> +            libxl__json_object_free(ctx->gc, obj);
> +            return 0;
> +        }
> +    }
> +
> +    ctx->current = obj;
> +    if (ctx->head == NULL) {
> +        ctx->head = obj;
> +    }
> +
> +    return 1;
> +}
> +
> +static int json_callback_end_array(void *opaque)
> +{
> +    libxl__yajl_ctx *ctx = opaque;
> +
> +    DEBUG_GEN(ctx, array_close);
> +
> +    if (ctx->current) {
> +        ctx->current = ctx->current->parent;
> +    } else {
> +        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
> +                   "No current libxl__json_object, cannot use his parent.");
> +        return 0;
> +    }
> +
> +    return 1;
> +}
> +
> +static yajl_callbacks callbacks = {
> +    json_callback_null,
> +    json_callback_boolean,
> +    json_callback_integer,
> +    json_callback_double,
> +    NULL,
> +    json_callback_string,
> +    json_callback_start_map,
> +    json_callback_map_key,
> +    json_callback_end_map,
> +    json_callback_start_array,
> +    json_callback_end_array
> +};
> +
> +static void yajl_ctx_free(libxl__yajl_ctx *yajl_ctx)
> +{
> +    if (yajl_ctx->hand) {
> +        yajl_free(yajl_ctx->hand);
> +        yajl_ctx->hand = NULL;
> +    }
> +    DEBUG_GEN_FREE(yajl_ctx);
> +}
> +
> +libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s)
> +{
> +    yajl_status status;
> +    libxl__yajl_ctx yajl_ctx;
> +
> +    memset(&yajl_ctx, 0, sizeof (yajl_ctx));
> +    yajl_ctx.gc = gc;
> +
> +    DEBUG_GEN_ALLOC(&yajl_ctx);
> +
> +    if (yajl_ctx.hand == NULL) {
> +        yajl_parser_config cfg = {
> +            .allowComments = 1,
> +            .checkUTF8 = 1,
> +        };
> +        yajl_ctx.hand = yajl_alloc(&callbacks, &cfg, NULL, &yajl_ctx);
> +    }
> +    status = yajl_parse(yajl_ctx.hand, (const unsigned char *)s, strlen(s));
> +    status = yajl_parse_complete(yajl_ctx.hand);
> +
> +    if (status == yajl_status_ok) {
> +        libxl__json_object *o = yajl_ctx.head;
> +
> +        DEBUG_GEN_REPORT(&yajl_ctx);
> +
> +        yajl_ctx.head = NULL;
> +
> +        yajl_ctx_free(&yajl_ctx);
> +        return o;
> +    } else {
> +        unsigned char *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);
> +
> +        libxl__json_object_free(gc, yajl_ctx.head);
> +        yajl_ctx_free(&yajl_ctx);
> +        return NULL;
> +    }
> +}
> --
> Anthony PERARD
> 



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.