diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 74dd5271a8..ac6a1e1622 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1766,6 +1766,7 @@ virISCSIScanTargets; # util/virjson.h virJSONValueArrayAppend; +virJSONValueArrayForeachSteal; virJSONValueArrayGet; virJSONValueArraySize; virJSONValueArraySteal; diff --git a/src/util/virjson.c b/src/util/virjson.c index 1d8e6d5774..b42211c0d2 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -949,6 +949,61 @@ virJSONValueArraySteal(virJSONValuePtr array, } +/** + * virJSONValueArrayForeachSteal: + * @array: array to iterate + * @cb: callback called on every member of the array + * @opaque: custom data for the callback + * + * Iterates members of the array and calls the callback on every single member. + * The return codes of the callback are interpreted as follows: + * 0: callback claims ownership of the array element and is responsible for + * freeing it + * 1: callback doesn't claim ownership of the element + * -1: callback doesn't claim ownership of the element and iteration does not + * continue + * + * Returns 0 if all members were iterated and/or stolen by the callback; -1 + * on callback failure or if the JSON value object is not an array. + * The rest of the members stay in possession of the array and it's condensed. + */ +int +virJSONValueArrayForeachSteal(virJSONValuePtr array, + virJSONArrayIteratorFunc cb, + void *opaque) +{ + size_t i; + size_t j = 0; + int ret = 0; + int rc; + + if (array->type != VIR_JSON_TYPE_ARRAY) + return -1; + + for (i = 0; i < array->data.array.nvalues; i++) { + if ((rc = cb(i, array->data.array.values[i], opaque)) < 0) { + ret = -1; + break; + } + + if (rc == 0) + array->data.array.values[i] = NULL; + } + + /* condense the remaining entries at the beginning */ + for (i = 0; i < array->data.array.nvalues; i++) { + if (!array->data.array.values[i]) + continue; + + array->data.array.values[j++] = array->data.array.values[i]; + } + + array->data.array.nvalues = j; + + return ret; +} + + const char * virJSONValueGetString(virJSONValuePtr string) { diff --git a/src/util/virjson.h b/src/util/virjson.h index 8b62d651d6..5b4f17253f 100644 --- a/src/util/virjson.h +++ b/src/util/virjson.h @@ -117,6 +117,12 @@ bool virJSONValueIsArray(virJSONValuePtr array); ssize_t virJSONValueArraySize(const virJSONValue *array); virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr object, unsigned int element); virJSONValuePtr virJSONValueArraySteal(virJSONValuePtr object, unsigned int element); +typedef int (*virJSONArrayIteratorFunc)(size_t pos, + virJSONValuePtr item, + void *opaque); +int virJSONValueArrayForeachSteal(virJSONValuePtr array, + virJSONArrayIteratorFunc cb, + void *opaque); int virJSONValueObjectKeysNumber(virJSONValuePtr object); const char *virJSONValueObjectGetKey(virJSONValuePtr object, unsigned int n);