[libvirt] [PATCH 04/12] util: json: Add functions to convert JSON arrays from/to virBitmaps

Michal Privoznik mprivozn at redhat.com
Thu Jan 29 13:11:23 UTC 2015


On 28.01.2015 11:30, Peter Krempa wrote:
> To be able to easily represent nodesets and other data stored in
> virBitmaps in libvirt, this patch introduces a set of helpers that allow
> to convert the bitmap to and from JSON value objects.
> ---
>  src/libvirt_private.syms |   2 +
>  src/util/virjson.c       | 113 +++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virjson.h       |   4 ++
>  3 files changed, 119 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index cc74e35..70c81a8 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1514,6 +1514,7 @@ virJSONValueArrayGet;
>  virJSONValueArraySize;
>  virJSONValueFree;
>  virJSONValueFromString;
> +virJSONValueGetArrayAsBitmap;
>  virJSONValueGetBoolean;
>  virJSONValueGetNumberDouble;
>  virJSONValueGetNumberInt;
> @@ -1523,6 +1524,7 @@ virJSONValueGetNumberUlong;
>  virJSONValueGetString;
>  virJSONValueIsNull;
>  virJSONValueNewArray;
> +virJSONValueNewArrayFromBitmap;
>  virJSONValueNewBoolean;
>  virJSONValueNewNull;
>  virJSONValueNewNumberDouble;
> diff --git a/src/util/virjson.c b/src/util/virjson.c
> index 9eb1bff..3e00650 100644
> --- a/src/util/virjson.c
> +++ b/src/util/virjson.c
> @@ -99,6 +99,8 @@ struct _virJSONParser {
>   *
>   * a: json object, must be non-NULL
>   * A: json object, omitted if NULL
> + * m: a bitmap represented as a JSON array, must be non-NULL
> + * M: a bitmap represented as a JSON array, omitted if NULL
>   *
>   * The value corresponds to the selected type.
>   *
> @@ -242,6 +244,28 @@ virJSONValueObjectAddVArgs(virJSONValuePtr obj,
>              rc = virJSONValueObjectAppend(obj, key, val);
>          }   break;
> 
> +        case 'M':
> +        case 'm': {
> +            virBitmapPtr map = va_arg(args, virBitmapPtr);
> +            virJSONValuePtr jsonMap;
> +
> +            if (!map) {
> +                if (type == 'M')
> +                    continue;
> +
> +                virReportError(VIR_ERR_INTERNAL_ERROR,
> +                               _("argument key '%s' must not have null value"),
> +                               key);
> +                goto cleanup;
> +            }
> +
> +            if (!(jsonMap = virJSONValueNewArrayFromBitmap(map)))
> +                goto cleanup;
> +
> +            if ((rc = virJSONValueObjectAppend(obj, key, jsonMap)) < 0)
> +                virJSONValueFree(jsonMap);
> +        } break;
> +
>          default:
>              virReportError(VIR_ERR_INTERNAL_ERROR,
>                             _("unsupported data type '%c' for arg '%s'"), type, key - 2);
> @@ -941,6 +965,95 @@ virJSONValueGetBoolean(virJSONValuePtr val,
>  }
> 
> 
> +/**
> + * virJSONValueGetArrayAsBitmap:
> + * @val: JSON array to convert to bitmap
> + * @bitmap: New bitmap is allocated filled and returned via this argument
> + *
> + * Attempts a conversion of a JSON array to a bitmap. The members of the array
> + * must be non-negative integers for the conversion to succeed. This function
> + * does not report libvirt errors (except for out-of-memory) so that it can be
> + * used to probe that the array can be represented as a bitmap.
> + *
> + * Returns 0 on success and fills @bitmap; -1 on error and  @bitmap is set to
> + * NULL.
> + */
> +int
> +virJSONValueGetArrayAsBitmap(const virJSONValue *val,
> +                             virBitmapPtr *bitmap)
> +{
> +    int ret = -1;
> +    virJSONValuePtr elem;
> +    size_t i;
> +    unsigned long long *elems = NULL;
> +    unsigned long long maxelem = 0;
> +
> +    *bitmap = NULL;
> +
> +    if (val->type != VIR_JSON_TYPE_ARRAY)
> +        return -1;
> +
> +    if (VIR_ALLOC_N(elems, val->data.array.nvalues) < 0)
> +        return -1;

This reports an error in case of failure ...

> +
> +    /* first pass converts array members to numbers and finds the maximum */
> +    for (i = 0; i < val->data.array.nvalues; i++) {
> +        elem = val->data.array.values[i];
> +
> +        if (elem->type != VIR_JSON_TYPE_NUMBER ||

while this does not. I'd rather make this report an error on all failures.

> +            virStrToLong_ullp(elem->data.number, NULL, 10, &elems[i]) < 0)
> +            goto cleanup;
> +
> +        if (elems[i] > maxelem)
> +            maxelem = elems[i];
> +    }
> +
> +    if (!(*bitmap = virBitmapNew(maxelem + 1)))
> +        goto cleanup;
> +
> +    /* second pass sets the correct bits in the map */
> +    for (i = 0; i < val->data.array.nvalues; i++)
> +        ignore_value(virBitmapSetBit(*bitmap, elems[i]));
> +
> +    ret = 0;
> +
> + cleanup:
> +    VIR_FREE(elems);
> +
> +    return ret;
> +}

Michal




More information about the libvir-list mailing list