
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