]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: qemu: Allow for different approaches to format JSON arrays
authorPeter Krempa <pkrempa@redhat.com>
Fri, 22 Jul 2016 15:50:03 +0000 (17:50 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 27 Jul 2016 07:40:07 +0000 (09:40 +0200)
For use with memory hotplug virQEMUBuildCommandLineJSONRecurse attempted
to format JSON arrays as bitmap on the command line. Make the formatter
function configurable so that it can be reused with different syntaxes
of arrays such as numbered arrays for use with disk sources.

This patch extracts the code and adds a parameter for the function that
will allow to plug in different formatters.

src/libvirt_private.syms
src/util/virqemu.c
src/util/virqemu.h
tests/qemucommandutiltest.c

index 948c7b58aa3d1f4ccfc8214cccab31ece19a4f3c..73904a68413661e9584152145aefbd01096301a1 100644 (file)
@@ -2205,6 +2205,7 @@ virProcessWait;
 # util/virqemu.h
 virQEMUBuildBufferEscapeComma;
 virQEMUBuildCommandLineJSON;
+virQEMUBuildCommandLineJSONArrayBitmap;
 virQEMUBuildLuksOpts;
 virQEMUBuildObjectCommandlineFromJSON;
 
index df665ad6add1ddcd3366e9be60d7eab78bfda0c4..3cc59e75ace8f04f2ce94fa32dbaa154c69d3f6c 100644 (file)
@@ -36,6 +36,7 @@ VIR_LOG_INIT("util.qemu");
 struct virQEMUCommandLineJSONIteratorData {
     const char *prefix;
     virBufferPtr buf;
+    virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc;
 };
 
 
@@ -43,8 +44,41 @@ static int
 virQEMUBuildCommandLineJSONRecurse(const char *key,
                                    const virJSONValue *value,
                                    virBufferPtr buf,
+                                   virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
                                    bool nested);
 
+
+
+int
+virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
+                                       const virJSONValue *array,
+                                       virBufferPtr buf)
+{
+    ssize_t pos = -1;
+    ssize_t end;
+    virBitmapPtr bitmap = NULL;
+
+    if (virJSONValueGetArrayAsBitmap(array, &bitmap) < 0)
+        return -1;
+
+    while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
+        if ((end = virBitmapNextClearBit(bitmap, pos)) < 0)
+            end = virBitmapLastSetBit(bitmap) + 1;
+
+        if (end - 1 > pos) {
+            virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1);
+            pos = end;
+        } else {
+            virBufferAsprintf(buf, ",%s=%zd", key, pos);
+        }
+    }
+
+    virBitmapFree(bitmap);
+
+    return 0;
+}
+
+
 /* internal iterator to handle nested object formatting */
 static int
 virQEMUBuildCommandLineJSONIterate(const char *key,
@@ -59,11 +93,13 @@ virQEMUBuildCommandLineJSONIterate(const char *key,
         if (virAsprintf(&tmpkey, "%s.%s", data->prefix, key) < 0)
             return -1;
 
-        ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf, false);
+        ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf,
+                                                 data->arrayFunc, false);
 
         VIR_FREE(tmpkey);
     } else {
-        ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf, false);
+        ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf,
+                                                 data->arrayFunc, false);
     }
 
     return ret;
@@ -74,13 +110,11 @@ static int
 virQEMUBuildCommandLineJSONRecurse(const char *key,
                                    const virJSONValue *value,
                                    virBufferPtr buf,
+                                   virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
                                    bool nested)
 {
-    struct virQEMUCommandLineJSONIteratorData data = { key, buf };
+    struct virQEMUCommandLineJSONIteratorData data = { key, buf, arrayFunc };
     virJSONValuePtr elem;
-    virBitmapPtr bitmap = NULL;
-    ssize_t pos = -1;
-    ssize_t end;
     size_t i;
 
     if (!key && value->type != VIR_JSON_TYPE_OBJECT) {
@@ -115,26 +149,15 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
             return -1;
         }
 
-        if (virJSONValueGetArrayAsBitmap(value, &bitmap) == 0) {
-            while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
-                if ((end = virBitmapNextClearBit(bitmap, pos)) < 0)
-                    end = virBitmapLastSetBit(bitmap) + 1;
-
-                if (end - 1 > pos) {
-                    virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1);
-                    pos = end;
-                } else {
-                    virBufferAsprintf(buf, ",%s=%zd", key, pos);
-                }
-            }
-        } else {
+        if (!arrayFunc || arrayFunc(key, value, buf) < 0) {
             /* fallback, treat the array as a non-bitmap, adding the key
              * for each member */
             for (i = 0; i < virJSONValueArraySize(value); i++) {
                 elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
 
                 /* recurse to avoid duplicating code */
-                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, true) < 0)
+                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf,
+                                                       arrayFunc, true) < 0)
                     return -1;
             }
         }
@@ -153,7 +176,6 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
         return -1;
     }
 
-    virBitmapFree(bitmap);
     return 0;
 }
 
@@ -162,6 +184,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
  * virQEMUBuildCommandLineJSON:
  * @value: json object containing the value
  * @buf: otuput buffer
+ * @arrayFunc: array formatter function to allow for different syntax
  *
  * Formats JSON value object into command line parameters suitable for use with
  * qemu.
@@ -170,9 +193,10 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
  */
 int
 virQEMUBuildCommandLineJSON(const virJSONValue *value,
-                            virBufferPtr buf)
+                            virBufferPtr buf,
+                            virQEMUBuildCommandLineJSONArrayFormatFunc array)
 {
-    return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, false);
+    return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, array, false);
 }
 
 
@@ -186,7 +210,8 @@ virQEMUBuildObjectCommandlineFromJSON(const char *type,
 
     virBufferAsprintf(&buf, "%s,id=%s", type, alias);
 
-    if (virQEMUBuildCommandLineJSON(props, &buf) < 0)
+    if (virQEMUBuildCommandLineJSON(props, &buf,
+                                    virQEMUBuildCommandLineJSONArrayBitmap) < 0)
         goto cleanup;
 
     if (virBufferCheckError(&buf) < 0)
index efc6c42c4d7ffe477715c4812a6a5518c13724e5..801c35b5dae8f8c323a6bad7d35036b3edbc364d 100644 (file)
 # include "virjson.h"
 # include "virstorageencryption.h"
 
+typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key,
+                                                          const virJSONValue *array,
+                                                          virBufferPtr buf);
+int virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
+                                           const virJSONValue *array,
+                                           virBufferPtr buf);
+
 int virQEMUBuildCommandLineJSON(const virJSONValue *value,
-                                virBufferPtr buf);
+                                virBufferPtr buf,
+                                virQEMUBuildCommandLineJSONArrayFormatFunc array);
 
 char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
                                             const char *alias,
index 4872ea3bba8204396039125072a62888a918fb40..a5e315347fa872c77c354d353fb3976066dbf392 100644 (file)
@@ -51,7 +51,8 @@ testQemuCommandBuildFromJSON(const void *opaque)
         virAsprintf(&expect, ",%s", data->expectprops) < 0)
         return -1;
 
-    if (virQEMUBuildCommandLineJSON(val, &buf) < 0) {
+    if (virQEMUBuildCommandLineJSON(val, &buf,
+                                    virQEMUBuildCommandLineJSONArrayBitmap) < 0) {
         fprintf(stderr,
                 "\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
                 data->props);