]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: json: add helper to iterate and steal members of json array
authorPeter Krempa <pkrempa@redhat.com>
Mon, 17 Oct 2016 11:44:16 +0000 (13:44 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 9 Nov 2016 15:47:08 +0000 (16:47 +0100)
Simplifies cases where JSON array members need to be transferred to a
different structure.

src/libvirt_private.syms
src/util/virjson.c
src/util/virjson.h

index 74dd5271a8bde9f3ed2ece926b72c5ede8e569f8..ac6a1e16226b2c4447cdd026d5273e96fa73540f 100644 (file)
@@ -1766,6 +1766,7 @@ virISCSIScanTargets;
 
 # util/virjson.h
 virJSONValueArrayAppend;
+virJSONValueArrayForeachSteal;
 virJSONValueArrayGet;
 virJSONValueArraySize;
 virJSONValueArraySteal;
index 1d8e6d577403c5b2d21c1c614d8f8bc4e58647cf..b42211c0d2869af67c9cbee419d4af9556a60f83 100644 (file)
@@ -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)
 {
index 8b62d651d60e727e271e90a546fb7db96d83f901..5b4f17253fec47198af1d753f7d9f32b0e116962 100644 (file)
@@ -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);