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 | 70 ++++++++++++++++++++++++++++++++++-----------
tests/qemucommandutiltest.c | 8 ++++++
2 files changed, 61 insertions(+), 17 deletions(-)
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 99c14c2..df665ad 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -26,11 +26,49 @@
#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);
}
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
index 8299462..4872ea3 100644
--- a/tests/qemucommandutiltest.c
+++ b/tests/qemucommandutiltest.c
@@ -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;
--
2.9.0