#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,
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);
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;
}
}
-static int
-virQEMUBuildCommandLineJSONIterate(const char *key,
- const virJSONValue *value,
- void *opaque)
-{
- return virQEMUBuildCommandLineJSONRecurse(key, value, opaque, false);
-}
-
-
/**
* virQEMUBuildCommandLineJSON:
* @value: json object containing the value
virQEMUBuildCommandLineJSON(const virJSONValue *value,
virBufferPtr buf)
{
- if (virJSONValueObjectForeachKeyValue(value,
- virQEMUBuildCommandLineJSONIterate,
- buf) < 0)
- return -1;
-
- return 0;
+ return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, false);
}
"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;