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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list