util: qemu: Allow nested objects in JSON -> commandline generator

Move the iterator of objects to the recursive function so that nested
objects are supported by flattening the structure with '.' delimiters.
This commit is contained in:
Peter Krempa 2016-07-22 17:19:28 +02:00
parent 25a272ada4
commit cd86d6f465
2 changed files with 61 additions and 17 deletions

View File

@ -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);
}

View 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;