提交 58f61d24 编写于 作者: P Peter Krempa

util: json: Add functions to convert JSON arrays from/to virBitmaps

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.
上级 bc2d8e5b
......@@ -1516,6 +1516,7 @@ virJSONValueArrayGet;
virJSONValueArraySize;
virJSONValueFree;
virJSONValueFromString;
virJSONValueGetArrayAsBitmap;
virJSONValueGetBoolean;
virJSONValueGetNumberDouble;
virJSONValueGetNumberInt;
......@@ -1525,6 +1526,7 @@ virJSONValueGetNumberUlong;
virJSONValueGetString;
virJSONValueIsNull;
virJSONValueNewArray;
virJSONValueNewArrayFromBitmap;
virJSONValueNewBoolean;
virJSONValueNewNull;
virJSONValueNewNumberDouble;
......
......@@ -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);
......@@ -943,6 +967,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 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_QUIET(elems, val->data.array.nvalues) < 0)
return -1;
/* 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 ||
virStrToLong_ullp(elem->data.number, NULL, 10, &elems[i]) < 0)
goto cleanup;
if (elems[i] > maxelem)
maxelem = elems[i];
}
if (!(*bitmap = virBitmapNewQuiet(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;
}
virJSONValuePtr
virJSONValueNewArrayFromBitmap(virBitmapPtr bitmap)
{
virJSONValuePtr ret;
ssize_t pos = -1;
if (!(ret = virJSONValueNewArray()))
return NULL;
if (!bitmap)
return ret;
while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
virJSONValuePtr newelem;
if (!(newelem = virJSONValueNewNumberLong(pos)) ||
virJSONValueArrayAppend(ret, newelem) < 0) {
virJSONValueFree(newelem);
goto error;
}
}
return ret;
error:
virJSONValueFree(ret);
return NULL;
}
int
virJSONValueIsNull(virJSONValuePtr val)
{
......
......@@ -25,6 +25,7 @@
# define __VIR_JSON_H_
# include "internal.h"
# include "virbitmap.h"
# include <stdarg.h>
......@@ -102,6 +103,7 @@ virJSONValuePtr virJSONValueNewBoolean(int boolean);
virJSONValuePtr virJSONValueNewNull(void);
virJSONValuePtr virJSONValueNewArray(void);
virJSONValuePtr virJSONValueNewObject(void);
virJSONValuePtr virJSONValueNewArrayFromBitmap(virBitmapPtr bitmap);
int virJSONValueObjectAppend(virJSONValuePtr object, const char *key, virJSONValuePtr value);
int virJSONValueArrayAppend(virJSONValuePtr object, virJSONValuePtr value);
......@@ -125,6 +127,8 @@ int virJSONValueGetNumberLong(virJSONValuePtr object, long long *value);
int virJSONValueGetNumberUlong(virJSONValuePtr object, unsigned long long *value);
int virJSONValueGetNumberDouble(virJSONValuePtr object, double *value);
int virJSONValueGetBoolean(virJSONValuePtr object, bool *value);
int virJSONValueGetArrayAsBitmap(const virJSONValue *val, virBitmapPtr *bitmap)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int virJSONValueIsNull(virJSONValuePtr object);
const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册