10bcc8e5bSMarkus Armbruster /*
20bcc8e5bSMarkus Armbruster * Special QDict functions used by the block layer
30bcc8e5bSMarkus Armbruster *
40bcc8e5bSMarkus Armbruster * Copyright (c) 2013-2018 Red Hat, Inc.
50bcc8e5bSMarkus Armbruster *
60bcc8e5bSMarkus Armbruster * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
70bcc8e5bSMarkus Armbruster * See the COPYING.LIB file in the top-level directory.
80bcc8e5bSMarkus Armbruster */
90bcc8e5bSMarkus Armbruster
100bcc8e5bSMarkus Armbruster #include "qemu/osdep.h"
110bcc8e5bSMarkus Armbruster #include "block/qdict.h"
12e5af0da1SMarkus Armbruster #include "qapi/qmp/qbool.h"
130bcc8e5bSMarkus Armbruster #include "qapi/qmp/qlist.h"
14e5af0da1SMarkus Armbruster #include "qapi/qmp/qnum.h"
15e5af0da1SMarkus Armbruster #include "qapi/qmp/qstring.h"
16af91062eSMarkus Armbruster #include "qapi/qobject-input-visitor.h"
170bcc8e5bSMarkus Armbruster #include "qemu/cutils.h"
180bcc8e5bSMarkus Armbruster #include "qapi/error.h"
190bcc8e5bSMarkus Armbruster
200bcc8e5bSMarkus Armbruster /**
210bcc8e5bSMarkus Armbruster * qdict_copy_default(): If no entry mapped by 'key' exists in 'dst' yet, the
220bcc8e5bSMarkus Armbruster * value of 'key' in 'src' is copied there (and the refcount increased
230bcc8e5bSMarkus Armbruster * accordingly).
240bcc8e5bSMarkus Armbruster */
qdict_copy_default(QDict * dst,QDict * src,const char * key)250bcc8e5bSMarkus Armbruster void qdict_copy_default(QDict *dst, QDict *src, const char *key)
260bcc8e5bSMarkus Armbruster {
270bcc8e5bSMarkus Armbruster QObject *val;
280bcc8e5bSMarkus Armbruster
290bcc8e5bSMarkus Armbruster if (qdict_haskey(dst, key)) {
300bcc8e5bSMarkus Armbruster return;
310bcc8e5bSMarkus Armbruster }
320bcc8e5bSMarkus Armbruster
330bcc8e5bSMarkus Armbruster val = qdict_get(src, key);
340bcc8e5bSMarkus Armbruster if (val) {
350bcc8e5bSMarkus Armbruster qdict_put_obj(dst, key, qobject_ref(val));
360bcc8e5bSMarkus Armbruster }
370bcc8e5bSMarkus Armbruster }
380bcc8e5bSMarkus Armbruster
390bcc8e5bSMarkus Armbruster /**
400bcc8e5bSMarkus Armbruster * qdict_set_default_str(): If no entry mapped by 'key' exists in 'dst' yet, a
410bcc8e5bSMarkus Armbruster * new QString initialised by 'val' is put there.
420bcc8e5bSMarkus Armbruster */
qdict_set_default_str(QDict * dst,const char * key,const char * val)430bcc8e5bSMarkus Armbruster void qdict_set_default_str(QDict *dst, const char *key, const char *val)
440bcc8e5bSMarkus Armbruster {
450bcc8e5bSMarkus Armbruster if (qdict_haskey(dst, key)) {
460bcc8e5bSMarkus Armbruster return;
470bcc8e5bSMarkus Armbruster }
480bcc8e5bSMarkus Armbruster
490bcc8e5bSMarkus Armbruster qdict_put_str(dst, key, val);
500bcc8e5bSMarkus Armbruster }
510bcc8e5bSMarkus Armbruster
520bcc8e5bSMarkus Armbruster static void qdict_flatten_qdict(QDict *qdict, QDict *target,
530bcc8e5bSMarkus Armbruster const char *prefix);
540bcc8e5bSMarkus Armbruster
qdict_flatten_qlist(QList * qlist,QDict * target,const char * prefix)550bcc8e5bSMarkus Armbruster static void qdict_flatten_qlist(QList *qlist, QDict *target, const char *prefix)
560bcc8e5bSMarkus Armbruster {
570bcc8e5bSMarkus Armbruster QObject *value;
580bcc8e5bSMarkus Armbruster const QListEntry *entry;
592860b2b2SMarkus Armbruster QDict *dict_val;
602860b2b2SMarkus Armbruster QList *list_val;
610bcc8e5bSMarkus Armbruster char *new_key;
620bcc8e5bSMarkus Armbruster int i;
630bcc8e5bSMarkus Armbruster
640bcc8e5bSMarkus Armbruster /* This function is never called with prefix == NULL, i.e., it is always
650bcc8e5bSMarkus Armbruster * called from within qdict_flatten_q(list|dict)(). Therefore, it does not
660bcc8e5bSMarkus Armbruster * need to remove list entries during the iteration (the whole list will be
670bcc8e5bSMarkus Armbruster * deleted eventually anyway from qdict_flatten_qdict()). */
680bcc8e5bSMarkus Armbruster assert(prefix);
690bcc8e5bSMarkus Armbruster
700bcc8e5bSMarkus Armbruster entry = qlist_first(qlist);
710bcc8e5bSMarkus Armbruster
720bcc8e5bSMarkus Armbruster for (i = 0; entry; entry = qlist_next(entry), i++) {
730bcc8e5bSMarkus Armbruster value = qlist_entry_obj(entry);
742860b2b2SMarkus Armbruster dict_val = qobject_to(QDict, value);
752860b2b2SMarkus Armbruster list_val = qobject_to(QList, value);
760bcc8e5bSMarkus Armbruster new_key = g_strdup_printf("%s.%i", prefix, i);
770bcc8e5bSMarkus Armbruster
78f1b34a24SMarkus Armbruster /*
79f1b34a24SMarkus Armbruster * Flatten non-empty QDict and QList recursively into @target,
80f1b34a24SMarkus Armbruster * copy other objects to @target
81f1b34a24SMarkus Armbruster */
822860b2b2SMarkus Armbruster if (dict_val && qdict_size(dict_val)) {
832860b2b2SMarkus Armbruster qdict_flatten_qdict(dict_val, target, new_key);
842860b2b2SMarkus Armbruster } else if (list_val && !qlist_empty(list_val)) {
852860b2b2SMarkus Armbruster qdict_flatten_qlist(list_val, target, new_key);
860bcc8e5bSMarkus Armbruster } else {
870bcc8e5bSMarkus Armbruster qdict_put_obj(target, new_key, qobject_ref(value));
880bcc8e5bSMarkus Armbruster }
890bcc8e5bSMarkus Armbruster
900bcc8e5bSMarkus Armbruster g_free(new_key);
910bcc8e5bSMarkus Armbruster }
920bcc8e5bSMarkus Armbruster }
930bcc8e5bSMarkus Armbruster
qdict_flatten_qdict(QDict * qdict,QDict * target,const char * prefix)940bcc8e5bSMarkus Armbruster static void qdict_flatten_qdict(QDict *qdict, QDict *target, const char *prefix)
950bcc8e5bSMarkus Armbruster {
960bcc8e5bSMarkus Armbruster QObject *value;
970bcc8e5bSMarkus Armbruster const QDictEntry *entry, *next;
982860b2b2SMarkus Armbruster QDict *dict_val;
992860b2b2SMarkus Armbruster QList *list_val;
10017e9aa3fSMarkus Armbruster char *key, *new_key;
1010bcc8e5bSMarkus Armbruster
1020bcc8e5bSMarkus Armbruster entry = qdict_first(qdict);
1030bcc8e5bSMarkus Armbruster
1040bcc8e5bSMarkus Armbruster while (entry != NULL) {
1050bcc8e5bSMarkus Armbruster next = qdict_next(qdict, entry);
1060bcc8e5bSMarkus Armbruster value = qdict_entry_value(entry);
1072860b2b2SMarkus Armbruster dict_val = qobject_to(QDict, value);
1082860b2b2SMarkus Armbruster list_val = qobject_to(QList, value);
1090bcc8e5bSMarkus Armbruster
1100bcc8e5bSMarkus Armbruster if (prefix) {
11117e9aa3fSMarkus Armbruster key = new_key = g_strdup_printf("%s.%s", prefix, entry->key);
11217e9aa3fSMarkus Armbruster } else {
11317e9aa3fSMarkus Armbruster key = entry->key;
11417e9aa3fSMarkus Armbruster new_key = NULL;
1150bcc8e5bSMarkus Armbruster }
1160bcc8e5bSMarkus Armbruster
117f1b34a24SMarkus Armbruster /*
118f1b34a24SMarkus Armbruster * Flatten non-empty QDict and QList recursively into @target,
119bf6e6a37SMax Reitz * copy other objects to @target.
120bf6e6a37SMax Reitz * On the root level (if @qdict == @target), remove flattened
121bf6e6a37SMax Reitz * nested QDicts and QLists from @qdict.
122bf6e6a37SMax Reitz *
123bf6e6a37SMax Reitz * (Note that we do not need to remove entries from nested
124bf6e6a37SMax Reitz * dicts or lists. Their reference count is decremented on
125bf6e6a37SMax Reitz * the root level, so there are no leaks. In fact, if they
126bf6e6a37SMax Reitz * have a reference count greater than one, we are probably
127bf6e6a37SMax Reitz * well advised not to modify them altogether.)
128f1b34a24SMarkus Armbruster */
1292860b2b2SMarkus Armbruster if (dict_val && qdict_size(dict_val)) {
13017e9aa3fSMarkus Armbruster qdict_flatten_qdict(dict_val, target, key);
131bf6e6a37SMax Reitz if (target == qdict) {
132eb0e0f7dSMarkus Armbruster qdict_del(qdict, entry->key);
133bf6e6a37SMax Reitz }
1342860b2b2SMarkus Armbruster } else if (list_val && !qlist_empty(list_val)) {
13517e9aa3fSMarkus Armbruster qdict_flatten_qlist(list_val, target, key);
136bf6e6a37SMax Reitz if (target == qdict) {
137eb0e0f7dSMarkus Armbruster qdict_del(qdict, entry->key);
138bf6e6a37SMax Reitz }
139f1b34a24SMarkus Armbruster } else if (target != qdict) {
14017e9aa3fSMarkus Armbruster qdict_put_obj(target, key, qobject_ref(value));
1410bcc8e5bSMarkus Armbruster }
1420bcc8e5bSMarkus Armbruster
1430bcc8e5bSMarkus Armbruster g_free(new_key);
1440bcc8e5bSMarkus Armbruster entry = next;
1450bcc8e5bSMarkus Armbruster }
1460bcc8e5bSMarkus Armbruster }
1470bcc8e5bSMarkus Armbruster
1480bcc8e5bSMarkus Armbruster /**
1492860b2b2SMarkus Armbruster * qdict_flatten(): For each nested non-empty QDict with key x, all
1502860b2b2SMarkus Armbruster * fields with key y are moved to this QDict and their key is renamed
1512860b2b2SMarkus Armbruster * to "x.y". For each nested non-empty QList with key x, the field at
1522860b2b2SMarkus Armbruster * index y is moved to this QDict with the key "x.y" (i.e., the
1532860b2b2SMarkus Armbruster * reverse of what qdict_array_split() does).
1540bcc8e5bSMarkus Armbruster * This operation is applied recursively for nested QDicts and QLists.
1550bcc8e5bSMarkus Armbruster */
qdict_flatten(QDict * qdict)1560bcc8e5bSMarkus Armbruster void qdict_flatten(QDict *qdict)
1570bcc8e5bSMarkus Armbruster {
1580bcc8e5bSMarkus Armbruster qdict_flatten_qdict(qdict, qdict, NULL);
1590bcc8e5bSMarkus Armbruster }
1600bcc8e5bSMarkus Armbruster
161655b4b67SAlberto Garcia /* extract all the src QDict entries starting by start into dst.
162655b4b67SAlberto Garcia * If dst is NULL then the entries are simply removed from src. */
qdict_extract_subqdict(QDict * src,QDict ** dst,const char * start)1630bcc8e5bSMarkus Armbruster void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start)
1640bcc8e5bSMarkus Armbruster
1650bcc8e5bSMarkus Armbruster {
1660bcc8e5bSMarkus Armbruster const QDictEntry *entry, *next;
1670bcc8e5bSMarkus Armbruster const char *p;
1680bcc8e5bSMarkus Armbruster
169655b4b67SAlberto Garcia if (dst) {
1700bcc8e5bSMarkus Armbruster *dst = qdict_new();
171655b4b67SAlberto Garcia }
1720bcc8e5bSMarkus Armbruster entry = qdict_first(src);
1730bcc8e5bSMarkus Armbruster
1740bcc8e5bSMarkus Armbruster while (entry != NULL) {
1750bcc8e5bSMarkus Armbruster next = qdict_next(src, entry);
1760bcc8e5bSMarkus Armbruster if (strstart(entry->key, start, &p)) {
177655b4b67SAlberto Garcia if (dst) {
1780bcc8e5bSMarkus Armbruster qdict_put_obj(*dst, p, qobject_ref(entry->value));
179655b4b67SAlberto Garcia }
1800bcc8e5bSMarkus Armbruster qdict_del(src, entry->key);
1810bcc8e5bSMarkus Armbruster }
1820bcc8e5bSMarkus Armbruster entry = next;
1830bcc8e5bSMarkus Armbruster }
1840bcc8e5bSMarkus Armbruster }
1850bcc8e5bSMarkus Armbruster
qdict_count_prefixed_entries(const QDict * src,const char * start)1860bcc8e5bSMarkus Armbruster static int qdict_count_prefixed_entries(const QDict *src, const char *start)
1870bcc8e5bSMarkus Armbruster {
1880bcc8e5bSMarkus Armbruster const QDictEntry *entry;
1890bcc8e5bSMarkus Armbruster int count = 0;
1900bcc8e5bSMarkus Armbruster
1910bcc8e5bSMarkus Armbruster for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) {
1920bcc8e5bSMarkus Armbruster if (strstart(entry->key, start, NULL)) {
1930bcc8e5bSMarkus Armbruster if (count == INT_MAX) {
1940bcc8e5bSMarkus Armbruster return -ERANGE;
1950bcc8e5bSMarkus Armbruster }
1960bcc8e5bSMarkus Armbruster count++;
1970bcc8e5bSMarkus Armbruster }
1980bcc8e5bSMarkus Armbruster }
1990bcc8e5bSMarkus Armbruster
2000bcc8e5bSMarkus Armbruster return count;
2010bcc8e5bSMarkus Armbruster }
2020bcc8e5bSMarkus Armbruster
2030bcc8e5bSMarkus Armbruster /**
2040bcc8e5bSMarkus Armbruster * qdict_array_split(): This function moves array-like elements of a QDict into
2050bcc8e5bSMarkus Armbruster * a new QList. Every entry in the original QDict with a key "%u" or one
2060bcc8e5bSMarkus Armbruster * prefixed "%u.", where %u designates an unsigned integer starting at 0 and
2070bcc8e5bSMarkus Armbruster * incrementally counting up, will be moved to a new QDict at index %u in the
2080bcc8e5bSMarkus Armbruster * output QList with the key prefix removed, if that prefix is "%u.". If the
2090bcc8e5bSMarkus Armbruster * whole key is just "%u", the whole QObject will be moved unchanged without
2100bcc8e5bSMarkus Armbruster * creating a new QDict. The function terminates when there is no entry in the
2110bcc8e5bSMarkus Armbruster * QDict with a prefix directly (incrementally) following the last one; it also
2120bcc8e5bSMarkus Armbruster * returns if there are both entries with "%u" and "%u." for the same index %u.
2130bcc8e5bSMarkus Armbruster * Example: {"0.a": 42, "0.b": 23, "1.x": 0, "4.y": 1, "o.o": 7, "2": 66}
2140bcc8e5bSMarkus Armbruster * (or {"1.x": 0, "4.y": 1, "0.a": 42, "o.o": 7, "0.b": 23, "2": 66})
2150bcc8e5bSMarkus Armbruster * => [{"a": 42, "b": 23}, {"x": 0}, 66]
2160bcc8e5bSMarkus Armbruster * and {"4.y": 1, "o.o": 7} (remainder of the old QDict)
2170bcc8e5bSMarkus Armbruster */
qdict_array_split(QDict * src,QList ** dst)2180bcc8e5bSMarkus Armbruster void qdict_array_split(QDict *src, QList **dst)
2190bcc8e5bSMarkus Armbruster {
2200bcc8e5bSMarkus Armbruster unsigned i;
2210bcc8e5bSMarkus Armbruster
2220bcc8e5bSMarkus Armbruster *dst = qlist_new();
2230bcc8e5bSMarkus Armbruster
2240bcc8e5bSMarkus Armbruster for (i = 0; i < UINT_MAX; i++) {
2250bcc8e5bSMarkus Armbruster QObject *subqobj;
2260bcc8e5bSMarkus Armbruster bool is_subqdict;
2270bcc8e5bSMarkus Armbruster QDict *subqdict;
2280bcc8e5bSMarkus Armbruster char indexstr[32], prefix[32];
2290bcc8e5bSMarkus Armbruster size_t snprintf_ret;
2300bcc8e5bSMarkus Armbruster
2310bcc8e5bSMarkus Armbruster snprintf_ret = snprintf(indexstr, 32, "%u", i);
2320bcc8e5bSMarkus Armbruster assert(snprintf_ret < 32);
2330bcc8e5bSMarkus Armbruster
2340bcc8e5bSMarkus Armbruster subqobj = qdict_get(src, indexstr);
2350bcc8e5bSMarkus Armbruster
2360bcc8e5bSMarkus Armbruster snprintf_ret = snprintf(prefix, 32, "%u.", i);
2370bcc8e5bSMarkus Armbruster assert(snprintf_ret < 32);
2380bcc8e5bSMarkus Armbruster
2390bcc8e5bSMarkus Armbruster /* Overflow is the same as positive non-zero results */
2400bcc8e5bSMarkus Armbruster is_subqdict = qdict_count_prefixed_entries(src, prefix);
2410bcc8e5bSMarkus Armbruster
2420bcc8e5bSMarkus Armbruster /*
2430bcc8e5bSMarkus Armbruster * There may be either a single subordinate object (named
2440bcc8e5bSMarkus Armbruster * "%u") or multiple objects (each with a key prefixed "%u."),
2450bcc8e5bSMarkus Armbruster * but not both.
2460bcc8e5bSMarkus Armbruster */
2470bcc8e5bSMarkus Armbruster if (!subqobj == !is_subqdict) {
2480bcc8e5bSMarkus Armbruster break;
2490bcc8e5bSMarkus Armbruster }
2500bcc8e5bSMarkus Armbruster
2510bcc8e5bSMarkus Armbruster if (is_subqdict) {
2520bcc8e5bSMarkus Armbruster qdict_extract_subqdict(src, &subqdict, prefix);
2530bcc8e5bSMarkus Armbruster assert(qdict_size(subqdict) > 0);
254*79854b95SMurilo Opsfelder Araujo qlist_append_obj(*dst, QOBJECT(subqdict));
2550bcc8e5bSMarkus Armbruster } else {
2560bcc8e5bSMarkus Armbruster qobject_ref(subqobj);
2570bcc8e5bSMarkus Armbruster qdict_del(src, indexstr);
258*79854b95SMurilo Opsfelder Araujo qlist_append_obj(*dst, subqobj);
2590bcc8e5bSMarkus Armbruster }
2600bcc8e5bSMarkus Armbruster }
2610bcc8e5bSMarkus Armbruster }
2620bcc8e5bSMarkus Armbruster
2630bcc8e5bSMarkus Armbruster /**
2640bcc8e5bSMarkus Armbruster * qdict_split_flat_key:
2650bcc8e5bSMarkus Armbruster * @key: the key string to split
2660bcc8e5bSMarkus Armbruster * @prefix: non-NULL pointer to hold extracted prefix
2670bcc8e5bSMarkus Armbruster * @suffix: non-NULL pointer to remaining suffix
2680bcc8e5bSMarkus Armbruster *
2690bcc8e5bSMarkus Armbruster * Given a flattened key such as 'foo.0.bar', split it into two parts
2700bcc8e5bSMarkus Armbruster * at the first '.' separator. Allows double dot ('..') to escape the
2710bcc8e5bSMarkus Armbruster * normal separator.
2720bcc8e5bSMarkus Armbruster *
2730bcc8e5bSMarkus Armbruster * e.g.
2740bcc8e5bSMarkus Armbruster * 'foo.0.bar' -> prefix='foo' and suffix='0.bar'
2750bcc8e5bSMarkus Armbruster * 'foo..0.bar' -> prefix='foo.0' and suffix='bar'
2760bcc8e5bSMarkus Armbruster *
2770bcc8e5bSMarkus Armbruster * The '..' sequence will be unescaped in the returned 'prefix'
2780bcc8e5bSMarkus Armbruster * string. The 'suffix' string will be left in escaped format, so it
2790bcc8e5bSMarkus Armbruster * can be fed back into the qdict_split_flat_key() key as the input
2800bcc8e5bSMarkus Armbruster * later.
2810bcc8e5bSMarkus Armbruster *
2820bcc8e5bSMarkus Armbruster * The caller is responsible for freeing the string returned in @prefix
2830bcc8e5bSMarkus Armbruster * using g_free().
2840bcc8e5bSMarkus Armbruster */
qdict_split_flat_key(const char * key,char ** prefix,const char ** suffix)2850bcc8e5bSMarkus Armbruster static void qdict_split_flat_key(const char *key, char **prefix,
2860bcc8e5bSMarkus Armbruster const char **suffix)
2870bcc8e5bSMarkus Armbruster {
2880bcc8e5bSMarkus Armbruster const char *separator;
2890bcc8e5bSMarkus Armbruster size_t i, j;
2900bcc8e5bSMarkus Armbruster
2910bcc8e5bSMarkus Armbruster /* Find first '.' separator, but if there is a pair '..'
2920bcc8e5bSMarkus Armbruster * that acts as an escape, so skip over '..' */
2930bcc8e5bSMarkus Armbruster separator = NULL;
2940bcc8e5bSMarkus Armbruster do {
2950bcc8e5bSMarkus Armbruster if (separator) {
2960bcc8e5bSMarkus Armbruster separator += 2;
2970bcc8e5bSMarkus Armbruster } else {
2980bcc8e5bSMarkus Armbruster separator = key;
2990bcc8e5bSMarkus Armbruster }
3000bcc8e5bSMarkus Armbruster separator = strchr(separator, '.');
3010bcc8e5bSMarkus Armbruster } while (separator && separator[1] == '.');
3020bcc8e5bSMarkus Armbruster
3030bcc8e5bSMarkus Armbruster if (separator) {
3040bcc8e5bSMarkus Armbruster *prefix = g_strndup(key, separator - key);
3050bcc8e5bSMarkus Armbruster *suffix = separator + 1;
3060bcc8e5bSMarkus Armbruster } else {
3070bcc8e5bSMarkus Armbruster *prefix = g_strdup(key);
3080bcc8e5bSMarkus Armbruster *suffix = NULL;
3090bcc8e5bSMarkus Armbruster }
3100bcc8e5bSMarkus Armbruster
3110bcc8e5bSMarkus Armbruster /* Unescape the '..' sequence into '.' */
3120bcc8e5bSMarkus Armbruster for (i = 0, j = 0; (*prefix)[i] != '\0'; i++, j++) {
3130bcc8e5bSMarkus Armbruster if ((*prefix)[i] == '.') {
3140bcc8e5bSMarkus Armbruster assert((*prefix)[i + 1] == '.');
3150bcc8e5bSMarkus Armbruster i++;
3160bcc8e5bSMarkus Armbruster }
3170bcc8e5bSMarkus Armbruster (*prefix)[j] = (*prefix)[i];
3180bcc8e5bSMarkus Armbruster }
3190bcc8e5bSMarkus Armbruster (*prefix)[j] = '\0';
3200bcc8e5bSMarkus Armbruster }
3210bcc8e5bSMarkus Armbruster
3220bcc8e5bSMarkus Armbruster /**
3230bcc8e5bSMarkus Armbruster * qdict_is_list:
3240bcc8e5bSMarkus Armbruster * @maybe_list: dict to check if keys represent list elements.
3250bcc8e5bSMarkus Armbruster *
3260bcc8e5bSMarkus Armbruster * Determine whether all keys in @maybe_list are valid list elements.
3270bcc8e5bSMarkus Armbruster * If @maybe_list is non-zero in length and all the keys look like
3280bcc8e5bSMarkus Armbruster * valid list indexes, this will return 1. If @maybe_list is zero
3290bcc8e5bSMarkus Armbruster * length or all keys are non-numeric then it will return 0 to indicate
3300bcc8e5bSMarkus Armbruster * it is a normal qdict. If there is a mix of numeric and non-numeric
3310bcc8e5bSMarkus Armbruster * keys, or the list indexes are non-contiguous, an error is reported.
3320bcc8e5bSMarkus Armbruster *
3330bcc8e5bSMarkus Armbruster * Returns: 1 if a valid list, 0 if a dict, -1 on error
3340bcc8e5bSMarkus Armbruster */
qdict_is_list(QDict * maybe_list,Error ** errp)3350bcc8e5bSMarkus Armbruster static int qdict_is_list(QDict *maybe_list, Error **errp)
3360bcc8e5bSMarkus Armbruster {
3370bcc8e5bSMarkus Armbruster const QDictEntry *ent;
3380bcc8e5bSMarkus Armbruster ssize_t len = 0;
3390bcc8e5bSMarkus Armbruster ssize_t max = -1;
3400bcc8e5bSMarkus Armbruster int is_list = -1;
3410bcc8e5bSMarkus Armbruster int64_t val;
3420bcc8e5bSMarkus Armbruster
3430bcc8e5bSMarkus Armbruster for (ent = qdict_first(maybe_list); ent != NULL;
3440bcc8e5bSMarkus Armbruster ent = qdict_next(maybe_list, ent)) {
345c78b8cfbSMarkus Armbruster int is_index = !qemu_strtoi64(ent->key, NULL, 10, &val);
3460bcc8e5bSMarkus Armbruster
3470bcc8e5bSMarkus Armbruster if (is_list == -1) {
348c78b8cfbSMarkus Armbruster is_list = is_index;
349c78b8cfbSMarkus Armbruster }
350c78b8cfbSMarkus Armbruster
351c78b8cfbSMarkus Armbruster if (is_index != is_list) {
352c78b8cfbSMarkus Armbruster error_setg(errp, "Cannot mix list and non-list keys");
3530bcc8e5bSMarkus Armbruster return -1;
3540bcc8e5bSMarkus Armbruster }
355c78b8cfbSMarkus Armbruster
356c78b8cfbSMarkus Armbruster if (is_index) {
3570bcc8e5bSMarkus Armbruster len++;
3580bcc8e5bSMarkus Armbruster if (val > max) {
3590bcc8e5bSMarkus Armbruster max = val;
3600bcc8e5bSMarkus Armbruster }
3610bcc8e5bSMarkus Armbruster }
3620bcc8e5bSMarkus Armbruster }
3630bcc8e5bSMarkus Armbruster
3640bcc8e5bSMarkus Armbruster if (is_list == -1) {
3650bcc8e5bSMarkus Armbruster assert(!qdict_size(maybe_list));
3660bcc8e5bSMarkus Armbruster is_list = 0;
3670bcc8e5bSMarkus Armbruster }
3680bcc8e5bSMarkus Armbruster
3690bcc8e5bSMarkus Armbruster /* NB this isn't a perfect check - e.g. it won't catch
3700bcc8e5bSMarkus Armbruster * a list containing '1', '+1', '01', '3', but that
3710bcc8e5bSMarkus Armbruster * does not matter - we've still proved that the
3720bcc8e5bSMarkus Armbruster * input is a list. It is up the caller to do a
3730bcc8e5bSMarkus Armbruster * stricter check if desired */
3740bcc8e5bSMarkus Armbruster if (len != (max + 1)) {
3750bcc8e5bSMarkus Armbruster error_setg(errp, "List indices are not contiguous, "
3760bcc8e5bSMarkus Armbruster "saw %zd elements but %zd largest index",
3770bcc8e5bSMarkus Armbruster len, max);
3780bcc8e5bSMarkus Armbruster return -1;
3790bcc8e5bSMarkus Armbruster }
3800bcc8e5bSMarkus Armbruster
3810bcc8e5bSMarkus Armbruster return is_list;
3820bcc8e5bSMarkus Armbruster }
3830bcc8e5bSMarkus Armbruster
3840bcc8e5bSMarkus Armbruster /**
3850bcc8e5bSMarkus Armbruster * qdict_crumple:
3860bcc8e5bSMarkus Armbruster * @src: the original flat dictionary (only scalar values) to crumple
3870bcc8e5bSMarkus Armbruster *
3880bcc8e5bSMarkus Armbruster * Takes a flat dictionary whose keys use '.' separator to indicate
3892860b2b2SMarkus Armbruster * nesting, and values are scalars, empty dictionaries or empty lists,
3902860b2b2SMarkus Armbruster * and crumples it into a nested structure.
3910bcc8e5bSMarkus Armbruster *
3920bcc8e5bSMarkus Armbruster * To include a literal '.' in a key name, it must be escaped as '..'
3930bcc8e5bSMarkus Armbruster *
3940bcc8e5bSMarkus Armbruster * For example, an input of:
3950bcc8e5bSMarkus Armbruster *
3960bcc8e5bSMarkus Armbruster * { 'foo.0.bar': 'one', 'foo.0.wizz': '1',
3970bcc8e5bSMarkus Armbruster * 'foo.1.bar': 'two', 'foo.1.wizz': '2' }
3980bcc8e5bSMarkus Armbruster *
3990bcc8e5bSMarkus Armbruster * will result in an output of:
4000bcc8e5bSMarkus Armbruster *
4010bcc8e5bSMarkus Armbruster * {
4020bcc8e5bSMarkus Armbruster * 'foo': [
4030bcc8e5bSMarkus Armbruster * { 'bar': 'one', 'wizz': '1' },
4040bcc8e5bSMarkus Armbruster * { 'bar': 'two', 'wizz': '2' }
4050bcc8e5bSMarkus Armbruster * ],
4060bcc8e5bSMarkus Armbruster * }
4070bcc8e5bSMarkus Armbruster *
4080bcc8e5bSMarkus Armbruster * The following scenarios in the input dict will result in an
4090bcc8e5bSMarkus Armbruster * error being returned:
4100bcc8e5bSMarkus Armbruster *
4110bcc8e5bSMarkus Armbruster * - Any values in @src are non-scalar types
4120bcc8e5bSMarkus Armbruster * - If keys in @src imply that a particular level is both a
4130bcc8e5bSMarkus Armbruster * list and a dict. e.g., "foo.0.bar" and "foo.eek.bar".
4140bcc8e5bSMarkus Armbruster * - If keys in @src imply that a particular level is a list,
4150bcc8e5bSMarkus Armbruster * but the indices are non-contiguous. e.g. "foo.0.bar" and
4160bcc8e5bSMarkus Armbruster * "foo.2.bar" without any "foo.1.bar" present.
4170bcc8e5bSMarkus Armbruster * - If keys in @src represent list indexes, but are not in
4180bcc8e5bSMarkus Armbruster * the "%zu" format. e.g. "foo.+0.bar"
4190bcc8e5bSMarkus Armbruster *
4200bcc8e5bSMarkus Armbruster * Returns: either a QDict or QList for the nested data structure, or NULL
4210bcc8e5bSMarkus Armbruster * on error
4220bcc8e5bSMarkus Armbruster */
qdict_crumple(const QDict * src,Error ** errp)4230bcc8e5bSMarkus Armbruster QObject *qdict_crumple(const QDict *src, Error **errp)
4240bcc8e5bSMarkus Armbruster {
4250bcc8e5bSMarkus Armbruster const QDictEntry *ent;
4263692b5d7SMarkus Armbruster QDict *two_level, *multi_level = NULL, *child_dict;
4272860b2b2SMarkus Armbruster QDict *dict_val;
4282860b2b2SMarkus Armbruster QList *list_val;
4290bcc8e5bSMarkus Armbruster QObject *dst = NULL, *child;
4300bcc8e5bSMarkus Armbruster size_t i;
4310bcc8e5bSMarkus Armbruster char *prefix = NULL;
4320bcc8e5bSMarkus Armbruster const char *suffix = NULL;
4330bcc8e5bSMarkus Armbruster int is_list;
4340bcc8e5bSMarkus Armbruster
4350bcc8e5bSMarkus Armbruster two_level = qdict_new();
4360bcc8e5bSMarkus Armbruster
4370bcc8e5bSMarkus Armbruster /* Step 1: split our totally flat dict into a two level dict */
4380bcc8e5bSMarkus Armbruster for (ent = qdict_first(src); ent != NULL; ent = qdict_next(src, ent)) {
4392860b2b2SMarkus Armbruster dict_val = qobject_to(QDict, ent->value);
4402860b2b2SMarkus Armbruster list_val = qobject_to(QList, ent->value);
4412860b2b2SMarkus Armbruster if ((dict_val && qdict_size(dict_val))
4422860b2b2SMarkus Armbruster || (list_val && !qlist_empty(list_val))) {
4432860b2b2SMarkus Armbruster error_setg(errp, "Value %s is not flat", ent->key);
4440bcc8e5bSMarkus Armbruster goto error;
4450bcc8e5bSMarkus Armbruster }
4460bcc8e5bSMarkus Armbruster
4470bcc8e5bSMarkus Armbruster qdict_split_flat_key(ent->key, &prefix, &suffix);
4480bcc8e5bSMarkus Armbruster child = qdict_get(two_level, prefix);
4493692b5d7SMarkus Armbruster child_dict = qobject_to(QDict, child);
4503692b5d7SMarkus Armbruster
4510bcc8e5bSMarkus Armbruster if (child) {
4523692b5d7SMarkus Armbruster /*
4533692b5d7SMarkus Armbruster * If @child_dict, then all previous keys with this prefix
4543692b5d7SMarkus Armbruster * had a suffix. If @suffix, this one has one as well,
4553692b5d7SMarkus Armbruster * and we're good, else there's a clash.
4563692b5d7SMarkus Armbruster */
4573692b5d7SMarkus Armbruster if (!child_dict || !suffix) {
4583692b5d7SMarkus Armbruster error_setg(errp, "Cannot mix scalar and non-scalar keys");
4590bcc8e5bSMarkus Armbruster goto error;
4600bcc8e5bSMarkus Armbruster }
4610bcc8e5bSMarkus Armbruster }
4620bcc8e5bSMarkus Armbruster
4633692b5d7SMarkus Armbruster if (suffix) {
4643692b5d7SMarkus Armbruster if (!child_dict) {
4653692b5d7SMarkus Armbruster child_dict = qdict_new();
4663692b5d7SMarkus Armbruster qdict_put(two_level, prefix, child_dict);
4673692b5d7SMarkus Armbruster }
4680bcc8e5bSMarkus Armbruster qdict_put_obj(child_dict, suffix, qobject_ref(ent->value));
4690bcc8e5bSMarkus Armbruster } else {
4700bcc8e5bSMarkus Armbruster qdict_put_obj(two_level, prefix, qobject_ref(ent->value));
4710bcc8e5bSMarkus Armbruster }
4720bcc8e5bSMarkus Armbruster
4730bcc8e5bSMarkus Armbruster g_free(prefix);
4740bcc8e5bSMarkus Armbruster prefix = NULL;
4750bcc8e5bSMarkus Armbruster }
4760bcc8e5bSMarkus Armbruster
4770bcc8e5bSMarkus Armbruster /* Step 2: optionally process the two level dict recursively
4780bcc8e5bSMarkus Armbruster * into a multi-level dict */
4790bcc8e5bSMarkus Armbruster multi_level = qdict_new();
4800bcc8e5bSMarkus Armbruster for (ent = qdict_first(two_level); ent != NULL;
4810bcc8e5bSMarkus Armbruster ent = qdict_next(two_level, ent)) {
4822860b2b2SMarkus Armbruster dict_val = qobject_to(QDict, ent->value);
4832860b2b2SMarkus Armbruster if (dict_val && qdict_size(dict_val)) {
4842860b2b2SMarkus Armbruster child = qdict_crumple(dict_val, errp);
4850bcc8e5bSMarkus Armbruster if (!child) {
4860bcc8e5bSMarkus Armbruster goto error;
4870bcc8e5bSMarkus Armbruster }
4880bcc8e5bSMarkus Armbruster
4890bcc8e5bSMarkus Armbruster qdict_put_obj(multi_level, ent->key, child);
4900bcc8e5bSMarkus Armbruster } else {
4910bcc8e5bSMarkus Armbruster qdict_put_obj(multi_level, ent->key, qobject_ref(ent->value));
4920bcc8e5bSMarkus Armbruster }
4930bcc8e5bSMarkus Armbruster }
4940bcc8e5bSMarkus Armbruster qobject_unref(two_level);
4950bcc8e5bSMarkus Armbruster two_level = NULL;
4960bcc8e5bSMarkus Armbruster
4970bcc8e5bSMarkus Armbruster /* Step 3: detect if we need to turn our dict into list */
4980bcc8e5bSMarkus Armbruster is_list = qdict_is_list(multi_level, errp);
4990bcc8e5bSMarkus Armbruster if (is_list < 0) {
5000bcc8e5bSMarkus Armbruster goto error;
5010bcc8e5bSMarkus Armbruster }
5020bcc8e5bSMarkus Armbruster
5030bcc8e5bSMarkus Armbruster if (is_list) {
5040bcc8e5bSMarkus Armbruster dst = QOBJECT(qlist_new());
5050bcc8e5bSMarkus Armbruster
5060bcc8e5bSMarkus Armbruster for (i = 0; i < qdict_size(multi_level); i++) {
5070bcc8e5bSMarkus Armbruster char *key = g_strdup_printf("%zu", i);
5080bcc8e5bSMarkus Armbruster
5090bcc8e5bSMarkus Armbruster child = qdict_get(multi_level, key);
5100bcc8e5bSMarkus Armbruster g_free(key);
5110bcc8e5bSMarkus Armbruster
5120bcc8e5bSMarkus Armbruster if (!child) {
5130bcc8e5bSMarkus Armbruster error_setg(errp, "Missing list index %zu", i);
5140bcc8e5bSMarkus Armbruster goto error;
5150bcc8e5bSMarkus Armbruster }
5160bcc8e5bSMarkus Armbruster
5170bcc8e5bSMarkus Armbruster qlist_append_obj(qobject_to(QList, dst), qobject_ref(child));
5180bcc8e5bSMarkus Armbruster }
5190bcc8e5bSMarkus Armbruster qobject_unref(multi_level);
5200bcc8e5bSMarkus Armbruster multi_level = NULL;
5210bcc8e5bSMarkus Armbruster } else {
5220bcc8e5bSMarkus Armbruster dst = QOBJECT(multi_level);
5230bcc8e5bSMarkus Armbruster }
5240bcc8e5bSMarkus Armbruster
5250bcc8e5bSMarkus Armbruster return dst;
5260bcc8e5bSMarkus Armbruster
5270bcc8e5bSMarkus Armbruster error:
5280bcc8e5bSMarkus Armbruster g_free(prefix);
5290bcc8e5bSMarkus Armbruster qobject_unref(multi_level);
5300bcc8e5bSMarkus Armbruster qobject_unref(two_level);
5310bcc8e5bSMarkus Armbruster qobject_unref(dst);
5320bcc8e5bSMarkus Armbruster return NULL;
5330bcc8e5bSMarkus Armbruster }
5340bcc8e5bSMarkus Armbruster
5350bcc8e5bSMarkus Armbruster /**
536e5af0da1SMarkus Armbruster * qdict_crumple_for_keyval_qiv:
537e5af0da1SMarkus Armbruster * @src: the flat dictionary (only scalar values) to crumple
538e5af0da1SMarkus Armbruster * @errp: location to store error
539e5af0da1SMarkus Armbruster *
540e5af0da1SMarkus Armbruster * Like qdict_crumple(), but additionally transforms scalar values so
541e5af0da1SMarkus Armbruster * the result can be passed to qobject_input_visitor_new_keyval().
542e5af0da1SMarkus Armbruster *
543e5af0da1SMarkus Armbruster * The block subsystem uses this function to prepare its flat QDict
544e5af0da1SMarkus Armbruster * with possibly confused scalar types for a visit. It should not be
545e5af0da1SMarkus Armbruster * used for anything else, and it should go away once the block
546e5af0da1SMarkus Armbruster * subsystem has been cleaned up.
547e5af0da1SMarkus Armbruster */
qdict_crumple_for_keyval_qiv(QDict * src,Error ** errp)548af91062eSMarkus Armbruster static QObject *qdict_crumple_for_keyval_qiv(QDict *src, Error **errp)
549e5af0da1SMarkus Armbruster {
550e5af0da1SMarkus Armbruster QDict *tmp = NULL;
551e5af0da1SMarkus Armbruster char *buf;
552e5af0da1SMarkus Armbruster const char *s;
553e5af0da1SMarkus Armbruster const QDictEntry *ent;
554e5af0da1SMarkus Armbruster QObject *dst;
555e5af0da1SMarkus Armbruster
556e5af0da1SMarkus Armbruster for (ent = qdict_first(src); ent; ent = qdict_next(src, ent)) {
557e5af0da1SMarkus Armbruster buf = NULL;
558e5af0da1SMarkus Armbruster switch (qobject_type(ent->value)) {
559e5af0da1SMarkus Armbruster case QTYPE_QNULL:
560e5af0da1SMarkus Armbruster case QTYPE_QSTRING:
561e5af0da1SMarkus Armbruster continue;
562e5af0da1SMarkus Armbruster case QTYPE_QNUM:
563e5af0da1SMarkus Armbruster s = buf = qnum_to_string(qobject_to(QNum, ent->value));
564e5af0da1SMarkus Armbruster break;
565e5af0da1SMarkus Armbruster case QTYPE_QDICT:
566e5af0da1SMarkus Armbruster case QTYPE_QLIST:
567e5af0da1SMarkus Armbruster /* @src isn't flat; qdict_crumple() will fail */
568e5af0da1SMarkus Armbruster continue;
569e5af0da1SMarkus Armbruster case QTYPE_QBOOL:
570e5af0da1SMarkus Armbruster s = qbool_get_bool(qobject_to(QBool, ent->value))
571e5af0da1SMarkus Armbruster ? "on" : "off";
572e5af0da1SMarkus Armbruster break;
573e5af0da1SMarkus Armbruster default:
574e5af0da1SMarkus Armbruster abort();
575e5af0da1SMarkus Armbruster }
576e5af0da1SMarkus Armbruster
577e5af0da1SMarkus Armbruster if (!tmp) {
578e5af0da1SMarkus Armbruster tmp = qdict_clone_shallow(src);
579e5af0da1SMarkus Armbruster }
58073969720SPhilippe Mathieu-Daudé qdict_put_str(tmp, ent->key, s);
581e5af0da1SMarkus Armbruster g_free(buf);
582e5af0da1SMarkus Armbruster }
583e5af0da1SMarkus Armbruster
584e5af0da1SMarkus Armbruster dst = qdict_crumple(tmp ?: src, errp);
585e5af0da1SMarkus Armbruster qobject_unref(tmp);
586e5af0da1SMarkus Armbruster return dst;
587e5af0da1SMarkus Armbruster }
588e5af0da1SMarkus Armbruster
589e5af0da1SMarkus Armbruster /**
5900bcc8e5bSMarkus Armbruster * qdict_array_entries(): Returns the number of direct array entries if the
5910bcc8e5bSMarkus Armbruster * sub-QDict of src specified by the prefix in subqdict (or src itself for
5920bcc8e5bSMarkus Armbruster * prefix == "") is valid as an array, i.e. the length of the created list if
5930bcc8e5bSMarkus Armbruster * the sub-QDict would become empty after calling qdict_array_split() on it. If
5940bcc8e5bSMarkus Armbruster * the array is not valid, -EINVAL is returned.
5950bcc8e5bSMarkus Armbruster */
qdict_array_entries(QDict * src,const char * subqdict)5960bcc8e5bSMarkus Armbruster int qdict_array_entries(QDict *src, const char *subqdict)
5970bcc8e5bSMarkus Armbruster {
5980bcc8e5bSMarkus Armbruster const QDictEntry *entry;
5990bcc8e5bSMarkus Armbruster unsigned i;
6000bcc8e5bSMarkus Armbruster unsigned entries = 0;
6010bcc8e5bSMarkus Armbruster size_t subqdict_len = strlen(subqdict);
6020bcc8e5bSMarkus Armbruster
6030bcc8e5bSMarkus Armbruster assert(!subqdict_len || subqdict[subqdict_len - 1] == '.');
6040bcc8e5bSMarkus Armbruster
6050bcc8e5bSMarkus Armbruster /* qdict_array_split() loops until UINT_MAX, but as we want to return
6060bcc8e5bSMarkus Armbruster * negative errors, we only have a signed return value here. Any additional
6070bcc8e5bSMarkus Armbruster * entries will lead to -EINVAL. */
6080bcc8e5bSMarkus Armbruster for (i = 0; i < INT_MAX; i++) {
6090bcc8e5bSMarkus Armbruster QObject *subqobj;
6100bcc8e5bSMarkus Armbruster int subqdict_entries;
6110bcc8e5bSMarkus Armbruster char *prefix = g_strdup_printf("%s%u.", subqdict, i);
6120bcc8e5bSMarkus Armbruster
6130bcc8e5bSMarkus Armbruster subqdict_entries = qdict_count_prefixed_entries(src, prefix);
6140bcc8e5bSMarkus Armbruster
6150bcc8e5bSMarkus Armbruster /* Remove ending "." */
6160bcc8e5bSMarkus Armbruster prefix[strlen(prefix) - 1] = 0;
6170bcc8e5bSMarkus Armbruster subqobj = qdict_get(src, prefix);
6180bcc8e5bSMarkus Armbruster
6190bcc8e5bSMarkus Armbruster g_free(prefix);
6200bcc8e5bSMarkus Armbruster
6210bcc8e5bSMarkus Armbruster if (subqdict_entries < 0) {
6220bcc8e5bSMarkus Armbruster return subqdict_entries;
6230bcc8e5bSMarkus Armbruster }
6240bcc8e5bSMarkus Armbruster
6250bcc8e5bSMarkus Armbruster /* There may be either a single subordinate object (named "%u") or
6260bcc8e5bSMarkus Armbruster * multiple objects (each with a key prefixed "%u."), but not both. */
6270bcc8e5bSMarkus Armbruster if (subqobj && subqdict_entries) {
6280bcc8e5bSMarkus Armbruster return -EINVAL;
6290bcc8e5bSMarkus Armbruster } else if (!subqobj && !subqdict_entries) {
6300bcc8e5bSMarkus Armbruster break;
6310bcc8e5bSMarkus Armbruster }
6320bcc8e5bSMarkus Armbruster
6330bcc8e5bSMarkus Armbruster entries += subqdict_entries ? subqdict_entries : 1;
6340bcc8e5bSMarkus Armbruster }
6350bcc8e5bSMarkus Armbruster
6360bcc8e5bSMarkus Armbruster /* Consider everything handled that isn't part of the given sub-QDict */
6370bcc8e5bSMarkus Armbruster for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) {
6380bcc8e5bSMarkus Armbruster if (!strstart(qdict_entry_key(entry), subqdict, NULL)) {
6390bcc8e5bSMarkus Armbruster entries++;
6400bcc8e5bSMarkus Armbruster }
6410bcc8e5bSMarkus Armbruster }
6420bcc8e5bSMarkus Armbruster
6430bcc8e5bSMarkus Armbruster /* Anything left in the sub-QDict that wasn't handled? */
6440bcc8e5bSMarkus Armbruster if (qdict_size(src) != entries) {
6450bcc8e5bSMarkus Armbruster return -EINVAL;
6460bcc8e5bSMarkus Armbruster }
6470bcc8e5bSMarkus Armbruster
6480bcc8e5bSMarkus Armbruster return i;
6490bcc8e5bSMarkus Armbruster }
6500bcc8e5bSMarkus Armbruster
6510bcc8e5bSMarkus Armbruster /**
6520bcc8e5bSMarkus Armbruster * qdict_join(): Absorb the src QDict into the dest QDict, that is, move all
6530bcc8e5bSMarkus Armbruster * elements from src to dest.
6540bcc8e5bSMarkus Armbruster *
6550bcc8e5bSMarkus Armbruster * If an element from src has a key already present in dest, it will not be
6560bcc8e5bSMarkus Armbruster * moved unless overwrite is true.
6570bcc8e5bSMarkus Armbruster *
6580bcc8e5bSMarkus Armbruster * If overwrite is true, the conflicting values in dest will be discarded and
6590bcc8e5bSMarkus Armbruster * replaced by the corresponding values from src.
6600bcc8e5bSMarkus Armbruster *
6610bcc8e5bSMarkus Armbruster * Therefore, with overwrite being true, the src QDict will always be empty when
6620bcc8e5bSMarkus Armbruster * this function returns. If overwrite is false, the src QDict will be empty
6630bcc8e5bSMarkus Armbruster * iff there were no conflicts.
6640bcc8e5bSMarkus Armbruster */
qdict_join(QDict * dest,QDict * src,bool overwrite)6650bcc8e5bSMarkus Armbruster void qdict_join(QDict *dest, QDict *src, bool overwrite)
6660bcc8e5bSMarkus Armbruster {
6670bcc8e5bSMarkus Armbruster const QDictEntry *entry, *next;
6680bcc8e5bSMarkus Armbruster
6690bcc8e5bSMarkus Armbruster entry = qdict_first(src);
6700bcc8e5bSMarkus Armbruster while (entry) {
6710bcc8e5bSMarkus Armbruster next = qdict_next(src, entry);
6720bcc8e5bSMarkus Armbruster
6730bcc8e5bSMarkus Armbruster if (overwrite || !qdict_haskey(dest, entry->key)) {
6740bcc8e5bSMarkus Armbruster qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
6750bcc8e5bSMarkus Armbruster qdict_del(src, entry->key);
6760bcc8e5bSMarkus Armbruster }
6770bcc8e5bSMarkus Armbruster
6780bcc8e5bSMarkus Armbruster entry = next;
6790bcc8e5bSMarkus Armbruster }
6800bcc8e5bSMarkus Armbruster }
6810bcc8e5bSMarkus Armbruster
6820bcc8e5bSMarkus Armbruster /**
6830bcc8e5bSMarkus Armbruster * qdict_rename_keys(): Rename keys in qdict according to the replacements
6840bcc8e5bSMarkus Armbruster * specified in the array renames. The array must be terminated by an entry
6850bcc8e5bSMarkus Armbruster * with from = NULL.
6860bcc8e5bSMarkus Armbruster *
6870bcc8e5bSMarkus Armbruster * The renames are performed individually in the order of the array, so entries
6880bcc8e5bSMarkus Armbruster * may be renamed multiple times and may or may not conflict depending on the
6890bcc8e5bSMarkus Armbruster * order of the renames array.
6900bcc8e5bSMarkus Armbruster *
6910bcc8e5bSMarkus Armbruster * Returns true for success, false in error cases.
6920bcc8e5bSMarkus Armbruster */
qdict_rename_keys(QDict * qdict,const QDictRenames * renames,Error ** errp)6930bcc8e5bSMarkus Armbruster bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp)
6940bcc8e5bSMarkus Armbruster {
6950bcc8e5bSMarkus Armbruster QObject *qobj;
6960bcc8e5bSMarkus Armbruster
6970bcc8e5bSMarkus Armbruster while (renames->from) {
6980bcc8e5bSMarkus Armbruster if (qdict_haskey(qdict, renames->from)) {
6990bcc8e5bSMarkus Armbruster if (qdict_haskey(qdict, renames->to)) {
7000bcc8e5bSMarkus Armbruster error_setg(errp, "'%s' and its alias '%s' can't be used at the "
7010bcc8e5bSMarkus Armbruster "same time", renames->to, renames->from);
7020bcc8e5bSMarkus Armbruster return false;
7030bcc8e5bSMarkus Armbruster }
7040bcc8e5bSMarkus Armbruster
7050bcc8e5bSMarkus Armbruster qobj = qdict_get(qdict, renames->from);
7060bcc8e5bSMarkus Armbruster qdict_put_obj(qdict, renames->to, qobject_ref(qobj));
7070bcc8e5bSMarkus Armbruster qdict_del(qdict, renames->from);
7080bcc8e5bSMarkus Armbruster }
7090bcc8e5bSMarkus Armbruster
7100bcc8e5bSMarkus Armbruster renames++;
7110bcc8e5bSMarkus Armbruster }
7120bcc8e5bSMarkus Armbruster return true;
7130bcc8e5bSMarkus Armbruster }
714af91062eSMarkus Armbruster
715af91062eSMarkus Armbruster /*
716af91062eSMarkus Armbruster * Create a QObject input visitor for flat @qdict with possibly
717af91062eSMarkus Armbruster * confused scalar types.
718af91062eSMarkus Armbruster *
719af91062eSMarkus Armbruster * The block subsystem uses this function to visit its flat QDict with
720af91062eSMarkus Armbruster * possibly confused scalar types. It should not be used for anything
721af91062eSMarkus Armbruster * else, and it should go away once the block subsystem has been
722af91062eSMarkus Armbruster * cleaned up.
723af91062eSMarkus Armbruster */
qobject_input_visitor_new_flat_confused(QDict * qdict,Error ** errp)724af91062eSMarkus Armbruster Visitor *qobject_input_visitor_new_flat_confused(QDict *qdict,
725af91062eSMarkus Armbruster Error **errp)
726af91062eSMarkus Armbruster {
727af91062eSMarkus Armbruster QObject *crumpled;
728af91062eSMarkus Armbruster Visitor *v;
729af91062eSMarkus Armbruster
730af91062eSMarkus Armbruster crumpled = qdict_crumple_for_keyval_qiv(qdict, errp);
731af91062eSMarkus Armbruster if (!crumpled) {
732af91062eSMarkus Armbruster return NULL;
733af91062eSMarkus Armbruster }
734af91062eSMarkus Armbruster
735af91062eSMarkus Armbruster v = qobject_input_visitor_new_keyval(crumpled);
736af91062eSMarkus Armbruster qobject_unref(crumpled);
737af91062eSMarkus Armbruster return v;
738af91062eSMarkus Armbruster }
739