[libvirt] [PATCH v3 6/9] util: virTypedParams{Filter,PickStrings}

Michal Privoznik mprivozn at redhat.com
Tue May 26 13:01:48 UTC 2015


From: Pavel Boldin <pboldin at mirantis.com>

Add multikey API:

 * virTypedParamsFilter that returns all the parameters with specified name.
 * virTypedParamsPickStrings that returns a list with all the values for
   specified name and string type.

Signed-off-by: Pavel Boldin <pboldin at mirantis.com>
Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 include/libvirt/libvirt-host.h |  11 ++++
 src/libvirt_public.syms        |   2 +
 src/util/virtypedparam.c       | 113 +++++++++++++++++++++++++++++++++++++++++
 tests/virtypedparamtest.c      |  99 ++++++++++++++++++++++++++++++++++++
 4 files changed, 225 insertions(+)

diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 070550b..6767527 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,
@@ -284,6 +289,12 @@ virTypedParamsGetString (virTypedParameterPtr params,
                          const char *name,
                          const char **value);
 int
+virTypedParamsPickStrings(virTypedParameterPtr params,
+                         int nparams,
+                         const char *name,
+                         const char ***values,
+                         size_t *picked);
+int
 virTypedParamsAddInt    (virTypedParameterPtr *params,
                          int *nparams,
                          int *maxparams,
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 716dd2f..845a0b8 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -713,6 +713,8 @@ LIBVIRT_1.2.15 {
 LIBVIRT_1.2.16 {
     global:
         virDomainSetUserPassword;
+        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 e91ca99..d88d4a7 100644
--- a/src/util/virtypedparam.c
+++ b/src/util/virtypedparam.c
@@ -481,6 +481,57 @@ 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 not
+ * 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, alloc = 0, n = 0;
+
+    virResetLastError();
+
+    virCheckNonNullArgGoto(params, error);
+    virCheckNonNullArgGoto(name, error);
+    virCheckNonNullArgGoto(ret, error);
+
+    *ret = NULL;
+
+    for (i = 0; i < nparams; i++) {
+        if (STREQ(params[i].field, name)) {
+            if (VIR_RESIZE_N(*ret, alloc, 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 +800,68 @@ virTypedParamsGetString(virTypedParameterPtr params,
 
 
 /**
+ * virTypedParamsPickStrings:
+ * @params: array of typed parameters
+ * @nparams: number of parameters in the @params array
+ * @name: name of the parameter to find
+ * @values: array of returned values
+ * @picked: pointer to the amount of picked strings.
+ *
+ * Finds all parameters with desired @name within @params and
+ * store their values into @values. The @values array is self
+ * allocated and its length is stored into @picked. When no
+ * longer needed, caller should free the returned array, but not
+ * the items since they are taken from @params array.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virTypedParamsPickStrings(virTypedParameterPtr params,
+                          int nparams,
+                          const char *name,
+                          const char ***values,
+                          size_t *picked)
+{
+    size_t i, n;
+    int nfiltered;
+    virTypedParameterPtr *filtered = NULL;
+
+    virResetLastError();
+
+    virCheckNonNullArgGoto(values, error);
+    virCheckNonNullArgGoto(picked, error);
+
+    nfiltered = virTypedParamsFilter(params, nparams, name, &filtered);
+
+    if (nfiltered < 0)
+        goto error;
+
+    *values = NULL;
+
+    if (nfiltered &&
+        VIR_ALLOC_N(*values, nfiltered) < 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;
+    }
+
+    *picked = n;
+
+    VIR_FREE(filtered);
+    return 0;
+
+ error:
+    if (values)
+        VIR_FREE(*values);
+    VIR_FREE(filtered);
+    virDispatchError(NULL);
+    return -1;
+}
+
+
+/**
  * 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..abdddd5 100644
--- a/tests/virtypedparamtest.c
+++ b/tests/virtypedparamtest.c
@@ -81,6 +81,99 @@ 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"} }
+    };
+
+    if (virTypedParamsPickStrings(params,
+                                  ARRAY_CARDINALITY(params),
+                                  "bar",
+                                  &strings,
+                                  &picked) < 0)
+        goto cleanup;
+
+    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 +252,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;
-- 
2.3.6




More information about the libvir-list mailing list