]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: qemu: Allow nested objects in JSON -> commandline generator
authorPeter Krempa <pkrempa@redhat.com>
Fri, 22 Jul 2016 15:19:28 +0000 (17:19 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 27 Jul 2016 07:39:58 +0000 (09:39 +0200)
Move the iterator of objects to the recursive function so that nested
objects are supported by flattening the structure with '.' delimiters.

src/util/virqemu.c
tests/qemucommandutiltest.c

index 99c14c2bf8ba73f9b96d0b029ea65860f4b59c22..df665ad6add1ddcd3366e9be60d7eab78bfda0c4 100644 (file)
 #include "virerror.h"
 #include "virlog.h"
 #include "virqemu.h"
+#include "virstring.h"
+#include "viralloc.h"
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
 VIR_LOG_INIT("util.qemu");
 
+struct virQEMUCommandLineJSONIteratorData {
+    const char *prefix;
+    virBufferPtr buf;
+};
+
+
+static int
+virQEMUBuildCommandLineJSONRecurse(const char *key,
+                                   const virJSONValue *value,
+                                   virBufferPtr buf,
+                                   bool nested);
+
+/* internal iterator to handle nested object formatting */
+static int
+virQEMUBuildCommandLineJSONIterate(const char *key,
+                                   const virJSONValue *value,
+                                   void *opaque)
+{
+    struct virQEMUCommandLineJSONIteratorData *data = opaque;
+    char *tmpkey = NULL;
+    int ret = -1;
+
+    if (data->prefix) {
+        if (virAsprintf(&tmpkey, "%s.%s", data->prefix, key) < 0)
+            return -1;
+
+        ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf, false);
+
+        VIR_FREE(tmpkey);
+    } else {
+        ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf, false);
+    }
+
+    return ret;
+}
+
 
 static int
 virQEMUBuildCommandLineJSONRecurse(const char *key,
@@ -38,12 +76,19 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
                                    virBufferPtr buf,
                                    bool nested)
 {
+    struct virQEMUCommandLineJSONIteratorData data = { key, buf };
     virJSONValuePtr elem;
     virBitmapPtr bitmap = NULL;
     ssize_t pos = -1;
     ssize_t end;
     size_t i;
 
+    if (!key && value->type != VIR_JSON_TYPE_OBJECT) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("only JSON objects can be top level"));
+        return -1;
+    }
+
     switch ((virJSONType) value->type) {
     case VIR_JSON_TYPE_STRING:
         virBufferAsprintf(buf, ",%s=", key);
@@ -96,10 +141,15 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
         break;
 
     case VIR_JSON_TYPE_OBJECT:
+        if (virJSONValueObjectForeachKeyValue(value,
+                                              virQEMUBuildCommandLineJSONIterate,
+                                              &data) < 0)
+            return -1;
+        break;
+
     case VIR_JSON_TYPE_NULL:
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("NULL and OBJECT JSON types can't be converted to "
-                         "commandline string"));
+                       _("NULL JSON type can't be converted to commandline"));
         return -1;
     }
 
@@ -108,15 +158,6 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
 }
 
 
-static int
-virQEMUBuildCommandLineJSONIterate(const char *key,
-                                   const virJSONValue *value,
-                                   void *opaque)
-{
-    return virQEMUBuildCommandLineJSONRecurse(key, value, opaque, false);
-}
-
-
 /**
  * virQEMUBuildCommandLineJSON:
  * @value: json object containing the value
@@ -131,12 +172,7 @@ int
 virQEMUBuildCommandLineJSON(const virJSONValue *value,
                             virBufferPtr buf)
 {
-    if (virJSONValueObjectForeachKeyValue(value,
-                                          virQEMUBuildCommandLineJSONIterate,
-                                          buf) < 0)
-        return -1;
-
-    return 0;
+    return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, false);
 }
 
 
index 82994623b1b9c4dd8e20763e20225a0af7f71593..4872ea3bba8204396039125072a62888a918fb40 100644 (file)
@@ -117,6 +117,14 @@ mymain(void)
                                      "array=bleah,array=qwerty,array=1");
     DO_TEST_COMMAND_OBJECT_FROM_JSON("{\"boolean\":true,\"hyphen-name\":1234,\"some_string\":\"bleah\"}",
                                      "boolean=yes,hyphen-name=1234,some_string=bleah");
+    DO_TEST_COMMAND_OBJECT_FROM_JSON("{\"nest\": {\"boolean\":true,"
+                                                 "\"hyphen-name\":1234,"
+                                                 "\"some_string\":\"bleah\","
+                                                 "\"bleah\":\"bl,eah\""
+                                                 "}"
+                                     "}",
+                                     "nest.boolean=yes,nest.hyphen-name=1234,"
+                                     "nest.some_string=bleah,nest.bleah=bl,,eah");
 
     return ret;