[libvirt] [PATCH 2/5] util: virTypedParamsPick* multikey API

Pavel Boldin pboldin at mirantis.com
Tue May 12 12:07:29 UTC 2015


Add multikey APIs for virTypedParams*:

 * virTypedParamsPick that returns all the parameters with the
   specified name and type.
 * 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       | 90 ++++++++++++++++++++++++++++++++++++++++++
 tests/virtypedparamtest.c      | 87 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 193 insertions(+)

diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index a3e8b88..afa730f 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -256,6 +256,12 @@ virTypedParameterPtr
 virTypedParamsGet       (virTypedParameterPtr params,
                          int nparams,
                          const char *name);
+virTypedParameterPtr*
+virTypedParamsPick      (virTypedParameterPtr params,
+                         int nparams,
+                         const char *name,
+                         int type,
+                         size_t *picked);
 int
 virTypedParamsGetInt    (virTypedParameterPtr params,
                          int nparams,
@@ -291,6 +297,10 @@ virTypedParamsGetString (virTypedParameterPtr params,
                          int nparams,
                          const char *name,
                          const char **value);
+const char **
+virTypedParamsPickStrings(virTypedParameterPtr params,
+                         int nparams,
+                         const char *name);
 int
 virTypedParamsAddInt    (virTypedParameterPtr *params,
                          int *nparams,
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index ef3d2f0..d886967 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:
+        virTypedParamsPick;
+        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 bd47609..643d10e 100644
--- a/src/util/virtypedparam.c
+++ b/src/util/virtypedparam.c
@@ -480,6 +480,56 @@ virTypedParamsGet(virTypedParameterPtr params,
 }
 
 
+/**
+ * virTypedParamsPick:
+ * @params: array of typed parameters
+ * @nparams: number of parameters in the @params array
+ * @name: name of the parameter to find
+ * @type: type of the parameter to find
+ * @picked: pointer to a size_t with amount of picked
+ *
+ *
+ * Finds typed parameters called @name.
+ *
+ * Returns pointers to the parameters or NULL if there are none in @params.
+ * This function does not raise an error, even when returning NULL.
+ * Callee should call VIR_FREE on the returned array.
+ */
+virTypedParameterPtr*
+virTypedParamsPick(virTypedParameterPtr params,
+                   int nparams,
+                   const char *name,
+                   int type,
+                   size_t *picked)
+{
+    size_t i, max = 0;
+    virTypedParameterPtr *values = NULL;
+
+    *picked = 0;
+
+    if (!params || !name)
+        return NULL;
+
+    for (i = 0; i < nparams; i++) {
+        if (params[i].type == type && STREQ(params[i].field, name)) {
+            if (VIR_RESIZE_N(values, max, *picked, 1) < 0)
+                goto error;
+
+            values[*picked] = &params[i];
+
+            *picked += 1;
+        }
+    }
+
+    return values;
+
+ error:
+    *picked = 0;
+    VIR_FREE(values);
+    return NULL;
+}
+
+
 #define VIR_TYPED_PARAM_CHECK_TYPE(check_type)                              \
     do { if (param->type != check_type) {                                   \
         virReportError(VIR_ERR_INVALID_ARG,                                 \
@@ -747,6 +797,46 @@ virTypedParamsGetString(virTypedParameterPtr params,
 }
 
 
+/**
+ * virTypedParamsPickStrings:
+ * @params: array of typed parameters
+ * @nparams: number of parameters in the @params array
+ * @name: name of the parameter to find
+ *
+ *
+ * Finds typed parameters called @name.
+ *
+ * Returns pointers to the parameters or NULL if there are none in @params.
+ * This function does not raise an error, even when returning NULL.
+ * Callee should call VIR_FREE on the returned array.
+ */
+const char **
+virTypedParamsPickStrings(virTypedParameterPtr params,
+                          int nparams, const char *name)
+{
+    const char **values = NULL;
+    size_t i, picked;
+    virTypedParameterPtr *picked_params;
+
+    picked_params = virTypedParamsPick(params, nparams,
+                                       name, VIR_TYPED_PARAM_STRING,
+                                       &picked);
+
+    if (picked_params == NULL)
+        return NULL;
+
+    if (VIR_ALLOC_N(values, picked + 1) < 0)
+        goto cleanup;
+
+    for (i = 0; i < picked; i++)
+        values[i] = picked_params[i]->value.s;
+
+ cleanup:
+    VIR_FREE(picked_params);
+    return values;
+}
+
+
 #define VIR_TYPED_PARAM_CHECK()                                     \
     do { if (virTypedParamsGet(*params, n, name)) {                 \
         virReportError(VIR_ERR_INVALID_ARG,                         \
diff --git a/tests/virtypedparamtest.c b/tests/virtypedparamtest.c
index 27b7e60..287d3f1 100644
--- a/tests/virtypedparamtest.c
+++ b/tests/virtypedparamtest.c
@@ -95,6 +95,87 @@ testTypedParamsValidate(const void *opaque)
 #define PARAM(field_, type_) { .field = field_, .type = type_ }
 
 static int
+testTypedParamsPick(const void *opaque ATTRIBUTE_UNUSED)
+{
+    size_t i, picked;
+    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 *picked_params = NULL;
+
+
+    picked_params = virTypedParamsPick(params, ARRAY_CARDINALITY(params),
+                                       "foo", VIR_TYPED_PARAM_INT, &picked);
+    if (picked != 3)
+        goto cleanup;
+
+    for (i = 0; i < picked; i++) {
+        if (picked_params[i] != &params[1 + i * 2])
+            goto cleanup;
+    }
+    VIR_FREE(picked_params);
+
+    picked_params = virTypedParamsPick(params, ARRAY_CARDINALITY(params),
+                                       "bar", VIR_TYPED_PARAM_UINT, &picked);
+
+    if (picked != 2)
+        goto cleanup;
+
+    for (i = 0; i < picked; i++) {
+        if (picked_params[i] != &params[i * 2])
+            goto cleanup;
+    }
+
+    rv = 0;
+ cleanup:
+    VIR_FREE(picked_params);
+    return rv;
+}
+
+static int
+testTypedParamsPickStrings(const void *opaque ATTRIBUTE_UNUSED)
+{
+    size_t i;
+    int rv = -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 = "foo", .type = VIR_TYPED_PARAM_INT },
+        { .field = "bar", .type = VIR_TYPED_PARAM_STRING,
+          .value = { .s = (char*)"bar3"} }
+    };
+
+    strings = virTypedParamsPickStrings(params,
+                                        ARRAY_CARDINALITY(params),
+                                        "bar");
+
+    for (i = 0; strings[i]; i++) {
+        if (!STREQLEN(strings[i], "bar", 3))
+            goto cleanup;
+        if (strings[i][3] != i + '1')
+            goto cleanup;
+    }
+
+    rv = 0;
+ cleanup:
+    VIR_FREE(strings);
+    return rv;
+}
+
+static int
 testTypedParamsValidator(void)
 {
     size_t i;
@@ -169,6 +250,12 @@ mymain(void)
     if (testTypedParamsValidator() < 0)
         rv = -1;
 
+    if (virtTestRun("Picking", testTypedParamsPick, 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