]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
util: virTypedParams{Filter,GetStringList}
authorPavel Boldin <pboldin@mirantis.com>
Mon, 15 Jun 2015 22:42:08 +0000 (01:42 +0300)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 18 Jun 2015 14:46:09 +0000 (16:46 +0200)
Add multikey API:

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

Signed-off-by: Pavel Boldin <pboldin@mirantis.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/libvirt_private.syms
src/util/virtypedparam.c
src/util/virtypedparam.h
tests/virtypedparamtest.c

index 2d4ab2171de3fbf6f59fd5e06f8382c6b8b157c4..bf8ef7632733b2032d427e0d3bb7bc7a35f5341a 100644 (file)
@@ -2274,6 +2274,8 @@ virTypedParameterTypeFromString;
 virTypedParameterTypeToString;
 virTypedParamsCheck;
 virTypedParamsCopy;
+virTypedParamsFilter;
+virTypedParamsGetStringList;
 virTypedParamsReplaceString;
 virTypedParamsValidate;
 
index 6f608d648b2bc43f7f66c91c81d374844f722be3..a9cc1bc48aa97b9b9ef06e6c481545627bf26c73 100644 (file)
@@ -482,6 +482,51 @@ 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;
+
+    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:
+    return -1;
+}
+
+
 #define VIR_TYPED_PARAM_CHECK_TYPE(check_type)                              \
     do { if (param->type != check_type) {                                   \
         virReportError(VIR_ERR_INVALID_ARG,                                 \
@@ -749,6 +794,63 @@ virTypedParamsGetString(virTypedParameterPtr params,
 }
 
 
+/**
+ * virTypedParamsGetStringList:
+ * @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
+ *
+ * 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 amount of strings in @values array on success,
+ * -1 otherwise.
+ */
+int
+virTypedParamsGetStringList(virTypedParameterPtr params,
+                            int nparams,
+                            const char *name,
+                            const char ***values)
+{
+    size_t i, n;
+    int nfiltered;
+    virTypedParameterPtr *filtered = NULL;
+
+    virResetLastError();
+
+    virCheckNonNullArgGoto(values, error);
+    *values = NULL;
+
+    nfiltered = virTypedParamsFilter(params, nparams, name, &filtered);
+
+    if (nfiltered < 0)
+        goto error;
+
+    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;
+    }
+
+    VIR_FREE(filtered);
+    return n;
+
+ error:
+    if (values)
+        VIR_FREE(*values);
+    VIR_FREE(filtered);
+    virDispatchError(NULL);
+    return -1;
+}
+
+
 /**
  * virTypedParamsAddInt:
  * @params: pointer to the array of typed parameters
index b4ae007cbf6b93153111f94bdafa69cfcdb9b88e..9bef2041db9b68ed307bb1d44531cb49bb0c8106 100644 (file)
@@ -45,6 +45,20 @@ bool virTypedParamsCheck(virTypedParameterPtr params,
                          const char **names,
                          int nnames);
 
+int
+virTypedParamsGetStringList(virTypedParameterPtr params,
+                            int nparams,
+                            const char *name,
+                            const char ***values);
+int
+virTypedParamsFilter(virTypedParameterPtr params,
+                     int nparams,
+                     const char *name,
+                     virTypedParameterPtr **ret)
+    ATTRIBUTE_RETURN_CHECK  ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3)
+    ATTRIBUTE_NONNULL(4);
+
+
 int virTypedParameterAssign(virTypedParameterPtr param, const char *name,
                             int type, /* TYPE arg */ ...)
     ATTRIBUTE_RETURN_CHECK;
index 95e22a7e2d1e341378bfe3542bf149b68e6e8d88..ef0be46e327658617ecc4c9571533998b4fac2c2 100644 (file)
@@ -80,6 +80,101 @@ testTypedParamsValidate(const void *opaque)
     .params  = PARAMS_ARRAY(__VA_ARGS__), \
     .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
+testTypedParamsGetStringList(const void *opaque ATTRIBUTE_UNUSED)
+{
+    size_t i;
+    int 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"} }
+    };
+
+    picked = virTypedParamsGetStringList(params,
+                                         ARRAY_CARDINALITY(params),
+                                         "bar",
+                                         &strings);
+
+    if (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)
 {
@@ -159,6 +254,12 @@ mymain(void)
     if (testTypedParamsValidator() < 0)
         rv = -1;
 
+    if (virtTestRun("Filtering", testTypedParamsFilter, NULL) < 0)
+        rv = -1;
+
+    if (virtTestRun("Get All Strings", testTypedParamsGetStringList, NULL) < 0)
+        rv = -1;
+
     if (rv < 0)
         return EXIT_FAILURE;
     return EXIT_SUCCESS;