The code will become more universal so it makes more sense for it to
live with the rest of the JSON functions.
---
src/libvirt_private.syms | 1 +
src/util/virjson.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
src/util/virjson.h | 2 ++
src/util/virstoragefile.c | 65 +----------------------------------------------
4 files changed, 65 insertions(+), 64 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d487b1f43..9f64b8d93 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1931,6 +1931,7 @@ virJSONValueObjectAppendNumberUlong;
virJSONValueObjectAppendString;
virJSONValueObjectCreate;
virJSONValueObjectCreateVArgs;
+virJSONValueObjectDeflatten;
virJSONValueObjectForeachKeyValue;
virJSONValueObjectGet;
virJSONValueObjectGetArray;
diff --git a/src/util/virjson.c b/src/util/virjson.c
index efd6c3a0e..8ab542432 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -1965,3 +1965,64 @@ virJSONStringReformat(const char *jsonstr,
virJSONValueFree(json);
return ret;
}
+
+
+static int
+virJSONValueObjectDeflattenWorker(const char *key,
+ virJSONValuePtr value,
+ void *opaque)
+{
+ virJSONValuePtr retobj = opaque;
+ virJSONValuePtr newval = NULL;
+ const char *newkey;
+
+ if (!(newkey = STRSKIP(key, "file."))) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("JSON object is neither nested nor flattened"));
+ return -1;
+ }
+
+ if (!(newval = virJSONValueCopy(value)))
+ return -1;
+
+ if (virJSONValueObjectAppend(retobj, newkey, newval) < 0) {
+ virJSONValueFree(newval);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/**
+ * virJSONValueObjectDeflatten:
+ *
+ * In some cases it's possible to nest JSON objects by prefixing object members
+ * with the parent object name followed by the dot and then the attribute name
+ * rather than directly using a nested value object (e.g qemu's JSON
+ * pseudo-protocol in backing file definition).
+ *
+ * This function will attempt to reverse the process and provide a nested json
+ * hierarchy so that the parsers can be kept simple and we still can use the
+ * weird syntax some users might use.
+ *
+ * Currently this function will flatten out just the 'file.' prefix into a new
+ * tree. Any other syntax will be rejected.
+ */
+virJSONValuePtr
+virJSONValueObjectDeflatten(virJSONValuePtr json)
+{
+ virJSONValuePtr ret;
+
+ if (!(ret = virJSONValueNewObject()))
+ return NULL;
+
+ if (virJSONValueObjectForeachKeyValue(json,
+ virJSONValueObjectDeflattenWorker,
+ ret) < 0) {
+ virJSONValueFree(ret);
+ return NULL;
+ }
+
+ return ret;
+}
diff --git a/src/util/virjson.h b/src/util/virjson.h
index c9d9752de..e89a776ab 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -186,4 +186,6 @@ virJSONValuePtr virJSONValueCopy(const virJSONValue *in);
char *virJSONStringReformat(const char *jsonstr, bool pretty);
+virJSONValuePtr virJSONValueObjectDeflatten(virJSONValuePtr json);
+
#endif /* __VIR_JSON_H_ */
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index f0ed5c6bd..52c5301ff 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -3244,69 +3244,6 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[]
= {
};
-static int
-virStorageSourceParseBackingJSONDeflattenWorker(const char *key,
- virJSONValuePtr value,
- void *opaque)
-{
- virJSONValuePtr retobj = opaque;
- virJSONValuePtr newval = NULL;
- const char *newkey;
-
- if (!(newkey = STRSKIP(key, "file."))) {
- virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("JSON backing file syntax is neither nested nor "
- "flattened"));
- return -1;
- }
-
- if (!(newval = virJSONValueCopy(value)))
- return -1;
-
- if (virJSONValueObjectAppend(retobj, newkey, newval) < 0) {
- virJSONValueFree(newval);
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * virStorageSourceParseBackingJSONDeflatten:
- *
- * The json: pseudo-protocol syntax in qemu allows multiple approaches to
- * describe nesting of the values. This is due to the lax handling of the string
- * in qemu and the fact that internally qemu is flattening the values using '.'.
- *
- * This allows to specify nested json strings either using nested json objects
- * or prefixing object members with the parent object name followed by the dot.
- *
- * This function will attempt to reverse the process and provide a nested json
- * hierarchy so that the parsers can be kept simple and we still can use the
- * weird syntax some users might use.
- *
- * Currently this function will flatten out just the 'file.' prefix into a new
- * tree. Any other syntax will be rejected.
- */
-static virJSONValuePtr
-virStorageSourceParseBackingJSONDeflatten(virJSONValuePtr json)
-{
- virJSONValuePtr ret;
-
- if (!(ret = virJSONValueNewObject()))
- return NULL;
-
- if (virJSONValueObjectForeachKeyValue(json,
-
virStorageSourceParseBackingJSONDeflattenWorker,
- ret) < 0) {
- virJSONValueFree(ret);
- return NULL;
- }
-
- return ret;
-}
-
static int
virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
@@ -3320,7 +3257,7 @@ virStorageSourceParseBackingJSONInternal(virStorageSourcePtr src,
int ret = -1;
if (!(file = virJSONValueObjectGetObject(json, "file"))) {
- if (!(fixedroot = virStorageSourceParseBackingJSONDeflatten(json)))
+ if (!(fixedroot = virJSONValueObjectDeflatten(json)))
goto cleanup;
file = fixedroot;
--
2.12.2