On 10/20/2016 10:24 AM, Peter Krempa wrote:
Simplifies cases where JSON array members need to be transferred to
a
different structure.
---
src/libvirt_private.syms | 1 +
src/util/virjson.c | 36 ++++++++++++++++++++++++++++++++++++
src/util/virjson.h | 6 ++++++
3 files changed, 43 insertions(+)
+/**
+ * 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.
+ * By returning success, the array claims ownership of given array element and
s/array claims/callback claims/
"returning success" - is that 0?
+ * is responsible for freeing it.
+ *
+ * Returns 0 if all members were successfully stolen by the callback; -1
+ * otherwise. The rest of the members stays in posession of the array.
s/stays/stay/
s/posession/the possession/
Does the iteration stop at the first callback that returns non-zero? Do
we want something a bit more complex, where a negative return aborts
right away, returning 0 means the callback claimed possession but keep
iterating, and where a positive return means the callback did not claim
possession but wants to keep iterating?
+ */
+int
+virJSONValueArrayForeachSteal(virJSONValuePtr array,
+ virJSONArrayIteratorFunc cb,
+ void *opaque)
+{
+ ssize_t i;
+
+ if (array->type != VIR_JSON_TYPE_ARRAY)
+ return -1;
+
+ for (i = array->data.array.nvalues - 1; i >= 0; i--) {
Does order of iteration matter? JSON arrays (can be) order-dependent,
unlike dicts that are order-agnostic. All other clients of
data.array.nvalues iterate forward, not backward, so we ought to do
likewise.
+ if (cb(i, array->data.array.values[i], opaque) < 0)
+ break;
Okay, you are handling < 0 as failure and end iteration, and treating
all non-negative as successfully claiming the element. But is that
enough power for all uses of this interface? See my thoughts above
about distinguishing between 0 and positive returns. Then again, if you
do that, you'd have to memmove remaining elements to close gaps.
+
+ array->data.array.values[i] = NULL;
+ }
+
+ array->data.array.nvalues = i + 1;
I see why you iterate backwards; you don't have to memmove elements that
aren't stolen. But I'm still not convinced it is the best thing to be
doing.
+
+ return i < 0 ? 0 : -1;
+}
The interface sounds like it will be useful, but I want to make sure it
doesn't lock us into design issues that will haunt us later on.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org