[libvirt] [PATCH v2 3/6] util: virTypedParams{Filter,PickStrings}

Pavel Boldin pboldin at mirantis.com
Thu May 21 11:07:32 UTC 2015


Add multikey API:

 * virTypedParamsFilter that returns all the parameters with specified name.
 * virTypedParamsPickStrings that returns a NULL-terminated `const char**'
   list with all the values for specified name and string type.

Signed-off-by: Pavel Boldin <pboldin at mirantis.com>
---
 include/libvirt/libvirt-host.h |  10 ++++
 src/libvirt_public.syms        |   6 +++
 src/util/virtypedparam.c       | 107 +++++++++++++++++++++++++++++++++++++++++
 tests/virtypedparamtest.c      |  96 ++++++++++++++++++++++++++++++++++++
 4 files changed, 219 insertions(+)

diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 070550b..36267fc 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -249,6 +249,11 @@ virTypedParamsGet       (virTypedParameterPtr params,
                          int nparams,
                          const char *name);
 int
+virTypedParamsFilter    (virTypedParameterPtr params,
+                         int nparams,
+                         const char *name,
+                         virTypedParameterPtr **ret);
+int
 virTypedParamsGetInt    (virTypedParameterPtr params,
                          int nparams,
                          const char *name,
@@ -283,6 +288,11 @@ virTypedParamsGetString (virTypedParameterPtr params,
                          int nparams,
                          const char *name,
                          const char **value);
+const char **
+virTypedParamsPickStrings(virTypedParameterPtr params,
+                         int nparams,
+                         const char *name,
+                         size_t *picked);
 int
 virTypedParamsAddInt    (virTypedParameterPtr *params,
                          int *nparams,
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index ef3d2f0..8fc8c42 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -710,4 +710,10 @@ LIBVIRT_1.2.15 {
         virDomainDelIOThread;
 } LIBVIRT_1.2.14;
 
+LIBVIRT_1.2.16 {
+    global:
+        virTypedParamsFilter;
+        virTypedParamsPickStrings;
+} LIBVIRT_1.2.15;
+
 # .... define new API here using predicted next version number ....
diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c
index ec20b74..a3d959e 100644
--- a/src/util/virtypedparam.c
+++ b/src/util/virtypedparam.c
@@ -481,6 +481,58 @@ virTypedParamsGet(virTypedParameterPtr params,
 }
 
 
+/**
+ * virTypedParamsFilter:
+ * @params: array of typed parameters
+ * @nparams: number of parameters in the @params array
+ * @name: name of the parameter to find
+ * @ret: pointer to the returned array
+ *
+ *
+ * Filters @params retaining only the parameters named @name in the
+ * resulting array @ret. Caller should free the @ret array but no the
+ * items since they are pointing to the @params elements.
+ *
+ * Returns amount of elements in @ret on success, -1 on error.
+ */
+int
+virTypedParamsFilter(virTypedParameterPtr params,
+                     int nparams,
+                     const char *name,
+                     virTypedParameterPtr **ret)
+{
+    size_t i, max = 0, n = 0;
+
+    virResetLastError();
+
+    if (!params || !name || !ret) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Required argument is missing: %s"),
+                       !params ? "params" : !name ? "name" : "ret");
+        goto error;
+    }
+
+    for (i = 0; i < nparams; i++) {
+        if (STREQ(params[i].field, name)) {
+            if (VIR_RESIZE_N(*ret, max, n, 1) < 0)
+                goto error;
+
+            (*ret)[n] = &params[i];
+
+            n++;
+        }
+    }
+
+    return n;
+
+ error:
+    if (ret)
+        VIR_FREE(*ret);
+    virDispatchError(NULL);
+    return -1;
+}
+
+
 #define VIR_TYPED_PARAM_CHECK_TYPE(check_type)                              \
     do { if (param->type != check_type) {                                   \
         virReportError(VIR_ERR_INVALID_ARG,                                 \
@@ -749,6 +801,61 @@ virTypedParamsGetString(virTypedParameterPtr params,
 
 
 /**
+ * virTypedParamsPickStrings:
+ * @params: array of typed parameters
+ * @nparams: number of parameters in the @params array
+ * @name: name of the parameter to find
+ * @picked: pointer to the amount of picked strings.
+ *
+ *
+ * Finds typed parameters called @name.
+ *
+ * Returns a string list, which is a NULL terminated array of pointers to
+ * strings. Since a NULL is a valid parameter string value caller can ask
+ * for exact amount of picked strings using @picked argument.
+ *
+ * Caller should free the returned array but not the items since they are
+ * taken from @params array.
+ */
+const char **
+virTypedParamsPickStrings(virTypedParameterPtr params,
+                          int nparams, const char *name,
+                          size_t *picked)
+{
+    const char **values = NULL;
+    size_t i, n;
+    int nfiltered;
+    virTypedParameterPtr *filtered = NULL;
+
+    virResetLastError();
+
+    nfiltered = virTypedParamsFilter(params, nparams, name, &filtered);
+
+    if (nfiltered <= 0)
+        return NULL;
+
+    if (VIR_ALLOC_N(values, nfiltered + 1) < 0)
+        goto error;
+
+    for (n = 0, i = 0; i < nfiltered; i++) {
+        if (filtered[i]->type == VIR_TYPED_PARAM_STRING)
+            values[n++] = filtered[i]->value.s;
+    }
+
+    if (picked)
+        *picked = n;
+
+    VIR_FREE(filtered);
+    return values;
+
+ error:
+    VIR_FREE(filtered);
+    virDispatchError(NULL);
+    return NULL;
+}
+
+
+/**
  * virTypedParamsAddInt:
  * @params: pointer to the array of typed parameters
  * @nparams: number of parameters in the @params array
diff --git a/tests/virtypedparamtest.c b/tests/virtypedparamtest.c
index 95e22a7..945dbe7 100644
--- a/tests/virtypedparamtest.c
+++ b/tests/virtypedparamtest.c
@@ -81,6 +81,96 @@ testTypedParamsValidate(const void *opaque)
     .nparams = PARAMS_SIZE(__VA_ARGS__),
 
 static int
+testTypedParamsFilter(const void *opaque ATTRIBUTE_UNUSED)
+{
+    size_t i, nfiltered;
+    int rv = -1;
+    virTypedParameter params[] = {
+        { .field = "bar", .type = VIR_TYPED_PARAM_UINT },
+        { .field = "foo", .type = VIR_TYPED_PARAM_INT },
+        { .field = "bar", .type = VIR_TYPED_PARAM_UINT },
+        { .field = "foo", .type = VIR_TYPED_PARAM_INT },
+        { .field = "foobar", .type = VIR_TYPED_PARAM_STRING },
+        { .field = "foo", .type = VIR_TYPED_PARAM_INT }
+    };
+    virTypedParameterPtr *filtered = NULL;
+
+
+    nfiltered = virTypedParamsFilter(params, ARRAY_CARDINALITY(params),
+                                     "foo", &filtered);
+    if (nfiltered != 3)
+        goto cleanup;
+
+    for (i = 0; i < nfiltered; i++) {
+        if (filtered[i] != &params[1 + i * 2])
+            goto cleanup;
+    }
+    VIR_FREE(filtered);
+    filtered = NULL;
+
+    nfiltered = virTypedParamsFilter(params, ARRAY_CARDINALITY(params),
+                                     "bar", &filtered);
+
+    if (nfiltered != 2)
+        goto cleanup;
+
+    for (i = 0; i < nfiltered; i++) {
+        if (filtered[i] != &params[i * 2])
+            goto cleanup;
+    }
+
+    rv = 0;
+ cleanup:
+    VIR_FREE(filtered);
+    return rv;
+}
+
+static int
+testTypedParamsPickStrings(const void *opaque ATTRIBUTE_UNUSED)
+{
+    size_t i, picked;
+    int rv = -1;
+    char l = '1';
+    const char **strings = NULL;
+
+    virTypedParameter params[] = {
+        { .field = "bar", .type = VIR_TYPED_PARAM_STRING,
+          .value = { .s = (char*)"bar1"} },
+        { .field = "foo", .type = VIR_TYPED_PARAM_INT },
+        { .field = "bar", .type = VIR_TYPED_PARAM_STRING,
+          .value = { .s = (char*)"bar2"} },
+        { .field = "foo", .type = VIR_TYPED_PARAM_INT },
+        { .field = "foobar", .type = VIR_TYPED_PARAM_STRING },
+        { .field = "bar", .type = VIR_TYPED_PARAM_STRING,
+          .value = { .s = NULL } },
+        { .field = "foo", .type = VIR_TYPED_PARAM_INT },
+        { .field = "bar", .type = VIR_TYPED_PARAM_STRING,
+          .value = { .s = (char*)"bar3"} }
+    };
+
+    strings = virTypedParamsPickStrings(params,
+                                        ARRAY_CARDINALITY(params),
+                                        "bar", &picked);
+
+    for (i = 0; i < picked; i++) {
+        if (i == 2) {
+            if (strings[i] != NULL)
+                goto cleanup;
+            continue;
+        }
+        if (!STREQLEN(strings[i], "bar", 3))
+            goto cleanup;
+        if (strings[i][3] != l++)
+            goto cleanup;
+    }
+
+    rv = 0;
+ cleanup:
+    VIR_FREE(strings);
+    return rv;
+}
+
+static int
 testTypedParamsValidator(void)
 {
     size_t i;
@@ -159,6 +249,12 @@ mymain(void)
     if (testTypedParamsValidator() < 0)
         rv = -1;
 
+    if (virtTestRun("Filtering", testTypedParamsFilter, NULL) < 0)
+        rv = -1;
+
+    if (virtTestRun("Picking Strings", testTypedParamsPickStrings, NULL) < 0)
+        rv = -1;
+
     if (rv < 0)
         return EXIT_FAILURE;
     return EXIT_SUCCESS;
-- 
1.9.1




More information about the libvir-list mailing list