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

Re: [Xen-devel] [PATCH V3 08/13] libxl_json: introduce parser functions for builtin types



On Wed, Apr 23, 2014 at 05:59:18PM +0100, Wei Liu wrote:
> This changeset introduces following functions:
>  * libxl_defbool_parse_json
>  * libxl__bool_parse_json
>  * libxl_uuid_parse_json
>  * libxl_mac_parse_json
>  * libxl_bitmap_parse_json
>  * libxl_cpuid_policy_list_parse_json
>  * libxl_string_list_parse_json
>  * libxl_key_value_list_parse_json
>  * libxl_hwcap_parse_json
>  * libxl__int_parse_json
>  * libxl__uint{8,16,32,64}_parse_json
>  * libxl__string_parse_json
> 
> They will be used in later patch to convert the libxl__json_object
> tree of a builtin type to libxl_FOO struct.
> 
> Also remove delcaration of libxl_domid_gen_json as libxl_domid uses
> yajl_gen_integer to generate JSON object.
> 
> Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
> ---
>  tools/libxl/libxl_cpuid.c   |   92 +++++++++++++---
>  tools/libxl/libxl_json.c    |  245 
> +++++++++++++++++++++++++++++++++++++++++++
>  tools/libxl/libxl_json.h    |   36 ++++++-
>  tools/libxl/libxl_nocpuid.c |    7 ++
>  4 files changed, 363 insertions(+), 17 deletions(-)
> 
> diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
> index 8a59c4d..895f5fd 100644
> --- a/tools/libxl/libxl_cpuid.c
> +++ b/tools/libxl/libxl_cpuid.c
> @@ -337,29 +337,29 @@ void libxl_cpuid_set(libxl_ctx *ctx, uint32_t domid,
>                       (const char**)(cpuid[i].policy), cpuid_res);
>  }
>  
> +static const char *input_names[2] = { "leaf", "subleaf" };
> +static const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" };
> +/*
> + * Aiming for:
> + * [
> + *     { 'leaf':    'val-eax',
> + *       'subleaf': 'val-ecx',
> + *       'eax':     'filter',
> + *       'ebx':     'filter',
> + *       'ecx':     'filter',
> + *       'edx':     'filter' },
> + *     { 'leaf':    'val-eax', ..., 'eax': 'filter', ... },
> + *     ... etc ...
> + * ]
> + */
> +
>  yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
>                                  libxl_cpuid_policy_list *pcpuid)
>  {
>      libxl_cpuid_policy_list cpuid = *pcpuid;
>      yajl_gen_status s;
> -    const char *input_names[2] = { "leaf", "subleaf" };
> -    const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" };
>      int i, j;
>  
> -    /*
> -     * Aiming for:
> -     * [
> -     *     { 'leaf':    'val-eax',
> -     *       'subleaf': 'val-ecx',
> -     *       'eax':     'filter',
> -     *       'ebx':     'filter',
> -     *       'ecx':     'filter',
> -     *       'edx':     'filter' },
> -     *     { 'leaf':    'val-eax', ..., 'eax': 'filter', ... },
> -     *     ... etc ...
> -     * ]
> -     */
> -
>      s = yajl_gen_array_open(hand);
>      if (s != yajl_gen_status_ok) goto out;
>  
> @@ -397,6 +397,66 @@ out:
>      return s;
>  }
>  
> +int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
> +                                       const libxl__json_object *o,
> +                                       libxl_cpuid_policy_list *p)
> +{
> +    int i, size;
> +    libxl_cpuid_policy_list l;
> +
> +    if (!libxl__json_object_is_array(o))
> +        return ERROR_FAIL;
> +
> +    if (!o->u.array->count)
> +        return 0;

There is a function called libxl__json_object_get_array which return a
flexarray_t. It might be better to use it than accessing it through
o->u.array.

> +
> +    size = o->u.array->count;
> +    /* need one extra slot as sentinel */
> +    l = *p = calloc(size + 1, sizeof(libxl_cpuid_policy));
> +
> +    if (!l)
> +        return ERROR_NOMEM;
> +
> +    l[size].input[0] = XEN_CPUID_INPUT_UNUSED;
> +    l[size].input[1] = XEN_CPUID_INPUT_UNUSED;
> +
> +    for (i = 0; i < size; i++) {
> +        const libxl__json_object *t;
> +        int j;
> +
> +        if (flexarray_get(o->u.array, i, (void**)&t) != 0)
> +            return ERROR_FAIL;
> +
> +        if (!libxl__json_object_is_map(t))
> +            return ERROR_FAIL;
> +
> +        for (j = 0; j < ARRAY_SIZE(l[0].input); j++) {
> +            const libxl__json_object *r;
> +
> +            r = libxl__json_map_get(input_names[j], t, JSON_INTEGER);
> +            if (!r)
> +                l[i].input[j] = XEN_CPUID_INPUT_UNUSED;
> +            else
> +                l[i].input[j] = r->u.i;

What about libxl__json_object_get_integer here? Same thing about
different types through the patch.

> +        }
> +
> +        for (j = 0; j < ARRAY_SIZE(l[0].policy); j++) {
> +            const libxl__json_object *r;
> +
> +            r = libxl__json_map_get(policy_names[j], t, JSON_STRING);
> +            if (!r) {
> +                l[i].policy[j] = NULL;
> +            } else {
> +                l[i].policy[j] = strdup(r->u.string);

libxl__json_object_get_string?

> +                if (!l[i].policy[j])
> +                    return ERROR_NOMEM;
> +            }
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
> index 27cce9c..3e7eb95 100644
> --- a/tools/libxl/libxl_json.c
> +++ b/tools/libxl/libxl_json.c
> @@ -100,6 +100,38 @@ yajl_gen_status libxl_defbool_gen_json(yajl_gen hand,
>      return libxl__yajl_gen_asciiz(hand, libxl_defbool_to_string(*db));
>  }
>  
> +int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             libxl_defbool *p)
> +{
> +    if (!libxl__json_object_is_string(o))
> +        return ERROR_FAIL;
> +
> +    if (!strncmp(o->u.string, LIBXL__DEFBOOL_STR_DEFAULT,
> +                 strlen(LIBXL__DEFBOOL_STR_DEFAULT)))
> +        p->val = LIBXL__DEFBOOL_DEFAULT;
> +    else if (!strncmp(o->u.string, LIBXL__DEFBOOL_STR_TRUE,
> +                      strlen(LIBXL__DEFBOOL_STR_TRUE)))
> +        p->val = LIBXL__DEFBOOL_TRUE;
> +    else if (!strncmp(o->u.string, LIBXL__DEFBOOL_STR_FALSE,
> +                      strlen(LIBXL__DEFBOOL_STR_FALSE)))
> +        p->val = LIBXL__DEFBOOL_FALSE;
> +    else
> +        return ERROR_FAIL;
> +
> +    return 0;
> +}
> +
> +int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                           bool *p)
> +{
> +    if (!libxl__json_object_is_bool(o))
> +        return ERROR_FAIL;
> +
> +    *p = o->u.b;

libxl__json_object_get_bool?

> +
> +    return 0;
> +}
> +
>  yajl_gen_status libxl_uuid_gen_json(yajl_gen hand,
>                                      libxl_uuid *uuid)
>  {
> @@ -108,6 +140,15 @@ yajl_gen_status libxl_uuid_gen_json(yajl_gen hand,
>      return yajl_gen_string(hand, (const unsigned char *)buf, 
> LIBXL_UUID_FMTLEN);
>  }
>  
> +int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                          libxl_uuid *p)
> +{
> +    if (!libxl__json_object_is_string(o))
> +        return ERROR_FAIL;
> +
> +    return libxl_uuid_from_string(p, o->u.string);
> +}
> +
>  yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand,
>                                        libxl_bitmap *bitmap)
>  {
> @@ -128,6 +169,36 @@ out:
>      return s;
>  }
>  
> +int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                            libxl_bitmap *p)
> +{
> +    int i;
> +    int size;
> +    const libxl__json_object *t;
> +
> +    if (!libxl__json_object_is_array(o))
> +        return ERROR_FAIL;
> +
> +    if (!o->u.array->count) {
> +        libxl_bitmap_init(p);
> +        return 0;
> +    }
> +
> +    t = libxl__json_array_get(o, o->u.array->count - 1);
> +    size = t->u.i + 1;

t is not an integer, yet. You should check first with
libxl__json_object_is_integer and get the value with
libxl__json_object_get_integer.

> +
> +    libxl_bitmap_alloc(CTX, p, size);
> +
> +    for (i = 0; (t = libxl__json_array_get(o, i)); i++) {
> +        if (!libxl__json_object_is_integer(t))
> +            return ERROR_FAIL;
> +
> +        libxl_bitmap_set(p, t->u.i);
> +    }
> +
> +    return 0;
> +}
> +
>  yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand,
>                                                libxl_key_value_list *pkvl)
>  {
> @@ -155,6 +226,47 @@ out:
>      return s;
>  }
>  
> +int libxl_key_value_list_parse_json(libxl__gc *gc, const libxl__json_object 
> *o,
> +                                    libxl_key_value_list *p)
> +{
> +    libxl__json_map_node *node = NULL;
> +    flexarray_t *maps = NULL;
> +    int i, size;
> +    libxl_key_value_list kvl;
> +
> +    if (!libxl__json_object_is_map(o))
> +        return ERROR_FAIL;
> +
> +    maps = o->u.map;

libxl__json_object_get_map?

> +    size = maps->count * 2;
> +    kvl = *p = calloc(size, sizeof(char *));
> +    if (!kvl)
> +        return ERROR_NOMEM;
> +
> +    for (i = 0; i < maps->count; i++) {
> +        int idx = i * 2;
> +        if (flexarray_get(maps, i, (void**)&node) != 0)
> +            return ERROR_FAIL;
> +
> +        if (!libxl__json_object_is_string(node->obj) &&
> +            !libxl__json_object_is_null(node->obj))
> +            return ERROR_FAIL;
> +
> +        kvl[idx]   = strdup(node->map_key);
> +        if (!kvl[idx])
> +            return ERROR_NOMEM;
> +        if (libxl__json_object_is_string(node->obj)) {
> +            kvl[idx+1] = strdup(node->obj->u.string);
> +            if (!kvl[idx+1])
> +                return ERROR_NOMEM;
> +        } else {
> +            kvl[idx+1] = NULL;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list 
> *pl)
>  {
>      libxl_string_list l = *pl;
> @@ -176,6 +288,37 @@ out:
>      return s;
>  }
>  
> +int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                                 libxl_string_list *p)
> +{
> +    const libxl__json_object *t;
> +    libxl_string_list l;
> +    flexarray_t *array = NULL;
> +    int i, size;
> +
> +    if (!libxl__json_object_is_array(o))
> +        return ERROR_FAIL;
> +
> +    array = o->u.array;
> +    size = array->count;
> +    /* need one extra slot as sentinel */
> +    l = *p = calloc((size + 1), sizeof(char *));
> +
> +    if (!l)
> +        return ERROR_NOMEM;
> +
> +    for (i = 0; (t = libxl__json_array_get(o, i)); i++) {
> +        if (!libxl__json_object_is_string(t))
> +            return ERROR_FAIL;
> +
> +        l[i] = strdup(t->u.string);
> +        if (!l[i])
> +            return ERROR_NOMEM;
> +    }
> +
> +    return 0;
> +}
> +
>  yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *mac)
>  {
>      char buf[LIBXL_MAC_FMTLEN+1];
> @@ -183,6 +326,15 @@ yajl_gen_status libxl_mac_gen_json(yajl_gen hand, 
> libxl_mac *mac)
>      return yajl_gen_string(hand, (const unsigned char *)buf, 
> LIBXL_MAC_FMTLEN);
>  }
>  
> +int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                         libxl_mac *p)
> +{
> +    if (!libxl__json_object_is_string(o))
> +        return ERROR_FAIL;
> +
> +    return libxl__parse_mac(o->u.string, *p);
> +}
> +
>  yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand,
>                                       libxl_hwcap *p)
>  {
> @@ -201,6 +353,27 @@ out:
>      return s;
>  }
>  
> +int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                           libxl_hwcap *p)
> +{
> +    int i;
> +
> +    if (!libxl__json_object_is_array(o))
> +        return ERROR_FAIL;
> +
> +    for (i = 0; i<4; i++) {
> +        const libxl__json_object *t;
> +
> +        t = libxl__json_array_get(o, i);
> +        if (!t || !libxl__json_object_is_integer(t))
> +            return ERROR_FAIL;
> +
> +        (*p)[i] = t->u.i;
> +    }
> +
> +    return 0;
> +}
> +
>  yajl_gen_status libxl__string_gen_json(yajl_gen hand,
>                                         const char *p)
>  {
> @@ -210,6 +383,23 @@ yajl_gen_status libxl__string_gen_json(yajl_gen hand,
>          return yajl_gen_null(hand);
>  }
>  
> +int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             char **p)
> +{
> +    if (!libxl__json_object_is_string(o) && !libxl__json_object_is_null(o))
> +        return ERROR_FAIL;
> +
> +    if (libxl__json_object_is_null(o)) {
> +        *p = NULL;
> +    } else {
> +        *p = strdup(o->u.string);
> +        if (!*p)
> +            return ERROR_NOMEM;
> +    }
> +
> +    return 0;
> +}
> +
>  /*
>   * libxl__json_object helper functions
>   */
> @@ -824,6 +1014,61 @@ out:
>      return rc;
>  }
>  
> +int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                          void *p)
> +{
> +    if (!libxl__json_object_is_integer(o))
> +        return ERROR_FAIL;
> +
> +    *((int *)p) = o->u.i;
> +
> +    return 0;
> +}
> +
> +int libxl__uint8_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                            void *p)
> +{
> +    if (!libxl__json_object_is_integer(o))
> +        return ERROR_FAIL;
> +
> +    *((uint8_t *)p) = o->u.i;

Maybe we should check the value of the int. If it those not fit in
uint8, then there is an error in the json input. Same thing for the
other functions below.

> +
> +    return 0;
> +}
> +
> +int libxl__uint16_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             void *p)
> +{
> +    if (!libxl__json_object_is_integer(o))
> +        return ERROR_FAIL;
> +
> +    *((uint16_t *)p) = o->u.i;
> +
> +    return 0;
> +}
> +
> +int libxl__uint32_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             void *p)
> +{
> +    if (!libxl__json_object_is_integer(o))
> +        return ERROR_FAIL;
> +
> +    *((uint32_t *)p) = o->u.i;
> +
> +    return 0;
> +}
> +
> +int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             void *p)
> +{
> +    if (!libxl__json_object_is_integer(o))
> +        return ERROR_FAIL;
> +
> +    *((uint64_t *)p) = o->u.i;
> +
> +    return 0;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/tools/libxl/libxl_json.h b/tools/libxl/libxl_json.h
> index a4dd8fc..924b2aa 100644
> --- a/tools/libxl/libxl_json.h
> +++ b/tools/libxl/libxl_json.h
> @@ -22,17 +22,51 @@
>  #  include <yajl/yajl_version.h>
>  #endif
>  
> +typedef struct libxl__gc libxl__gc;
> +typedef struct libxl__json_object libxl__json_object;
> +
>  yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p);
> -yajl_gen_status libxl_domid_gen_json(yajl_gen hand, libxl_domid *p);
> +int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             libxl_defbool *p);
> +int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                           bool *p);
>  yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, libxl_uuid *p);
> +int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                          libxl_uuid *p);
>  yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *p);
> +int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                         libxl_mac *p);
>  yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand, libxl_bitmap *p);
> +int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                            libxl_bitmap *p);
>  yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
>                                                   libxl_cpuid_policy_list *p);
> +int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
> +                                       const libxl__json_object *o,
> +                                       libxl_cpuid_policy_list *p);
>  yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list 
> *p);
> +int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                                 libxl_string_list *p);
>  yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand,
>                                                libxl_key_value_list *p);
> +int libxl_key_value_list_parse_json(libxl__gc *gc,
> +                                    const libxl__json_object *o,
> +                                    libxl_key_value_list *p);
>  yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand, libxl_hwcap *p);
> +int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                           libxl_hwcap *p);
> +int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                          void *p);
> +int libxl__uint8_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                            void *p);
> +int libxl__uint16_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             void *p);
> +int libxl__uint32_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             void *p);
> +int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             void *p);
> +int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
> +                             char **p);
>  
>  #include <_libxl_types_json.h>
>  
> diff --git a/tools/libxl/libxl_nocpuid.c b/tools/libxl/libxl_nocpuid.c
> index 5f7cb6a..eb525fc 100644
> --- a/tools/libxl/libxl_nocpuid.c
> +++ b/tools/libxl/libxl_nocpuid.c
> @@ -44,6 +44,13 @@ yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen 
> hand,
>      return 0;
>  }
>  
> +int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
> +                                       const libxl__json_object *o,
> +                                       libxl_cpuid_policy_list *p)
> +{
> +    return 0;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C

Regards,

-- 
Anthony PERARD

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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