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