xref: /qemu/qobject/block-qdict.c (revision e5af0da1dcbfb1a4694150f9954554fb6df88819)
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"
12*e5af0da1SMarkus Armbruster #include "qapi/qmp/qbool.h"
130bcc8e5bSMarkus Armbruster #include "qapi/qmp/qlist.h"
14*e5af0da1SMarkus Armbruster #include "qapi/qmp/qnum.h"
15*e5af0da1SMarkus Armbruster #include "qapi/qmp/qstring.h"
160bcc8e5bSMarkus Armbruster #include "qemu/cutils.h"
170bcc8e5bSMarkus Armbruster #include "qapi/error.h"
180bcc8e5bSMarkus Armbruster 
190bcc8e5bSMarkus Armbruster /**
200bcc8e5bSMarkus Armbruster  * qdict_copy_default(): If no entry mapped by 'key' exists in 'dst' yet, the
210bcc8e5bSMarkus Armbruster  * value of 'key' in 'src' is copied there (and the refcount increased
220bcc8e5bSMarkus Armbruster  * accordingly).
230bcc8e5bSMarkus Armbruster  */
240bcc8e5bSMarkus Armbruster void qdict_copy_default(QDict *dst, QDict *src, const char *key)
250bcc8e5bSMarkus Armbruster {
260bcc8e5bSMarkus Armbruster     QObject *val;
270bcc8e5bSMarkus Armbruster 
280bcc8e5bSMarkus Armbruster     if (qdict_haskey(dst, key)) {
290bcc8e5bSMarkus Armbruster         return;
300bcc8e5bSMarkus Armbruster     }
310bcc8e5bSMarkus Armbruster 
320bcc8e5bSMarkus Armbruster     val = qdict_get(src, key);
330bcc8e5bSMarkus Armbruster     if (val) {
340bcc8e5bSMarkus Armbruster         qdict_put_obj(dst, key, qobject_ref(val));
350bcc8e5bSMarkus Armbruster     }
360bcc8e5bSMarkus Armbruster }
370bcc8e5bSMarkus Armbruster 
380bcc8e5bSMarkus Armbruster /**
390bcc8e5bSMarkus Armbruster  * qdict_set_default_str(): If no entry mapped by 'key' exists in 'dst' yet, a
400bcc8e5bSMarkus Armbruster  * new QString initialised by 'val' is put there.
410bcc8e5bSMarkus Armbruster  */
420bcc8e5bSMarkus Armbruster void qdict_set_default_str(QDict *dst, const char *key, const char *val)
430bcc8e5bSMarkus Armbruster {
440bcc8e5bSMarkus Armbruster     if (qdict_haskey(dst, key)) {
450bcc8e5bSMarkus Armbruster         return;
460bcc8e5bSMarkus Armbruster     }
470bcc8e5bSMarkus Armbruster 
480bcc8e5bSMarkus Armbruster     qdict_put_str(dst, key, val);
490bcc8e5bSMarkus Armbruster }
500bcc8e5bSMarkus Armbruster 
510bcc8e5bSMarkus Armbruster static void qdict_flatten_qdict(QDict *qdict, QDict *target,
520bcc8e5bSMarkus Armbruster                                 const char *prefix);
530bcc8e5bSMarkus Armbruster 
540bcc8e5bSMarkus Armbruster static void qdict_flatten_qlist(QList *qlist, QDict *target, const char *prefix)
550bcc8e5bSMarkus Armbruster {
560bcc8e5bSMarkus Armbruster     QObject *value;
570bcc8e5bSMarkus Armbruster     const QListEntry *entry;
580bcc8e5bSMarkus Armbruster     char *new_key;
590bcc8e5bSMarkus Armbruster     int i;
600bcc8e5bSMarkus Armbruster 
610bcc8e5bSMarkus Armbruster     /* This function is never called with prefix == NULL, i.e., it is always
620bcc8e5bSMarkus Armbruster      * called from within qdict_flatten_q(list|dict)(). Therefore, it does not
630bcc8e5bSMarkus Armbruster      * need to remove list entries during the iteration (the whole list will be
640bcc8e5bSMarkus Armbruster      * deleted eventually anyway from qdict_flatten_qdict()). */
650bcc8e5bSMarkus Armbruster     assert(prefix);
660bcc8e5bSMarkus Armbruster 
670bcc8e5bSMarkus Armbruster     entry = qlist_first(qlist);
680bcc8e5bSMarkus Armbruster 
690bcc8e5bSMarkus Armbruster     for (i = 0; entry; entry = qlist_next(entry), i++) {
700bcc8e5bSMarkus Armbruster         value = qlist_entry_obj(entry);
710bcc8e5bSMarkus Armbruster         new_key = g_strdup_printf("%s.%i", prefix, i);
720bcc8e5bSMarkus Armbruster 
730bcc8e5bSMarkus Armbruster         if (qobject_type(value) == QTYPE_QDICT) {
740bcc8e5bSMarkus Armbruster             qdict_flatten_qdict(qobject_to(QDict, value), target, new_key);
750bcc8e5bSMarkus Armbruster         } else if (qobject_type(value) == QTYPE_QLIST) {
760bcc8e5bSMarkus Armbruster             qdict_flatten_qlist(qobject_to(QList, value), target, new_key);
770bcc8e5bSMarkus Armbruster         } else {
780bcc8e5bSMarkus Armbruster             /* All other types are moved to the target unchanged. */
790bcc8e5bSMarkus Armbruster             qdict_put_obj(target, new_key, qobject_ref(value));
800bcc8e5bSMarkus Armbruster         }
810bcc8e5bSMarkus Armbruster 
820bcc8e5bSMarkus Armbruster         g_free(new_key);
830bcc8e5bSMarkus Armbruster     }
840bcc8e5bSMarkus Armbruster }
850bcc8e5bSMarkus Armbruster 
860bcc8e5bSMarkus Armbruster static void qdict_flatten_qdict(QDict *qdict, QDict *target, const char *prefix)
870bcc8e5bSMarkus Armbruster {
880bcc8e5bSMarkus Armbruster     QObject *value;
890bcc8e5bSMarkus Armbruster     const QDictEntry *entry, *next;
900bcc8e5bSMarkus Armbruster     char *new_key;
910bcc8e5bSMarkus Armbruster     bool delete;
920bcc8e5bSMarkus Armbruster 
930bcc8e5bSMarkus Armbruster     entry = qdict_first(qdict);
940bcc8e5bSMarkus Armbruster 
950bcc8e5bSMarkus Armbruster     while (entry != NULL) {
960bcc8e5bSMarkus Armbruster 
970bcc8e5bSMarkus Armbruster         next = qdict_next(qdict, entry);
980bcc8e5bSMarkus Armbruster         value = qdict_entry_value(entry);
990bcc8e5bSMarkus Armbruster         new_key = NULL;
1000bcc8e5bSMarkus Armbruster         delete = false;
1010bcc8e5bSMarkus Armbruster 
1020bcc8e5bSMarkus Armbruster         if (prefix) {
1030bcc8e5bSMarkus Armbruster             new_key = g_strdup_printf("%s.%s", prefix, entry->key);
1040bcc8e5bSMarkus Armbruster         }
1050bcc8e5bSMarkus Armbruster 
1060bcc8e5bSMarkus Armbruster         if (qobject_type(value) == QTYPE_QDICT) {
1070bcc8e5bSMarkus Armbruster             /* Entries of QDicts are processed recursively, the QDict object
1080bcc8e5bSMarkus Armbruster              * itself disappears. */
1090bcc8e5bSMarkus Armbruster             qdict_flatten_qdict(qobject_to(QDict, value), target,
1100bcc8e5bSMarkus Armbruster                                 new_key ? new_key : entry->key);
1110bcc8e5bSMarkus Armbruster             delete = true;
1120bcc8e5bSMarkus Armbruster         } else if (qobject_type(value) == QTYPE_QLIST) {
1130bcc8e5bSMarkus Armbruster             qdict_flatten_qlist(qobject_to(QList, value), target,
1140bcc8e5bSMarkus Armbruster                                 new_key ? new_key : entry->key);
1150bcc8e5bSMarkus Armbruster             delete = true;
1160bcc8e5bSMarkus Armbruster         } else if (prefix) {
1170bcc8e5bSMarkus Armbruster             /* All other objects are moved to the target unchanged. */
1180bcc8e5bSMarkus Armbruster             qdict_put_obj(target, new_key, qobject_ref(value));
1190bcc8e5bSMarkus Armbruster             delete = true;
1200bcc8e5bSMarkus Armbruster         }
1210bcc8e5bSMarkus Armbruster 
1220bcc8e5bSMarkus Armbruster         g_free(new_key);
1230bcc8e5bSMarkus Armbruster 
1240bcc8e5bSMarkus Armbruster         if (delete) {
1250bcc8e5bSMarkus Armbruster             qdict_del(qdict, entry->key);
1260bcc8e5bSMarkus Armbruster 
1270bcc8e5bSMarkus Armbruster             /* Restart loop after modifying the iterated QDict */
1280bcc8e5bSMarkus Armbruster             entry = qdict_first(qdict);
1290bcc8e5bSMarkus Armbruster             continue;
1300bcc8e5bSMarkus Armbruster         }
1310bcc8e5bSMarkus Armbruster 
1320bcc8e5bSMarkus Armbruster         entry = next;
1330bcc8e5bSMarkus Armbruster     }
1340bcc8e5bSMarkus Armbruster }
1350bcc8e5bSMarkus Armbruster 
1360bcc8e5bSMarkus Armbruster /**
1370bcc8e5bSMarkus Armbruster  * qdict_flatten(): For each nested QDict with key x, all fields with key y
1380bcc8e5bSMarkus Armbruster  * are moved to this QDict and their key is renamed to "x.y". For each nested
1390bcc8e5bSMarkus Armbruster  * QList with key x, the field at index y is moved to this QDict with the key
1400bcc8e5bSMarkus Armbruster  * "x.y" (i.e., the reverse of what qdict_array_split() does).
1410bcc8e5bSMarkus Armbruster  * This operation is applied recursively for nested QDicts and QLists.
1420bcc8e5bSMarkus Armbruster  */
1430bcc8e5bSMarkus Armbruster void qdict_flatten(QDict *qdict)
1440bcc8e5bSMarkus Armbruster {
1450bcc8e5bSMarkus Armbruster     qdict_flatten_qdict(qdict, qdict, NULL);
1460bcc8e5bSMarkus Armbruster }
1470bcc8e5bSMarkus Armbruster 
1480bcc8e5bSMarkus Armbruster /* extract all the src QDict entries starting by start into dst */
1490bcc8e5bSMarkus Armbruster void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start)
1500bcc8e5bSMarkus Armbruster 
1510bcc8e5bSMarkus Armbruster {
1520bcc8e5bSMarkus Armbruster     const QDictEntry *entry, *next;
1530bcc8e5bSMarkus Armbruster     const char *p;
1540bcc8e5bSMarkus Armbruster 
1550bcc8e5bSMarkus Armbruster     *dst = qdict_new();
1560bcc8e5bSMarkus Armbruster     entry = qdict_first(src);
1570bcc8e5bSMarkus Armbruster 
1580bcc8e5bSMarkus Armbruster     while (entry != NULL) {
1590bcc8e5bSMarkus Armbruster         next = qdict_next(src, entry);
1600bcc8e5bSMarkus Armbruster         if (strstart(entry->key, start, &p)) {
1610bcc8e5bSMarkus Armbruster             qdict_put_obj(*dst, p, qobject_ref(entry->value));
1620bcc8e5bSMarkus Armbruster             qdict_del(src, entry->key);
1630bcc8e5bSMarkus Armbruster         }
1640bcc8e5bSMarkus Armbruster         entry = next;
1650bcc8e5bSMarkus Armbruster     }
1660bcc8e5bSMarkus Armbruster }
1670bcc8e5bSMarkus Armbruster 
1680bcc8e5bSMarkus Armbruster static int qdict_count_prefixed_entries(const QDict *src, const char *start)
1690bcc8e5bSMarkus Armbruster {
1700bcc8e5bSMarkus Armbruster     const QDictEntry *entry;
1710bcc8e5bSMarkus Armbruster     int count = 0;
1720bcc8e5bSMarkus Armbruster 
1730bcc8e5bSMarkus Armbruster     for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) {
1740bcc8e5bSMarkus Armbruster         if (strstart(entry->key, start, NULL)) {
1750bcc8e5bSMarkus Armbruster             if (count == INT_MAX) {
1760bcc8e5bSMarkus Armbruster                 return -ERANGE;
1770bcc8e5bSMarkus Armbruster             }
1780bcc8e5bSMarkus Armbruster             count++;
1790bcc8e5bSMarkus Armbruster         }
1800bcc8e5bSMarkus Armbruster     }
1810bcc8e5bSMarkus Armbruster 
1820bcc8e5bSMarkus Armbruster     return count;
1830bcc8e5bSMarkus Armbruster }
1840bcc8e5bSMarkus Armbruster 
1850bcc8e5bSMarkus Armbruster /**
1860bcc8e5bSMarkus Armbruster  * qdict_array_split(): This function moves array-like elements of a QDict into
1870bcc8e5bSMarkus Armbruster  * a new QList. Every entry in the original QDict with a key "%u" or one
1880bcc8e5bSMarkus Armbruster  * prefixed "%u.", where %u designates an unsigned integer starting at 0 and
1890bcc8e5bSMarkus Armbruster  * incrementally counting up, will be moved to a new QDict at index %u in the
1900bcc8e5bSMarkus Armbruster  * output QList with the key prefix removed, if that prefix is "%u.". If the
1910bcc8e5bSMarkus Armbruster  * whole key is just "%u", the whole QObject will be moved unchanged without
1920bcc8e5bSMarkus Armbruster  * creating a new QDict. The function terminates when there is no entry in the
1930bcc8e5bSMarkus Armbruster  * QDict with a prefix directly (incrementally) following the last one; it also
1940bcc8e5bSMarkus Armbruster  * returns if there are both entries with "%u" and "%u." for the same index %u.
1950bcc8e5bSMarkus Armbruster  * Example: {"0.a": 42, "0.b": 23, "1.x": 0, "4.y": 1, "o.o": 7, "2": 66}
1960bcc8e5bSMarkus Armbruster  *      (or {"1.x": 0, "4.y": 1, "0.a": 42, "o.o": 7, "0.b": 23, "2": 66})
1970bcc8e5bSMarkus Armbruster  *       => [{"a": 42, "b": 23}, {"x": 0}, 66]
1980bcc8e5bSMarkus Armbruster  *      and {"4.y": 1, "o.o": 7} (remainder of the old QDict)
1990bcc8e5bSMarkus Armbruster  */
2000bcc8e5bSMarkus Armbruster void qdict_array_split(QDict *src, QList **dst)
2010bcc8e5bSMarkus Armbruster {
2020bcc8e5bSMarkus Armbruster     unsigned i;
2030bcc8e5bSMarkus Armbruster 
2040bcc8e5bSMarkus Armbruster     *dst = qlist_new();
2050bcc8e5bSMarkus Armbruster 
2060bcc8e5bSMarkus Armbruster     for (i = 0; i < UINT_MAX; i++) {
2070bcc8e5bSMarkus Armbruster         QObject *subqobj;
2080bcc8e5bSMarkus Armbruster         bool is_subqdict;
2090bcc8e5bSMarkus Armbruster         QDict *subqdict;
2100bcc8e5bSMarkus Armbruster         char indexstr[32], prefix[32];
2110bcc8e5bSMarkus Armbruster         size_t snprintf_ret;
2120bcc8e5bSMarkus Armbruster 
2130bcc8e5bSMarkus Armbruster         snprintf_ret = snprintf(indexstr, 32, "%u", i);
2140bcc8e5bSMarkus Armbruster         assert(snprintf_ret < 32);
2150bcc8e5bSMarkus Armbruster 
2160bcc8e5bSMarkus Armbruster         subqobj = qdict_get(src, indexstr);
2170bcc8e5bSMarkus Armbruster 
2180bcc8e5bSMarkus Armbruster         snprintf_ret = snprintf(prefix, 32, "%u.", i);
2190bcc8e5bSMarkus Armbruster         assert(snprintf_ret < 32);
2200bcc8e5bSMarkus Armbruster 
2210bcc8e5bSMarkus Armbruster         /* Overflow is the same as positive non-zero results */
2220bcc8e5bSMarkus Armbruster         is_subqdict = qdict_count_prefixed_entries(src, prefix);
2230bcc8e5bSMarkus Armbruster 
2240bcc8e5bSMarkus Armbruster         /*
2250bcc8e5bSMarkus Armbruster          * There may be either a single subordinate object (named
2260bcc8e5bSMarkus Armbruster          * "%u") or multiple objects (each with a key prefixed "%u."),
2270bcc8e5bSMarkus Armbruster          * but not both.
2280bcc8e5bSMarkus Armbruster          */
2290bcc8e5bSMarkus Armbruster         if (!subqobj == !is_subqdict) {
2300bcc8e5bSMarkus Armbruster             break;
2310bcc8e5bSMarkus Armbruster         }
2320bcc8e5bSMarkus Armbruster 
2330bcc8e5bSMarkus Armbruster         if (is_subqdict) {
2340bcc8e5bSMarkus Armbruster             qdict_extract_subqdict(src, &subqdict, prefix);
2350bcc8e5bSMarkus Armbruster             assert(qdict_size(subqdict) > 0);
2360bcc8e5bSMarkus Armbruster         } else {
2370bcc8e5bSMarkus Armbruster             qobject_ref(subqobj);
2380bcc8e5bSMarkus Armbruster             qdict_del(src, indexstr);
2390bcc8e5bSMarkus Armbruster         }
2400bcc8e5bSMarkus Armbruster 
2410bcc8e5bSMarkus Armbruster         qlist_append_obj(*dst, subqobj ?: QOBJECT(subqdict));
2420bcc8e5bSMarkus Armbruster     }
2430bcc8e5bSMarkus Armbruster }
2440bcc8e5bSMarkus Armbruster 
2450bcc8e5bSMarkus Armbruster /**
2460bcc8e5bSMarkus Armbruster  * qdict_split_flat_key:
2470bcc8e5bSMarkus Armbruster  * @key: the key string to split
2480bcc8e5bSMarkus Armbruster  * @prefix: non-NULL pointer to hold extracted prefix
2490bcc8e5bSMarkus Armbruster  * @suffix: non-NULL pointer to remaining suffix
2500bcc8e5bSMarkus Armbruster  *
2510bcc8e5bSMarkus Armbruster  * Given a flattened key such as 'foo.0.bar', split it into two parts
2520bcc8e5bSMarkus Armbruster  * at the first '.' separator. Allows double dot ('..') to escape the
2530bcc8e5bSMarkus Armbruster  * normal separator.
2540bcc8e5bSMarkus Armbruster  *
2550bcc8e5bSMarkus Armbruster  * e.g.
2560bcc8e5bSMarkus Armbruster  *    'foo.0.bar' -> prefix='foo' and suffix='0.bar'
2570bcc8e5bSMarkus Armbruster  *    'foo..0.bar' -> prefix='foo.0' and suffix='bar'
2580bcc8e5bSMarkus Armbruster  *
2590bcc8e5bSMarkus Armbruster  * The '..' sequence will be unescaped in the returned 'prefix'
2600bcc8e5bSMarkus Armbruster  * string. The 'suffix' string will be left in escaped format, so it
2610bcc8e5bSMarkus Armbruster  * can be fed back into the qdict_split_flat_key() key as the input
2620bcc8e5bSMarkus Armbruster  * later.
2630bcc8e5bSMarkus Armbruster  *
2640bcc8e5bSMarkus Armbruster  * The caller is responsible for freeing the string returned in @prefix
2650bcc8e5bSMarkus Armbruster  * using g_free().
2660bcc8e5bSMarkus Armbruster  */
2670bcc8e5bSMarkus Armbruster static void qdict_split_flat_key(const char *key, char **prefix,
2680bcc8e5bSMarkus Armbruster                                  const char **suffix)
2690bcc8e5bSMarkus Armbruster {
2700bcc8e5bSMarkus Armbruster     const char *separator;
2710bcc8e5bSMarkus Armbruster     size_t i, j;
2720bcc8e5bSMarkus Armbruster 
2730bcc8e5bSMarkus Armbruster     /* Find first '.' separator, but if there is a pair '..'
2740bcc8e5bSMarkus Armbruster      * that acts as an escape, so skip over '..' */
2750bcc8e5bSMarkus Armbruster     separator = NULL;
2760bcc8e5bSMarkus Armbruster     do {
2770bcc8e5bSMarkus Armbruster         if (separator) {
2780bcc8e5bSMarkus Armbruster             separator += 2;
2790bcc8e5bSMarkus Armbruster         } else {
2800bcc8e5bSMarkus Armbruster             separator = key;
2810bcc8e5bSMarkus Armbruster         }
2820bcc8e5bSMarkus Armbruster         separator = strchr(separator, '.');
2830bcc8e5bSMarkus Armbruster     } while (separator && separator[1] == '.');
2840bcc8e5bSMarkus Armbruster 
2850bcc8e5bSMarkus Armbruster     if (separator) {
2860bcc8e5bSMarkus Armbruster         *prefix = g_strndup(key, separator - key);
2870bcc8e5bSMarkus Armbruster         *suffix = separator + 1;
2880bcc8e5bSMarkus Armbruster     } else {
2890bcc8e5bSMarkus Armbruster         *prefix = g_strdup(key);
2900bcc8e5bSMarkus Armbruster         *suffix = NULL;
2910bcc8e5bSMarkus Armbruster     }
2920bcc8e5bSMarkus Armbruster 
2930bcc8e5bSMarkus Armbruster     /* Unescape the '..' sequence into '.' */
2940bcc8e5bSMarkus Armbruster     for (i = 0, j = 0; (*prefix)[i] != '\0'; i++, j++) {
2950bcc8e5bSMarkus Armbruster         if ((*prefix)[i] == '.') {
2960bcc8e5bSMarkus Armbruster             assert((*prefix)[i + 1] == '.');
2970bcc8e5bSMarkus Armbruster             i++;
2980bcc8e5bSMarkus Armbruster         }
2990bcc8e5bSMarkus Armbruster         (*prefix)[j] = (*prefix)[i];
3000bcc8e5bSMarkus Armbruster     }
3010bcc8e5bSMarkus Armbruster     (*prefix)[j] = '\0';
3020bcc8e5bSMarkus Armbruster }
3030bcc8e5bSMarkus Armbruster 
3040bcc8e5bSMarkus Armbruster /**
3050bcc8e5bSMarkus Armbruster  * qdict_is_list:
3060bcc8e5bSMarkus Armbruster  * @maybe_list: dict to check if keys represent list elements.
3070bcc8e5bSMarkus Armbruster  *
3080bcc8e5bSMarkus Armbruster  * Determine whether all keys in @maybe_list are valid list elements.
3090bcc8e5bSMarkus Armbruster  * If @maybe_list is non-zero in length and all the keys look like
3100bcc8e5bSMarkus Armbruster  * valid list indexes, this will return 1. If @maybe_list is zero
3110bcc8e5bSMarkus Armbruster  * length or all keys are non-numeric then it will return 0 to indicate
3120bcc8e5bSMarkus Armbruster  * it is a normal qdict. If there is a mix of numeric and non-numeric
3130bcc8e5bSMarkus Armbruster  * keys, or the list indexes are non-contiguous, an error is reported.
3140bcc8e5bSMarkus Armbruster  *
3150bcc8e5bSMarkus Armbruster  * Returns: 1 if a valid list, 0 if a dict, -1 on error
3160bcc8e5bSMarkus Armbruster  */
3170bcc8e5bSMarkus Armbruster static int qdict_is_list(QDict *maybe_list, Error **errp)
3180bcc8e5bSMarkus Armbruster {
3190bcc8e5bSMarkus Armbruster     const QDictEntry *ent;
3200bcc8e5bSMarkus Armbruster     ssize_t len = 0;
3210bcc8e5bSMarkus Armbruster     ssize_t max = -1;
3220bcc8e5bSMarkus Armbruster     int is_list = -1;
3230bcc8e5bSMarkus Armbruster     int64_t val;
3240bcc8e5bSMarkus Armbruster 
3250bcc8e5bSMarkus Armbruster     for (ent = qdict_first(maybe_list); ent != NULL;
3260bcc8e5bSMarkus Armbruster          ent = qdict_next(maybe_list, ent)) {
3270bcc8e5bSMarkus Armbruster 
3280bcc8e5bSMarkus Armbruster         if (qemu_strtoi64(ent->key, NULL, 10, &val) == 0) {
3290bcc8e5bSMarkus Armbruster             if (is_list == -1) {
3300bcc8e5bSMarkus Armbruster                 is_list = 1;
3310bcc8e5bSMarkus Armbruster             } else if (!is_list) {
3320bcc8e5bSMarkus Armbruster                 error_setg(errp,
3330bcc8e5bSMarkus Armbruster                            "Cannot mix list and non-list keys");
3340bcc8e5bSMarkus Armbruster                 return -1;
3350bcc8e5bSMarkus Armbruster             }
3360bcc8e5bSMarkus Armbruster             len++;
3370bcc8e5bSMarkus Armbruster             if (val > max) {
3380bcc8e5bSMarkus Armbruster                 max = val;
3390bcc8e5bSMarkus Armbruster             }
3400bcc8e5bSMarkus Armbruster         } else {
3410bcc8e5bSMarkus Armbruster             if (is_list == -1) {
3420bcc8e5bSMarkus Armbruster                 is_list = 0;
3430bcc8e5bSMarkus Armbruster             } else if (is_list) {
3440bcc8e5bSMarkus Armbruster                 error_setg(errp,
3450bcc8e5bSMarkus Armbruster                            "Cannot mix list and non-list keys");
3460bcc8e5bSMarkus Armbruster                 return -1;
3470bcc8e5bSMarkus Armbruster             }
3480bcc8e5bSMarkus Armbruster         }
3490bcc8e5bSMarkus Armbruster     }
3500bcc8e5bSMarkus Armbruster 
3510bcc8e5bSMarkus Armbruster     if (is_list == -1) {
3520bcc8e5bSMarkus Armbruster         assert(!qdict_size(maybe_list));
3530bcc8e5bSMarkus Armbruster         is_list = 0;
3540bcc8e5bSMarkus Armbruster     }
3550bcc8e5bSMarkus Armbruster 
3560bcc8e5bSMarkus Armbruster     /* NB this isn't a perfect check - e.g. it won't catch
3570bcc8e5bSMarkus Armbruster      * a list containing '1', '+1', '01', '3', but that
3580bcc8e5bSMarkus Armbruster      * does not matter - we've still proved that the
3590bcc8e5bSMarkus Armbruster      * input is a list. It is up the caller to do a
3600bcc8e5bSMarkus Armbruster      * stricter check if desired */
3610bcc8e5bSMarkus Armbruster     if (len != (max + 1)) {
3620bcc8e5bSMarkus Armbruster         error_setg(errp, "List indices are not contiguous, "
3630bcc8e5bSMarkus Armbruster                    "saw %zd elements but %zd largest index",
3640bcc8e5bSMarkus Armbruster                    len, max);
3650bcc8e5bSMarkus Armbruster         return -1;
3660bcc8e5bSMarkus Armbruster     }
3670bcc8e5bSMarkus Armbruster 
3680bcc8e5bSMarkus Armbruster     return is_list;
3690bcc8e5bSMarkus Armbruster }
3700bcc8e5bSMarkus Armbruster 
3710bcc8e5bSMarkus Armbruster /**
3720bcc8e5bSMarkus Armbruster  * qdict_crumple:
3730bcc8e5bSMarkus Armbruster  * @src: the original flat dictionary (only scalar values) to crumple
3740bcc8e5bSMarkus Armbruster  *
3750bcc8e5bSMarkus Armbruster  * Takes a flat dictionary whose keys use '.' separator to indicate
3760bcc8e5bSMarkus Armbruster  * nesting, and values are scalars, and crumples it into a nested
3770bcc8e5bSMarkus Armbruster  * structure.
3780bcc8e5bSMarkus Armbruster  *
3790bcc8e5bSMarkus Armbruster  * To include a literal '.' in a key name, it must be escaped as '..'
3800bcc8e5bSMarkus Armbruster  *
3810bcc8e5bSMarkus Armbruster  * For example, an input of:
3820bcc8e5bSMarkus Armbruster  *
3830bcc8e5bSMarkus Armbruster  * { 'foo.0.bar': 'one', 'foo.0.wizz': '1',
3840bcc8e5bSMarkus Armbruster  *   'foo.1.bar': 'two', 'foo.1.wizz': '2' }
3850bcc8e5bSMarkus Armbruster  *
3860bcc8e5bSMarkus Armbruster  * will result in an output of:
3870bcc8e5bSMarkus Armbruster  *
3880bcc8e5bSMarkus Armbruster  * {
3890bcc8e5bSMarkus Armbruster  *   'foo': [
3900bcc8e5bSMarkus Armbruster  *      { 'bar': 'one', 'wizz': '1' },
3910bcc8e5bSMarkus Armbruster  *      { 'bar': 'two', 'wizz': '2' }
3920bcc8e5bSMarkus Armbruster  *   ],
3930bcc8e5bSMarkus Armbruster  * }
3940bcc8e5bSMarkus Armbruster  *
3950bcc8e5bSMarkus Armbruster  * The following scenarios in the input dict will result in an
3960bcc8e5bSMarkus Armbruster  * error being returned:
3970bcc8e5bSMarkus Armbruster  *
3980bcc8e5bSMarkus Armbruster  *  - Any values in @src are non-scalar types
3990bcc8e5bSMarkus Armbruster  *  - If keys in @src imply that a particular level is both a
4000bcc8e5bSMarkus Armbruster  *    list and a dict. e.g., "foo.0.bar" and "foo.eek.bar".
4010bcc8e5bSMarkus Armbruster  *  - If keys in @src imply that a particular level is a list,
4020bcc8e5bSMarkus Armbruster  *    but the indices are non-contiguous. e.g. "foo.0.bar" and
4030bcc8e5bSMarkus Armbruster  *    "foo.2.bar" without any "foo.1.bar" present.
4040bcc8e5bSMarkus Armbruster  *  - If keys in @src represent list indexes, but are not in
4050bcc8e5bSMarkus Armbruster  *    the "%zu" format. e.g. "foo.+0.bar"
4060bcc8e5bSMarkus Armbruster  *
4070bcc8e5bSMarkus Armbruster  * Returns: either a QDict or QList for the nested data structure, or NULL
4080bcc8e5bSMarkus Armbruster  * on error
4090bcc8e5bSMarkus Armbruster  */
4100bcc8e5bSMarkus Armbruster QObject *qdict_crumple(const QDict *src, Error **errp)
4110bcc8e5bSMarkus Armbruster {
4120bcc8e5bSMarkus Armbruster     const QDictEntry *ent;
4130bcc8e5bSMarkus Armbruster     QDict *two_level, *multi_level = NULL;
4140bcc8e5bSMarkus Armbruster     QObject *dst = NULL, *child;
4150bcc8e5bSMarkus Armbruster     size_t i;
4160bcc8e5bSMarkus Armbruster     char *prefix = NULL;
4170bcc8e5bSMarkus Armbruster     const char *suffix = NULL;
4180bcc8e5bSMarkus Armbruster     int is_list;
4190bcc8e5bSMarkus Armbruster 
4200bcc8e5bSMarkus Armbruster     two_level = qdict_new();
4210bcc8e5bSMarkus Armbruster 
4220bcc8e5bSMarkus Armbruster     /* Step 1: split our totally flat dict into a two level dict */
4230bcc8e5bSMarkus Armbruster     for (ent = qdict_first(src); ent != NULL; ent = qdict_next(src, ent)) {
4240bcc8e5bSMarkus Armbruster         if (qobject_type(ent->value) == QTYPE_QDICT ||
4250bcc8e5bSMarkus Armbruster             qobject_type(ent->value) == QTYPE_QLIST) {
4260bcc8e5bSMarkus Armbruster             error_setg(errp, "Value %s is not a scalar",
4270bcc8e5bSMarkus Armbruster                        ent->key);
4280bcc8e5bSMarkus Armbruster             goto error;
4290bcc8e5bSMarkus Armbruster         }
4300bcc8e5bSMarkus Armbruster 
4310bcc8e5bSMarkus Armbruster         qdict_split_flat_key(ent->key, &prefix, &suffix);
4320bcc8e5bSMarkus Armbruster 
4330bcc8e5bSMarkus Armbruster         child = qdict_get(two_level, prefix);
4340bcc8e5bSMarkus Armbruster         if (suffix) {
4350bcc8e5bSMarkus Armbruster             QDict *child_dict = qobject_to(QDict, child);
4360bcc8e5bSMarkus Armbruster             if (!child_dict) {
4370bcc8e5bSMarkus Armbruster                 if (child) {
4380bcc8e5bSMarkus Armbruster                     error_setg(errp, "Key %s prefix is already set as a scalar",
4390bcc8e5bSMarkus Armbruster                                prefix);
4400bcc8e5bSMarkus Armbruster                     goto error;
4410bcc8e5bSMarkus Armbruster                 }
4420bcc8e5bSMarkus Armbruster 
4430bcc8e5bSMarkus Armbruster                 child_dict = qdict_new();
4440bcc8e5bSMarkus Armbruster                 qdict_put_obj(two_level, prefix, QOBJECT(child_dict));
4450bcc8e5bSMarkus Armbruster             }
4460bcc8e5bSMarkus Armbruster 
4470bcc8e5bSMarkus Armbruster             qdict_put_obj(child_dict, suffix, qobject_ref(ent->value));
4480bcc8e5bSMarkus Armbruster         } else {
4490bcc8e5bSMarkus Armbruster             if (child) {
4500bcc8e5bSMarkus Armbruster                 error_setg(errp, "Key %s prefix is already set as a dict",
4510bcc8e5bSMarkus Armbruster                            prefix);
4520bcc8e5bSMarkus Armbruster                 goto error;
4530bcc8e5bSMarkus Armbruster             }
4540bcc8e5bSMarkus Armbruster             qdict_put_obj(two_level, prefix, qobject_ref(ent->value));
4550bcc8e5bSMarkus Armbruster         }
4560bcc8e5bSMarkus Armbruster 
4570bcc8e5bSMarkus Armbruster         g_free(prefix);
4580bcc8e5bSMarkus Armbruster         prefix = NULL;
4590bcc8e5bSMarkus Armbruster     }
4600bcc8e5bSMarkus Armbruster 
4610bcc8e5bSMarkus Armbruster     /* Step 2: optionally process the two level dict recursively
4620bcc8e5bSMarkus Armbruster      * into a multi-level dict */
4630bcc8e5bSMarkus Armbruster     multi_level = qdict_new();
4640bcc8e5bSMarkus Armbruster     for (ent = qdict_first(two_level); ent != NULL;
4650bcc8e5bSMarkus Armbruster          ent = qdict_next(two_level, ent)) {
4660bcc8e5bSMarkus Armbruster         QDict *dict = qobject_to(QDict, ent->value);
4670bcc8e5bSMarkus Armbruster         if (dict) {
4680bcc8e5bSMarkus Armbruster             child = qdict_crumple(dict, errp);
4690bcc8e5bSMarkus Armbruster             if (!child) {
4700bcc8e5bSMarkus Armbruster                 goto error;
4710bcc8e5bSMarkus Armbruster             }
4720bcc8e5bSMarkus Armbruster 
4730bcc8e5bSMarkus Armbruster             qdict_put_obj(multi_level, ent->key, child);
4740bcc8e5bSMarkus Armbruster         } else {
4750bcc8e5bSMarkus Armbruster             qdict_put_obj(multi_level, ent->key, qobject_ref(ent->value));
4760bcc8e5bSMarkus Armbruster         }
4770bcc8e5bSMarkus Armbruster     }
4780bcc8e5bSMarkus Armbruster     qobject_unref(two_level);
4790bcc8e5bSMarkus Armbruster     two_level = NULL;
4800bcc8e5bSMarkus Armbruster 
4810bcc8e5bSMarkus Armbruster     /* Step 3: detect if we need to turn our dict into list */
4820bcc8e5bSMarkus Armbruster     is_list = qdict_is_list(multi_level, errp);
4830bcc8e5bSMarkus Armbruster     if (is_list < 0) {
4840bcc8e5bSMarkus Armbruster         goto error;
4850bcc8e5bSMarkus Armbruster     }
4860bcc8e5bSMarkus Armbruster 
4870bcc8e5bSMarkus Armbruster     if (is_list) {
4880bcc8e5bSMarkus Armbruster         dst = QOBJECT(qlist_new());
4890bcc8e5bSMarkus Armbruster 
4900bcc8e5bSMarkus Armbruster         for (i = 0; i < qdict_size(multi_level); i++) {
4910bcc8e5bSMarkus Armbruster             char *key = g_strdup_printf("%zu", i);
4920bcc8e5bSMarkus Armbruster 
4930bcc8e5bSMarkus Armbruster             child = qdict_get(multi_level, key);
4940bcc8e5bSMarkus Armbruster             g_free(key);
4950bcc8e5bSMarkus Armbruster 
4960bcc8e5bSMarkus Armbruster             if (!child) {
4970bcc8e5bSMarkus Armbruster                 error_setg(errp, "Missing list index %zu", i);
4980bcc8e5bSMarkus Armbruster                 goto error;
4990bcc8e5bSMarkus Armbruster             }
5000bcc8e5bSMarkus Armbruster 
5010bcc8e5bSMarkus Armbruster             qlist_append_obj(qobject_to(QList, dst), qobject_ref(child));
5020bcc8e5bSMarkus Armbruster         }
5030bcc8e5bSMarkus Armbruster         qobject_unref(multi_level);
5040bcc8e5bSMarkus Armbruster         multi_level = NULL;
5050bcc8e5bSMarkus Armbruster     } else {
5060bcc8e5bSMarkus Armbruster         dst = QOBJECT(multi_level);
5070bcc8e5bSMarkus Armbruster     }
5080bcc8e5bSMarkus Armbruster 
5090bcc8e5bSMarkus Armbruster     return dst;
5100bcc8e5bSMarkus Armbruster 
5110bcc8e5bSMarkus Armbruster  error:
5120bcc8e5bSMarkus Armbruster     g_free(prefix);
5130bcc8e5bSMarkus Armbruster     qobject_unref(multi_level);
5140bcc8e5bSMarkus Armbruster     qobject_unref(two_level);
5150bcc8e5bSMarkus Armbruster     qobject_unref(dst);
5160bcc8e5bSMarkus Armbruster     return NULL;
5170bcc8e5bSMarkus Armbruster }
5180bcc8e5bSMarkus Armbruster 
5190bcc8e5bSMarkus Armbruster /**
520*e5af0da1SMarkus Armbruster  * qdict_crumple_for_keyval_qiv:
521*e5af0da1SMarkus Armbruster  * @src: the flat dictionary (only scalar values) to crumple
522*e5af0da1SMarkus Armbruster  * @errp: location to store error
523*e5af0da1SMarkus Armbruster  *
524*e5af0da1SMarkus Armbruster  * Like qdict_crumple(), but additionally transforms scalar values so
525*e5af0da1SMarkus Armbruster  * the result can be passed to qobject_input_visitor_new_keyval().
526*e5af0da1SMarkus Armbruster  *
527*e5af0da1SMarkus Armbruster  * The block subsystem uses this function to prepare its flat QDict
528*e5af0da1SMarkus Armbruster  * with possibly confused scalar types for a visit.  It should not be
529*e5af0da1SMarkus Armbruster  * used for anything else, and it should go away once the block
530*e5af0da1SMarkus Armbruster  * subsystem has been cleaned up.
531*e5af0da1SMarkus Armbruster  */
532*e5af0da1SMarkus Armbruster QObject *qdict_crumple_for_keyval_qiv(QDict *src, Error **errp)
533*e5af0da1SMarkus Armbruster {
534*e5af0da1SMarkus Armbruster     QDict *tmp = NULL;
535*e5af0da1SMarkus Armbruster     char *buf;
536*e5af0da1SMarkus Armbruster     const char *s;
537*e5af0da1SMarkus Armbruster     const QDictEntry *ent;
538*e5af0da1SMarkus Armbruster     QObject *dst;
539*e5af0da1SMarkus Armbruster 
540*e5af0da1SMarkus Armbruster     for (ent = qdict_first(src); ent; ent = qdict_next(src, ent)) {
541*e5af0da1SMarkus Armbruster         buf = NULL;
542*e5af0da1SMarkus Armbruster         switch (qobject_type(ent->value)) {
543*e5af0da1SMarkus Armbruster         case QTYPE_QNULL:
544*e5af0da1SMarkus Armbruster         case QTYPE_QSTRING:
545*e5af0da1SMarkus Armbruster             continue;
546*e5af0da1SMarkus Armbruster         case QTYPE_QNUM:
547*e5af0da1SMarkus Armbruster             s = buf = qnum_to_string(qobject_to(QNum, ent->value));
548*e5af0da1SMarkus Armbruster             break;
549*e5af0da1SMarkus Armbruster         case QTYPE_QDICT:
550*e5af0da1SMarkus Armbruster         case QTYPE_QLIST:
551*e5af0da1SMarkus Armbruster             /* @src isn't flat; qdict_crumple() will fail */
552*e5af0da1SMarkus Armbruster             continue;
553*e5af0da1SMarkus Armbruster         case QTYPE_QBOOL:
554*e5af0da1SMarkus Armbruster             s = qbool_get_bool(qobject_to(QBool, ent->value))
555*e5af0da1SMarkus Armbruster                 ? "on" : "off";
556*e5af0da1SMarkus Armbruster             break;
557*e5af0da1SMarkus Armbruster         default:
558*e5af0da1SMarkus Armbruster             abort();
559*e5af0da1SMarkus Armbruster         }
560*e5af0da1SMarkus Armbruster 
561*e5af0da1SMarkus Armbruster         if (!tmp) {
562*e5af0da1SMarkus Armbruster             tmp = qdict_clone_shallow(src);
563*e5af0da1SMarkus Armbruster         }
564*e5af0da1SMarkus Armbruster         qdict_put(tmp, ent->key, qstring_from_str(s));
565*e5af0da1SMarkus Armbruster         g_free(buf);
566*e5af0da1SMarkus Armbruster     }
567*e5af0da1SMarkus Armbruster 
568*e5af0da1SMarkus Armbruster     dst = qdict_crumple(tmp ?: src, errp);
569*e5af0da1SMarkus Armbruster     qobject_unref(tmp);
570*e5af0da1SMarkus Armbruster     return dst;
571*e5af0da1SMarkus Armbruster }
572*e5af0da1SMarkus Armbruster 
573*e5af0da1SMarkus Armbruster /**
5740bcc8e5bSMarkus Armbruster  * qdict_array_entries(): Returns the number of direct array entries if the
5750bcc8e5bSMarkus Armbruster  * sub-QDict of src specified by the prefix in subqdict (or src itself for
5760bcc8e5bSMarkus Armbruster  * prefix == "") is valid as an array, i.e. the length of the created list if
5770bcc8e5bSMarkus Armbruster  * the sub-QDict would become empty after calling qdict_array_split() on it. If
5780bcc8e5bSMarkus Armbruster  * the array is not valid, -EINVAL is returned.
5790bcc8e5bSMarkus Armbruster  */
5800bcc8e5bSMarkus Armbruster int qdict_array_entries(QDict *src, const char *subqdict)
5810bcc8e5bSMarkus Armbruster {
5820bcc8e5bSMarkus Armbruster     const QDictEntry *entry;
5830bcc8e5bSMarkus Armbruster     unsigned i;
5840bcc8e5bSMarkus Armbruster     unsigned entries = 0;
5850bcc8e5bSMarkus Armbruster     size_t subqdict_len = strlen(subqdict);
5860bcc8e5bSMarkus Armbruster 
5870bcc8e5bSMarkus Armbruster     assert(!subqdict_len || subqdict[subqdict_len - 1] == '.');
5880bcc8e5bSMarkus Armbruster 
5890bcc8e5bSMarkus Armbruster     /* qdict_array_split() loops until UINT_MAX, but as we want to return
5900bcc8e5bSMarkus Armbruster      * negative errors, we only have a signed return value here. Any additional
5910bcc8e5bSMarkus Armbruster      * entries will lead to -EINVAL. */
5920bcc8e5bSMarkus Armbruster     for (i = 0; i < INT_MAX; i++) {
5930bcc8e5bSMarkus Armbruster         QObject *subqobj;
5940bcc8e5bSMarkus Armbruster         int subqdict_entries;
5950bcc8e5bSMarkus Armbruster         char *prefix = g_strdup_printf("%s%u.", subqdict, i);
5960bcc8e5bSMarkus Armbruster 
5970bcc8e5bSMarkus Armbruster         subqdict_entries = qdict_count_prefixed_entries(src, prefix);
5980bcc8e5bSMarkus Armbruster 
5990bcc8e5bSMarkus Armbruster         /* Remove ending "." */
6000bcc8e5bSMarkus Armbruster         prefix[strlen(prefix) - 1] = 0;
6010bcc8e5bSMarkus Armbruster         subqobj = qdict_get(src, prefix);
6020bcc8e5bSMarkus Armbruster 
6030bcc8e5bSMarkus Armbruster         g_free(prefix);
6040bcc8e5bSMarkus Armbruster 
6050bcc8e5bSMarkus Armbruster         if (subqdict_entries < 0) {
6060bcc8e5bSMarkus Armbruster             return subqdict_entries;
6070bcc8e5bSMarkus Armbruster         }
6080bcc8e5bSMarkus Armbruster 
6090bcc8e5bSMarkus Armbruster         /* There may be either a single subordinate object (named "%u") or
6100bcc8e5bSMarkus Armbruster          * multiple objects (each with a key prefixed "%u."), but not both. */
6110bcc8e5bSMarkus Armbruster         if (subqobj && subqdict_entries) {
6120bcc8e5bSMarkus Armbruster             return -EINVAL;
6130bcc8e5bSMarkus Armbruster         } else if (!subqobj && !subqdict_entries) {
6140bcc8e5bSMarkus Armbruster             break;
6150bcc8e5bSMarkus Armbruster         }
6160bcc8e5bSMarkus Armbruster 
6170bcc8e5bSMarkus Armbruster         entries += subqdict_entries ? subqdict_entries : 1;
6180bcc8e5bSMarkus Armbruster     }
6190bcc8e5bSMarkus Armbruster 
6200bcc8e5bSMarkus Armbruster     /* Consider everything handled that isn't part of the given sub-QDict */
6210bcc8e5bSMarkus Armbruster     for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) {
6220bcc8e5bSMarkus Armbruster         if (!strstart(qdict_entry_key(entry), subqdict, NULL)) {
6230bcc8e5bSMarkus Armbruster             entries++;
6240bcc8e5bSMarkus Armbruster         }
6250bcc8e5bSMarkus Armbruster     }
6260bcc8e5bSMarkus Armbruster 
6270bcc8e5bSMarkus Armbruster     /* Anything left in the sub-QDict that wasn't handled? */
6280bcc8e5bSMarkus Armbruster     if (qdict_size(src) != entries) {
6290bcc8e5bSMarkus Armbruster         return -EINVAL;
6300bcc8e5bSMarkus Armbruster     }
6310bcc8e5bSMarkus Armbruster 
6320bcc8e5bSMarkus Armbruster     return i;
6330bcc8e5bSMarkus Armbruster }
6340bcc8e5bSMarkus Armbruster 
6350bcc8e5bSMarkus Armbruster /**
6360bcc8e5bSMarkus Armbruster  * qdict_join(): Absorb the src QDict into the dest QDict, that is, move all
6370bcc8e5bSMarkus Armbruster  * elements from src to dest.
6380bcc8e5bSMarkus Armbruster  *
6390bcc8e5bSMarkus Armbruster  * If an element from src has a key already present in dest, it will not be
6400bcc8e5bSMarkus Armbruster  * moved unless overwrite is true.
6410bcc8e5bSMarkus Armbruster  *
6420bcc8e5bSMarkus Armbruster  * If overwrite is true, the conflicting values in dest will be discarded and
6430bcc8e5bSMarkus Armbruster  * replaced by the corresponding values from src.
6440bcc8e5bSMarkus Armbruster  *
6450bcc8e5bSMarkus Armbruster  * Therefore, with overwrite being true, the src QDict will always be empty when
6460bcc8e5bSMarkus Armbruster  * this function returns. If overwrite is false, the src QDict will be empty
6470bcc8e5bSMarkus Armbruster  * iff there were no conflicts.
6480bcc8e5bSMarkus Armbruster  */
6490bcc8e5bSMarkus Armbruster void qdict_join(QDict *dest, QDict *src, bool overwrite)
6500bcc8e5bSMarkus Armbruster {
6510bcc8e5bSMarkus Armbruster     const QDictEntry *entry, *next;
6520bcc8e5bSMarkus Armbruster 
6530bcc8e5bSMarkus Armbruster     entry = qdict_first(src);
6540bcc8e5bSMarkus Armbruster     while (entry) {
6550bcc8e5bSMarkus Armbruster         next = qdict_next(src, entry);
6560bcc8e5bSMarkus Armbruster 
6570bcc8e5bSMarkus Armbruster         if (overwrite || !qdict_haskey(dest, entry->key)) {
6580bcc8e5bSMarkus Armbruster             qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
6590bcc8e5bSMarkus Armbruster             qdict_del(src, entry->key);
6600bcc8e5bSMarkus Armbruster         }
6610bcc8e5bSMarkus Armbruster 
6620bcc8e5bSMarkus Armbruster         entry = next;
6630bcc8e5bSMarkus Armbruster     }
6640bcc8e5bSMarkus Armbruster }
6650bcc8e5bSMarkus Armbruster 
6660bcc8e5bSMarkus Armbruster /**
6670bcc8e5bSMarkus Armbruster  * qdict_rename_keys(): Rename keys in qdict according to the replacements
6680bcc8e5bSMarkus Armbruster  * specified in the array renames. The array must be terminated by an entry
6690bcc8e5bSMarkus Armbruster  * with from = NULL.
6700bcc8e5bSMarkus Armbruster  *
6710bcc8e5bSMarkus Armbruster  * The renames are performed individually in the order of the array, so entries
6720bcc8e5bSMarkus Armbruster  * may be renamed multiple times and may or may not conflict depending on the
6730bcc8e5bSMarkus Armbruster  * order of the renames array.
6740bcc8e5bSMarkus Armbruster  *
6750bcc8e5bSMarkus Armbruster  * Returns true for success, false in error cases.
6760bcc8e5bSMarkus Armbruster  */
6770bcc8e5bSMarkus Armbruster bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp)
6780bcc8e5bSMarkus Armbruster {
6790bcc8e5bSMarkus Armbruster     QObject *qobj;
6800bcc8e5bSMarkus Armbruster 
6810bcc8e5bSMarkus Armbruster     while (renames->from) {
6820bcc8e5bSMarkus Armbruster         if (qdict_haskey(qdict, renames->from)) {
6830bcc8e5bSMarkus Armbruster             if (qdict_haskey(qdict, renames->to)) {
6840bcc8e5bSMarkus Armbruster                 error_setg(errp, "'%s' and its alias '%s' can't be used at the "
6850bcc8e5bSMarkus Armbruster                            "same time", renames->to, renames->from);
6860bcc8e5bSMarkus Armbruster                 return false;
6870bcc8e5bSMarkus Armbruster             }
6880bcc8e5bSMarkus Armbruster 
6890bcc8e5bSMarkus Armbruster             qobj = qdict_get(qdict, renames->from);
6900bcc8e5bSMarkus Armbruster             qdict_put_obj(qdict, renames->to, qobject_ref(qobj));
6910bcc8e5bSMarkus Armbruster             qdict_del(qdict, renames->from);
6920bcc8e5bSMarkus Armbruster         }
6930bcc8e5bSMarkus Armbruster 
6940bcc8e5bSMarkus Armbruster         renames++;
6950bcc8e5bSMarkus Armbruster     }
6960bcc8e5bSMarkus Armbruster     return true;
6970bcc8e5bSMarkus Armbruster }
698