All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony PERARD <anthony.perard@citrix.com>
To: Wei Liu <wei.liu2@citrix.com>
Cc: ian.jackson@eu.citrix.com, ian.campbell@citrix.com,
	xen-devel@lists.xen.org
Subject: Re: [PATCH V3 08/13] libxl_json: introduce parser functions for builtin types
Date: Thu, 1 May 2014 15:28:42 +0100	[thread overview]
Message-ID: <20140501142841.GA3530@perard.uk.xensource.com> (raw)
In-Reply-To: <1398272363-12133-9-git-send-email-wei.liu2@citrix.com>

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@citrix.com>
> ---
>  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

  reply	other threads:[~2014-05-01 14:28 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-23 16:59 [PATCH V3 00/13] JSON infrastructure and new "xl-json" format Wei Liu
2014-04-23 16:59 ` [PATCH V3 01/13] libxl: fix memory leak in libxl_cpuid_dispose Wei Liu
2014-04-23 16:59 ` [PATCH V3 02/13] libxl.h: document the paradigm of using libxl types Wei Liu
2014-04-23 16:59 ` [PATCH V3 03/13] libxl.h: move / add some libxl defbool #define here Wei Liu
2014-04-23 16:59 ` [PATCH V3 04/13] libxl IDL: rename json_fn to json_gen_fn Wei Liu
2014-04-23 16:59 ` [PATCH V3 05/13] libxl_json: introduce libx__object_from_json Wei Liu
2014-04-23 16:59 ` [PATCH V3 06/13] libxl_internal: make JSON_* types a bit-field Wei Liu
2014-04-23 16:59 ` [PATCH V3 07/13] libxl_internal: introduce libxl__json_object_is_{null, number, double} Wei Liu
2014-04-23 16:59 ` [PATCH V3 08/13] libxl_json: introduce parser functions for builtin types Wei Liu
2014-05-01 14:28   ` Anthony PERARD [this message]
2014-05-01 14:38     ` Wei Liu
2014-04-23 16:59 ` [PATCH V3 09/13] libxl_json: allow basic JSON type objects generation Wei Liu
2014-04-23 16:59 ` [PATCH V3 10/13] libxl/gentypes.py: include discriminator in JSON output Wei Liu
2014-04-23 22:40   ` Andrew Cooper
2014-04-24  8:12     ` Wei Liu
2014-04-23 16:59 ` [PATCH V3 11/13] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
2014-04-23 16:59 ` [PATCH V3 12/13] libxl/gentest.py: test JSON parser Wei Liu
2014-04-23 16:59 ` [PATCH V3 13/13] xl: introduce "xl-json" format Wei Liu
2014-04-24 16:11   ` Ian Jackson
2014-04-25 15:53     ` Wei Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140501142841.GA3530@perard.uk.xensource.com \
    --to=anthony.perard@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.