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 */ 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 */ 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 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 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; 1000bcc8e5bSMarkus Armbruster char *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 new_key = NULL; 1100bcc8e5bSMarkus Armbruster 1110bcc8e5bSMarkus Armbruster if (prefix) { 1120bcc8e5bSMarkus Armbruster new_key = g_strdup_printf("%s.%s", prefix, entry->key); 1130bcc8e5bSMarkus Armbruster } 1140bcc8e5bSMarkus Armbruster 115f1b34a24SMarkus Armbruster /* 116f1b34a24SMarkus Armbruster * Flatten non-empty QDict and QList recursively into @target, 117*bf6e6a37SMax Reitz * copy other objects to @target. 118*bf6e6a37SMax Reitz * On the root level (if @qdict == @target), remove flattened 119*bf6e6a37SMax Reitz * nested QDicts and QLists from @qdict. 120*bf6e6a37SMax Reitz * 121*bf6e6a37SMax Reitz * (Note that we do not need to remove entries from nested 122*bf6e6a37SMax Reitz * dicts or lists. Their reference count is decremented on 123*bf6e6a37SMax Reitz * the root level, so there are no leaks. In fact, if they 124*bf6e6a37SMax Reitz * have a reference count greater than one, we are probably 125*bf6e6a37SMax Reitz * well advised not to modify them altogether.) 126f1b34a24SMarkus Armbruster */ 1272860b2b2SMarkus Armbruster if (dict_val && qdict_size(dict_val)) { 1282860b2b2SMarkus Armbruster qdict_flatten_qdict(dict_val, target, 1290bcc8e5bSMarkus Armbruster new_key ? new_key : entry->key); 130*bf6e6a37SMax Reitz if (target == qdict) { 131eb0e0f7dSMarkus Armbruster qdict_del(qdict, entry->key); 132*bf6e6a37SMax Reitz } 1332860b2b2SMarkus Armbruster } else if (list_val && !qlist_empty(list_val)) { 1342860b2b2SMarkus Armbruster qdict_flatten_qlist(list_val, target, 1350bcc8e5bSMarkus Armbruster new_key ? new_key : entry->key); 136*bf6e6a37SMax Reitz if (target == qdict) { 137eb0e0f7dSMarkus Armbruster qdict_del(qdict, entry->key); 138*bf6e6a37SMax Reitz } 139f1b34a24SMarkus Armbruster } else if (target != qdict) { 1400bcc8e5bSMarkus Armbruster qdict_put_obj(target, new_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 */ 1560bcc8e5bSMarkus Armbruster void qdict_flatten(QDict *qdict) 1570bcc8e5bSMarkus Armbruster { 1580bcc8e5bSMarkus Armbruster qdict_flatten_qdict(qdict, qdict, NULL); 1590bcc8e5bSMarkus Armbruster } 1600bcc8e5bSMarkus Armbruster 1610bcc8e5bSMarkus Armbruster /* extract all the src QDict entries starting by start into dst */ 1620bcc8e5bSMarkus Armbruster void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start) 1630bcc8e5bSMarkus Armbruster 1640bcc8e5bSMarkus Armbruster { 1650bcc8e5bSMarkus Armbruster const QDictEntry *entry, *next; 1660bcc8e5bSMarkus Armbruster const char *p; 1670bcc8e5bSMarkus Armbruster 1680bcc8e5bSMarkus Armbruster *dst = qdict_new(); 1690bcc8e5bSMarkus Armbruster entry = qdict_first(src); 1700bcc8e5bSMarkus Armbruster 1710bcc8e5bSMarkus Armbruster while (entry != NULL) { 1720bcc8e5bSMarkus Armbruster next = qdict_next(src, entry); 1730bcc8e5bSMarkus Armbruster if (strstart(entry->key, start, &p)) { 1740bcc8e5bSMarkus Armbruster qdict_put_obj(*dst, p, qobject_ref(entry->value)); 1750bcc8e5bSMarkus Armbruster qdict_del(src, entry->key); 1760bcc8e5bSMarkus Armbruster } 1770bcc8e5bSMarkus Armbruster entry = next; 1780bcc8e5bSMarkus Armbruster } 1790bcc8e5bSMarkus Armbruster } 1800bcc8e5bSMarkus Armbruster 1810bcc8e5bSMarkus Armbruster static int qdict_count_prefixed_entries(const QDict *src, const char *start) 1820bcc8e5bSMarkus Armbruster { 1830bcc8e5bSMarkus Armbruster const QDictEntry *entry; 1840bcc8e5bSMarkus Armbruster int count = 0; 1850bcc8e5bSMarkus Armbruster 1860bcc8e5bSMarkus Armbruster for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) { 1870bcc8e5bSMarkus Armbruster if (strstart(entry->key, start, NULL)) { 1880bcc8e5bSMarkus Armbruster if (count == INT_MAX) { 1890bcc8e5bSMarkus Armbruster return -ERANGE; 1900bcc8e5bSMarkus Armbruster } 1910bcc8e5bSMarkus Armbruster count++; 1920bcc8e5bSMarkus Armbruster } 1930bcc8e5bSMarkus Armbruster } 1940bcc8e5bSMarkus Armbruster 1950bcc8e5bSMarkus Armbruster return count; 1960bcc8e5bSMarkus Armbruster } 1970bcc8e5bSMarkus Armbruster 1980bcc8e5bSMarkus Armbruster /** 1990bcc8e5bSMarkus Armbruster * qdict_array_split(): This function moves array-like elements of a QDict into 2000bcc8e5bSMarkus Armbruster * a new QList. Every entry in the original QDict with a key "%u" or one 2010bcc8e5bSMarkus Armbruster * prefixed "%u.", where %u designates an unsigned integer starting at 0 and 2020bcc8e5bSMarkus Armbruster * incrementally counting up, will be moved to a new QDict at index %u in the 2030bcc8e5bSMarkus Armbruster * output QList with the key prefix removed, if that prefix is "%u.". If the 2040bcc8e5bSMarkus Armbruster * whole key is just "%u", the whole QObject will be moved unchanged without 2050bcc8e5bSMarkus Armbruster * creating a new QDict. The function terminates when there is no entry in the 2060bcc8e5bSMarkus Armbruster * QDict with a prefix directly (incrementally) following the last one; it also 2070bcc8e5bSMarkus Armbruster * returns if there are both entries with "%u" and "%u." for the same index %u. 2080bcc8e5bSMarkus Armbruster * Example: {"0.a": 42, "0.b": 23, "1.x": 0, "4.y": 1, "o.o": 7, "2": 66} 2090bcc8e5bSMarkus Armbruster * (or {"1.x": 0, "4.y": 1, "0.a": 42, "o.o": 7, "0.b": 23, "2": 66}) 2100bcc8e5bSMarkus Armbruster * => [{"a": 42, "b": 23}, {"x": 0}, 66] 2110bcc8e5bSMarkus Armbruster * and {"4.y": 1, "o.o": 7} (remainder of the old QDict) 2120bcc8e5bSMarkus Armbruster */ 2130bcc8e5bSMarkus Armbruster void qdict_array_split(QDict *src, QList **dst) 2140bcc8e5bSMarkus Armbruster { 2150bcc8e5bSMarkus Armbruster unsigned i; 2160bcc8e5bSMarkus Armbruster 2170bcc8e5bSMarkus Armbruster *dst = qlist_new(); 2180bcc8e5bSMarkus Armbruster 2190bcc8e5bSMarkus Armbruster for (i = 0; i < UINT_MAX; i++) { 2200bcc8e5bSMarkus Armbruster QObject *subqobj; 2210bcc8e5bSMarkus Armbruster bool is_subqdict; 2220bcc8e5bSMarkus Armbruster QDict *subqdict; 2230bcc8e5bSMarkus Armbruster char indexstr[32], prefix[32]; 2240bcc8e5bSMarkus Armbruster size_t snprintf_ret; 2250bcc8e5bSMarkus Armbruster 2260bcc8e5bSMarkus Armbruster snprintf_ret = snprintf(indexstr, 32, "%u", i); 2270bcc8e5bSMarkus Armbruster assert(snprintf_ret < 32); 2280bcc8e5bSMarkus Armbruster 2290bcc8e5bSMarkus Armbruster subqobj = qdict_get(src, indexstr); 2300bcc8e5bSMarkus Armbruster 2310bcc8e5bSMarkus Armbruster snprintf_ret = snprintf(prefix, 32, "%u.", i); 2320bcc8e5bSMarkus Armbruster assert(snprintf_ret < 32); 2330bcc8e5bSMarkus Armbruster 2340bcc8e5bSMarkus Armbruster /* Overflow is the same as positive non-zero results */ 2350bcc8e5bSMarkus Armbruster is_subqdict = qdict_count_prefixed_entries(src, prefix); 2360bcc8e5bSMarkus Armbruster 2370bcc8e5bSMarkus Armbruster /* 2380bcc8e5bSMarkus Armbruster * There may be either a single subordinate object (named 2390bcc8e5bSMarkus Armbruster * "%u") or multiple objects (each with a key prefixed "%u."), 2400bcc8e5bSMarkus Armbruster * but not both. 2410bcc8e5bSMarkus Armbruster */ 2420bcc8e5bSMarkus Armbruster if (!subqobj == !is_subqdict) { 2430bcc8e5bSMarkus Armbruster break; 2440bcc8e5bSMarkus Armbruster } 2450bcc8e5bSMarkus Armbruster 2460bcc8e5bSMarkus Armbruster if (is_subqdict) { 2470bcc8e5bSMarkus Armbruster qdict_extract_subqdict(src, &subqdict, prefix); 2480bcc8e5bSMarkus Armbruster assert(qdict_size(subqdict) > 0); 2490bcc8e5bSMarkus Armbruster } else { 2500bcc8e5bSMarkus Armbruster qobject_ref(subqobj); 2510bcc8e5bSMarkus Armbruster qdict_del(src, indexstr); 2520bcc8e5bSMarkus Armbruster } 2530bcc8e5bSMarkus Armbruster 2540bcc8e5bSMarkus Armbruster qlist_append_obj(*dst, subqobj ?: QOBJECT(subqdict)); 2550bcc8e5bSMarkus Armbruster } 2560bcc8e5bSMarkus Armbruster } 2570bcc8e5bSMarkus Armbruster 2580bcc8e5bSMarkus Armbruster /** 2590bcc8e5bSMarkus Armbruster * qdict_split_flat_key: 2600bcc8e5bSMarkus Armbruster * @key: the key string to split 2610bcc8e5bSMarkus Armbruster * @prefix: non-NULL pointer to hold extracted prefix 2620bcc8e5bSMarkus Armbruster * @suffix: non-NULL pointer to remaining suffix 2630bcc8e5bSMarkus Armbruster * 2640bcc8e5bSMarkus Armbruster * Given a flattened key such as 'foo.0.bar', split it into two parts 2650bcc8e5bSMarkus Armbruster * at the first '.' separator. Allows double dot ('..') to escape the 2660bcc8e5bSMarkus Armbruster * normal separator. 2670bcc8e5bSMarkus Armbruster * 2680bcc8e5bSMarkus Armbruster * e.g. 2690bcc8e5bSMarkus Armbruster * 'foo.0.bar' -> prefix='foo' and suffix='0.bar' 2700bcc8e5bSMarkus Armbruster * 'foo..0.bar' -> prefix='foo.0' and suffix='bar' 2710bcc8e5bSMarkus Armbruster * 2720bcc8e5bSMarkus Armbruster * The '..' sequence will be unescaped in the returned 'prefix' 2730bcc8e5bSMarkus Armbruster * string. The 'suffix' string will be left in escaped format, so it 2740bcc8e5bSMarkus Armbruster * can be fed back into the qdict_split_flat_key() key as the input 2750bcc8e5bSMarkus Armbruster * later. 2760bcc8e5bSMarkus Armbruster * 2770bcc8e5bSMarkus Armbruster * The caller is responsible for freeing the string returned in @prefix 2780bcc8e5bSMarkus Armbruster * using g_free(). 2790bcc8e5bSMarkus Armbruster */ 2800bcc8e5bSMarkus Armbruster static void qdict_split_flat_key(const char *key, char **prefix, 2810bcc8e5bSMarkus Armbruster const char **suffix) 2820bcc8e5bSMarkus Armbruster { 2830bcc8e5bSMarkus Armbruster const char *separator; 2840bcc8e5bSMarkus Armbruster size_t i, j; 2850bcc8e5bSMarkus Armbruster 2860bcc8e5bSMarkus Armbruster /* Find first '.' separator, but if there is a pair '..' 2870bcc8e5bSMarkus Armbruster * that acts as an escape, so skip over '..' */ 2880bcc8e5bSMarkus Armbruster separator = NULL; 2890bcc8e5bSMarkus Armbruster do { 2900bcc8e5bSMarkus Armbruster if (separator) { 2910bcc8e5bSMarkus Armbruster separator += 2; 2920bcc8e5bSMarkus Armbruster } else { 2930bcc8e5bSMarkus Armbruster separator = key; 2940bcc8e5bSMarkus Armbruster } 2950bcc8e5bSMarkus Armbruster separator = strchr(separator, '.'); 2960bcc8e5bSMarkus Armbruster } while (separator && separator[1] == '.'); 2970bcc8e5bSMarkus Armbruster 2980bcc8e5bSMarkus Armbruster if (separator) { 2990bcc8e5bSMarkus Armbruster *prefix = g_strndup(key, separator - key); 3000bcc8e5bSMarkus Armbruster *suffix = separator + 1; 3010bcc8e5bSMarkus Armbruster } else { 3020bcc8e5bSMarkus Armbruster *prefix = g_strdup(key); 3030bcc8e5bSMarkus Armbruster *suffix = NULL; 3040bcc8e5bSMarkus Armbruster } 3050bcc8e5bSMarkus Armbruster 3060bcc8e5bSMarkus Armbruster /* Unescape the '..' sequence into '.' */ 3070bcc8e5bSMarkus Armbruster for (i = 0, j = 0; (*prefix)[i] != '\0'; i++, j++) { 3080bcc8e5bSMarkus Armbruster if ((*prefix)[i] == '.') { 3090bcc8e5bSMarkus Armbruster assert((*prefix)[i + 1] == '.'); 3100bcc8e5bSMarkus Armbruster i++; 3110bcc8e5bSMarkus Armbruster } 3120bcc8e5bSMarkus Armbruster (*prefix)[j] = (*prefix)[i]; 3130bcc8e5bSMarkus Armbruster } 3140bcc8e5bSMarkus Armbruster (*prefix)[j] = '\0'; 3150bcc8e5bSMarkus Armbruster } 3160bcc8e5bSMarkus Armbruster 3170bcc8e5bSMarkus Armbruster /** 3180bcc8e5bSMarkus Armbruster * qdict_is_list: 3190bcc8e5bSMarkus Armbruster * @maybe_list: dict to check if keys represent list elements. 3200bcc8e5bSMarkus Armbruster * 3210bcc8e5bSMarkus Armbruster * Determine whether all keys in @maybe_list are valid list elements. 3220bcc8e5bSMarkus Armbruster * If @maybe_list is non-zero in length and all the keys look like 3230bcc8e5bSMarkus Armbruster * valid list indexes, this will return 1. If @maybe_list is zero 3240bcc8e5bSMarkus Armbruster * length or all keys are non-numeric then it will return 0 to indicate 3250bcc8e5bSMarkus Armbruster * it is a normal qdict. If there is a mix of numeric and non-numeric 3260bcc8e5bSMarkus Armbruster * keys, or the list indexes are non-contiguous, an error is reported. 3270bcc8e5bSMarkus Armbruster * 3280bcc8e5bSMarkus Armbruster * Returns: 1 if a valid list, 0 if a dict, -1 on error 3290bcc8e5bSMarkus Armbruster */ 3300bcc8e5bSMarkus Armbruster static int qdict_is_list(QDict *maybe_list, Error **errp) 3310bcc8e5bSMarkus Armbruster { 3320bcc8e5bSMarkus Armbruster const QDictEntry *ent; 3330bcc8e5bSMarkus Armbruster ssize_t len = 0; 3340bcc8e5bSMarkus Armbruster ssize_t max = -1; 3350bcc8e5bSMarkus Armbruster int is_list = -1; 3360bcc8e5bSMarkus Armbruster int64_t val; 3370bcc8e5bSMarkus Armbruster 3380bcc8e5bSMarkus Armbruster for (ent = qdict_first(maybe_list); ent != NULL; 3390bcc8e5bSMarkus Armbruster ent = qdict_next(maybe_list, ent)) { 340c78b8cfbSMarkus Armbruster int is_index = !qemu_strtoi64(ent->key, NULL, 10, &val); 3410bcc8e5bSMarkus Armbruster 3420bcc8e5bSMarkus Armbruster if (is_list == -1) { 343c78b8cfbSMarkus Armbruster is_list = is_index; 344c78b8cfbSMarkus Armbruster } 345c78b8cfbSMarkus Armbruster 346c78b8cfbSMarkus Armbruster if (is_index != is_list) { 347c78b8cfbSMarkus Armbruster error_setg(errp, "Cannot mix list and non-list keys"); 3480bcc8e5bSMarkus Armbruster return -1; 3490bcc8e5bSMarkus Armbruster } 350c78b8cfbSMarkus Armbruster 351c78b8cfbSMarkus Armbruster if (is_index) { 3520bcc8e5bSMarkus Armbruster len++; 3530bcc8e5bSMarkus Armbruster if (val > max) { 3540bcc8e5bSMarkus Armbruster max = val; 3550bcc8e5bSMarkus Armbruster } 3560bcc8e5bSMarkus Armbruster } 3570bcc8e5bSMarkus Armbruster } 3580bcc8e5bSMarkus Armbruster 3590bcc8e5bSMarkus Armbruster if (is_list == -1) { 3600bcc8e5bSMarkus Armbruster assert(!qdict_size(maybe_list)); 3610bcc8e5bSMarkus Armbruster is_list = 0; 3620bcc8e5bSMarkus Armbruster } 3630bcc8e5bSMarkus Armbruster 3640bcc8e5bSMarkus Armbruster /* NB this isn't a perfect check - e.g. it won't catch 3650bcc8e5bSMarkus Armbruster * a list containing '1', '+1', '01', '3', but that 3660bcc8e5bSMarkus Armbruster * does not matter - we've still proved that the 3670bcc8e5bSMarkus Armbruster * input is a list. It is up the caller to do a 3680bcc8e5bSMarkus Armbruster * stricter check if desired */ 3690bcc8e5bSMarkus Armbruster if (len != (max + 1)) { 3700bcc8e5bSMarkus Armbruster error_setg(errp, "List indices are not contiguous, " 3710bcc8e5bSMarkus Armbruster "saw %zd elements but %zd largest index", 3720bcc8e5bSMarkus Armbruster len, max); 3730bcc8e5bSMarkus Armbruster return -1; 3740bcc8e5bSMarkus Armbruster } 3750bcc8e5bSMarkus Armbruster 3760bcc8e5bSMarkus Armbruster return is_list; 3770bcc8e5bSMarkus Armbruster } 3780bcc8e5bSMarkus Armbruster 3790bcc8e5bSMarkus Armbruster /** 3800bcc8e5bSMarkus Armbruster * qdict_crumple: 3810bcc8e5bSMarkus Armbruster * @src: the original flat dictionary (only scalar values) to crumple 3820bcc8e5bSMarkus Armbruster * 3830bcc8e5bSMarkus Armbruster * Takes a flat dictionary whose keys use '.' separator to indicate 3842860b2b2SMarkus Armbruster * nesting, and values are scalars, empty dictionaries or empty lists, 3852860b2b2SMarkus Armbruster * and crumples it into a nested structure. 3860bcc8e5bSMarkus Armbruster * 3870bcc8e5bSMarkus Armbruster * To include a literal '.' in a key name, it must be escaped as '..' 3880bcc8e5bSMarkus Armbruster * 3890bcc8e5bSMarkus Armbruster * For example, an input of: 3900bcc8e5bSMarkus Armbruster * 3910bcc8e5bSMarkus Armbruster * { 'foo.0.bar': 'one', 'foo.0.wizz': '1', 3920bcc8e5bSMarkus Armbruster * 'foo.1.bar': 'two', 'foo.1.wizz': '2' } 3930bcc8e5bSMarkus Armbruster * 3940bcc8e5bSMarkus Armbruster * will result in an output of: 3950bcc8e5bSMarkus Armbruster * 3960bcc8e5bSMarkus Armbruster * { 3970bcc8e5bSMarkus Armbruster * 'foo': [ 3980bcc8e5bSMarkus Armbruster * { 'bar': 'one', 'wizz': '1' }, 3990bcc8e5bSMarkus Armbruster * { 'bar': 'two', 'wizz': '2' } 4000bcc8e5bSMarkus Armbruster * ], 4010bcc8e5bSMarkus Armbruster * } 4020bcc8e5bSMarkus Armbruster * 4030bcc8e5bSMarkus Armbruster * The following scenarios in the input dict will result in an 4040bcc8e5bSMarkus Armbruster * error being returned: 4050bcc8e5bSMarkus Armbruster * 4060bcc8e5bSMarkus Armbruster * - Any values in @src are non-scalar types 4070bcc8e5bSMarkus Armbruster * - If keys in @src imply that a particular level is both a 4080bcc8e5bSMarkus Armbruster * list and a dict. e.g., "foo.0.bar" and "foo.eek.bar". 4090bcc8e5bSMarkus Armbruster * - If keys in @src imply that a particular level is a list, 4100bcc8e5bSMarkus Armbruster * but the indices are non-contiguous. e.g. "foo.0.bar" and 4110bcc8e5bSMarkus Armbruster * "foo.2.bar" without any "foo.1.bar" present. 4120bcc8e5bSMarkus Armbruster * - If keys in @src represent list indexes, but are not in 4130bcc8e5bSMarkus Armbruster * the "%zu" format. e.g. "foo.+0.bar" 4140bcc8e5bSMarkus Armbruster * 4150bcc8e5bSMarkus Armbruster * Returns: either a QDict or QList for the nested data structure, or NULL 4160bcc8e5bSMarkus Armbruster * on error 4170bcc8e5bSMarkus Armbruster */ 4180bcc8e5bSMarkus Armbruster QObject *qdict_crumple(const QDict *src, Error **errp) 4190bcc8e5bSMarkus Armbruster { 4200bcc8e5bSMarkus Armbruster const QDictEntry *ent; 4213692b5d7SMarkus Armbruster QDict *two_level, *multi_level = NULL, *child_dict; 4222860b2b2SMarkus Armbruster QDict *dict_val; 4232860b2b2SMarkus Armbruster QList *list_val; 4240bcc8e5bSMarkus Armbruster QObject *dst = NULL, *child; 4250bcc8e5bSMarkus Armbruster size_t i; 4260bcc8e5bSMarkus Armbruster char *prefix = NULL; 4270bcc8e5bSMarkus Armbruster const char *suffix = NULL; 4280bcc8e5bSMarkus Armbruster int is_list; 4290bcc8e5bSMarkus Armbruster 4300bcc8e5bSMarkus Armbruster two_level = qdict_new(); 4310bcc8e5bSMarkus Armbruster 4320bcc8e5bSMarkus Armbruster /* Step 1: split our totally flat dict into a two level dict */ 4330bcc8e5bSMarkus Armbruster for (ent = qdict_first(src); ent != NULL; ent = qdict_next(src, ent)) { 4342860b2b2SMarkus Armbruster dict_val = qobject_to(QDict, ent->value); 4352860b2b2SMarkus Armbruster list_val = qobject_to(QList, ent->value); 4362860b2b2SMarkus Armbruster if ((dict_val && qdict_size(dict_val)) 4372860b2b2SMarkus Armbruster || (list_val && !qlist_empty(list_val))) { 4382860b2b2SMarkus Armbruster error_setg(errp, "Value %s is not flat", ent->key); 4390bcc8e5bSMarkus Armbruster goto error; 4400bcc8e5bSMarkus Armbruster } 4410bcc8e5bSMarkus Armbruster 4420bcc8e5bSMarkus Armbruster qdict_split_flat_key(ent->key, &prefix, &suffix); 4430bcc8e5bSMarkus Armbruster child = qdict_get(two_level, prefix); 4443692b5d7SMarkus Armbruster child_dict = qobject_to(QDict, child); 4453692b5d7SMarkus Armbruster 4460bcc8e5bSMarkus Armbruster if (child) { 4473692b5d7SMarkus Armbruster /* 4483692b5d7SMarkus Armbruster * If @child_dict, then all previous keys with this prefix 4493692b5d7SMarkus Armbruster * had a suffix. If @suffix, this one has one as well, 4503692b5d7SMarkus Armbruster * and we're good, else there's a clash. 4513692b5d7SMarkus Armbruster */ 4523692b5d7SMarkus Armbruster if (!child_dict || !suffix) { 4533692b5d7SMarkus Armbruster error_setg(errp, "Cannot mix scalar and non-scalar keys"); 4540bcc8e5bSMarkus Armbruster goto error; 4550bcc8e5bSMarkus Armbruster } 4560bcc8e5bSMarkus Armbruster } 4570bcc8e5bSMarkus Armbruster 4583692b5d7SMarkus Armbruster if (suffix) { 4593692b5d7SMarkus Armbruster if (!child_dict) { 4603692b5d7SMarkus Armbruster child_dict = qdict_new(); 4613692b5d7SMarkus Armbruster qdict_put(two_level, prefix, child_dict); 4623692b5d7SMarkus Armbruster } 4630bcc8e5bSMarkus Armbruster qdict_put_obj(child_dict, suffix, qobject_ref(ent->value)); 4640bcc8e5bSMarkus Armbruster } else { 4650bcc8e5bSMarkus Armbruster qdict_put_obj(two_level, prefix, qobject_ref(ent->value)); 4660bcc8e5bSMarkus Armbruster } 4670bcc8e5bSMarkus Armbruster 4680bcc8e5bSMarkus Armbruster g_free(prefix); 4690bcc8e5bSMarkus Armbruster prefix = NULL; 4700bcc8e5bSMarkus Armbruster } 4710bcc8e5bSMarkus Armbruster 4720bcc8e5bSMarkus Armbruster /* Step 2: optionally process the two level dict recursively 4730bcc8e5bSMarkus Armbruster * into a multi-level dict */ 4740bcc8e5bSMarkus Armbruster multi_level = qdict_new(); 4750bcc8e5bSMarkus Armbruster for (ent = qdict_first(two_level); ent != NULL; 4760bcc8e5bSMarkus Armbruster ent = qdict_next(two_level, ent)) { 4772860b2b2SMarkus Armbruster dict_val = qobject_to(QDict, ent->value); 4782860b2b2SMarkus Armbruster if (dict_val && qdict_size(dict_val)) { 4792860b2b2SMarkus Armbruster child = qdict_crumple(dict_val, errp); 4800bcc8e5bSMarkus Armbruster if (!child) { 4810bcc8e5bSMarkus Armbruster goto error; 4820bcc8e5bSMarkus Armbruster } 4830bcc8e5bSMarkus Armbruster 4840bcc8e5bSMarkus Armbruster qdict_put_obj(multi_level, ent->key, child); 4850bcc8e5bSMarkus Armbruster } else { 4860bcc8e5bSMarkus Armbruster qdict_put_obj(multi_level, ent->key, qobject_ref(ent->value)); 4870bcc8e5bSMarkus Armbruster } 4880bcc8e5bSMarkus Armbruster } 4890bcc8e5bSMarkus Armbruster qobject_unref(two_level); 4900bcc8e5bSMarkus Armbruster two_level = NULL; 4910bcc8e5bSMarkus Armbruster 4920bcc8e5bSMarkus Armbruster /* Step 3: detect if we need to turn our dict into list */ 4930bcc8e5bSMarkus Armbruster is_list = qdict_is_list(multi_level, errp); 4940bcc8e5bSMarkus Armbruster if (is_list < 0) { 4950bcc8e5bSMarkus Armbruster goto error; 4960bcc8e5bSMarkus Armbruster } 4970bcc8e5bSMarkus Armbruster 4980bcc8e5bSMarkus Armbruster if (is_list) { 4990bcc8e5bSMarkus Armbruster dst = QOBJECT(qlist_new()); 5000bcc8e5bSMarkus Armbruster 5010bcc8e5bSMarkus Armbruster for (i = 0; i < qdict_size(multi_level); i++) { 5020bcc8e5bSMarkus Armbruster char *key = g_strdup_printf("%zu", i); 5030bcc8e5bSMarkus Armbruster 5040bcc8e5bSMarkus Armbruster child = qdict_get(multi_level, key); 5050bcc8e5bSMarkus Armbruster g_free(key); 5060bcc8e5bSMarkus Armbruster 5070bcc8e5bSMarkus Armbruster if (!child) { 5080bcc8e5bSMarkus Armbruster error_setg(errp, "Missing list index %zu", i); 5090bcc8e5bSMarkus Armbruster goto error; 5100bcc8e5bSMarkus Armbruster } 5110bcc8e5bSMarkus Armbruster 5120bcc8e5bSMarkus Armbruster qlist_append_obj(qobject_to(QList, dst), qobject_ref(child)); 5130bcc8e5bSMarkus Armbruster } 5140bcc8e5bSMarkus Armbruster qobject_unref(multi_level); 5150bcc8e5bSMarkus Armbruster multi_level = NULL; 5160bcc8e5bSMarkus Armbruster } else { 5170bcc8e5bSMarkus Armbruster dst = QOBJECT(multi_level); 5180bcc8e5bSMarkus Armbruster } 5190bcc8e5bSMarkus Armbruster 5200bcc8e5bSMarkus Armbruster return dst; 5210bcc8e5bSMarkus Armbruster 5220bcc8e5bSMarkus Armbruster error: 5230bcc8e5bSMarkus Armbruster g_free(prefix); 5240bcc8e5bSMarkus Armbruster qobject_unref(multi_level); 5250bcc8e5bSMarkus Armbruster qobject_unref(two_level); 5260bcc8e5bSMarkus Armbruster qobject_unref(dst); 5270bcc8e5bSMarkus Armbruster return NULL; 5280bcc8e5bSMarkus Armbruster } 5290bcc8e5bSMarkus Armbruster 5300bcc8e5bSMarkus Armbruster /** 531e5af0da1SMarkus Armbruster * qdict_crumple_for_keyval_qiv: 532e5af0da1SMarkus Armbruster * @src: the flat dictionary (only scalar values) to crumple 533e5af0da1SMarkus Armbruster * @errp: location to store error 534e5af0da1SMarkus Armbruster * 535e5af0da1SMarkus Armbruster * Like qdict_crumple(), but additionally transforms scalar values so 536e5af0da1SMarkus Armbruster * the result can be passed to qobject_input_visitor_new_keyval(). 537e5af0da1SMarkus Armbruster * 538e5af0da1SMarkus Armbruster * The block subsystem uses this function to prepare its flat QDict 539e5af0da1SMarkus Armbruster * with possibly confused scalar types for a visit. It should not be 540e5af0da1SMarkus Armbruster * used for anything else, and it should go away once the block 541e5af0da1SMarkus Armbruster * subsystem has been cleaned up. 542e5af0da1SMarkus Armbruster */ 543af91062eSMarkus Armbruster static QObject *qdict_crumple_for_keyval_qiv(QDict *src, Error **errp) 544e5af0da1SMarkus Armbruster { 545e5af0da1SMarkus Armbruster QDict *tmp = NULL; 546e5af0da1SMarkus Armbruster char *buf; 547e5af0da1SMarkus Armbruster const char *s; 548e5af0da1SMarkus Armbruster const QDictEntry *ent; 549e5af0da1SMarkus Armbruster QObject *dst; 550e5af0da1SMarkus Armbruster 551e5af0da1SMarkus Armbruster for (ent = qdict_first(src); ent; ent = qdict_next(src, ent)) { 552e5af0da1SMarkus Armbruster buf = NULL; 553e5af0da1SMarkus Armbruster switch (qobject_type(ent->value)) { 554e5af0da1SMarkus Armbruster case QTYPE_QNULL: 555e5af0da1SMarkus Armbruster case QTYPE_QSTRING: 556e5af0da1SMarkus Armbruster continue; 557e5af0da1SMarkus Armbruster case QTYPE_QNUM: 558e5af0da1SMarkus Armbruster s = buf = qnum_to_string(qobject_to(QNum, ent->value)); 559e5af0da1SMarkus Armbruster break; 560e5af0da1SMarkus Armbruster case QTYPE_QDICT: 561e5af0da1SMarkus Armbruster case QTYPE_QLIST: 562e5af0da1SMarkus Armbruster /* @src isn't flat; qdict_crumple() will fail */ 563e5af0da1SMarkus Armbruster continue; 564e5af0da1SMarkus Armbruster case QTYPE_QBOOL: 565e5af0da1SMarkus Armbruster s = qbool_get_bool(qobject_to(QBool, ent->value)) 566e5af0da1SMarkus Armbruster ? "on" : "off"; 567e5af0da1SMarkus Armbruster break; 568e5af0da1SMarkus Armbruster default: 569e5af0da1SMarkus Armbruster abort(); 570e5af0da1SMarkus Armbruster } 571e5af0da1SMarkus Armbruster 572e5af0da1SMarkus Armbruster if (!tmp) { 573e5af0da1SMarkus Armbruster tmp = qdict_clone_shallow(src); 574e5af0da1SMarkus Armbruster } 575e5af0da1SMarkus Armbruster qdict_put(tmp, ent->key, qstring_from_str(s)); 576e5af0da1SMarkus Armbruster g_free(buf); 577e5af0da1SMarkus Armbruster } 578e5af0da1SMarkus Armbruster 579e5af0da1SMarkus Armbruster dst = qdict_crumple(tmp ?: src, errp); 580e5af0da1SMarkus Armbruster qobject_unref(tmp); 581e5af0da1SMarkus Armbruster return dst; 582e5af0da1SMarkus Armbruster } 583e5af0da1SMarkus Armbruster 584e5af0da1SMarkus Armbruster /** 5850bcc8e5bSMarkus Armbruster * qdict_array_entries(): Returns the number of direct array entries if the 5860bcc8e5bSMarkus Armbruster * sub-QDict of src specified by the prefix in subqdict (or src itself for 5870bcc8e5bSMarkus Armbruster * prefix == "") is valid as an array, i.e. the length of the created list if 5880bcc8e5bSMarkus Armbruster * the sub-QDict would become empty after calling qdict_array_split() on it. If 5890bcc8e5bSMarkus Armbruster * the array is not valid, -EINVAL is returned. 5900bcc8e5bSMarkus Armbruster */ 5910bcc8e5bSMarkus Armbruster int qdict_array_entries(QDict *src, const char *subqdict) 5920bcc8e5bSMarkus Armbruster { 5930bcc8e5bSMarkus Armbruster const QDictEntry *entry; 5940bcc8e5bSMarkus Armbruster unsigned i; 5950bcc8e5bSMarkus Armbruster unsigned entries = 0; 5960bcc8e5bSMarkus Armbruster size_t subqdict_len = strlen(subqdict); 5970bcc8e5bSMarkus Armbruster 5980bcc8e5bSMarkus Armbruster assert(!subqdict_len || subqdict[subqdict_len - 1] == '.'); 5990bcc8e5bSMarkus Armbruster 6000bcc8e5bSMarkus Armbruster /* qdict_array_split() loops until UINT_MAX, but as we want to return 6010bcc8e5bSMarkus Armbruster * negative errors, we only have a signed return value here. Any additional 6020bcc8e5bSMarkus Armbruster * entries will lead to -EINVAL. */ 6030bcc8e5bSMarkus Armbruster for (i = 0; i < INT_MAX; i++) { 6040bcc8e5bSMarkus Armbruster QObject *subqobj; 6050bcc8e5bSMarkus Armbruster int subqdict_entries; 6060bcc8e5bSMarkus Armbruster char *prefix = g_strdup_printf("%s%u.", subqdict, i); 6070bcc8e5bSMarkus Armbruster 6080bcc8e5bSMarkus Armbruster subqdict_entries = qdict_count_prefixed_entries(src, prefix); 6090bcc8e5bSMarkus Armbruster 6100bcc8e5bSMarkus Armbruster /* Remove ending "." */ 6110bcc8e5bSMarkus Armbruster prefix[strlen(prefix) - 1] = 0; 6120bcc8e5bSMarkus Armbruster subqobj = qdict_get(src, prefix); 6130bcc8e5bSMarkus Armbruster 6140bcc8e5bSMarkus Armbruster g_free(prefix); 6150bcc8e5bSMarkus Armbruster 6160bcc8e5bSMarkus Armbruster if (subqdict_entries < 0) { 6170bcc8e5bSMarkus Armbruster return subqdict_entries; 6180bcc8e5bSMarkus Armbruster } 6190bcc8e5bSMarkus Armbruster 6200bcc8e5bSMarkus Armbruster /* There may be either a single subordinate object (named "%u") or 6210bcc8e5bSMarkus Armbruster * multiple objects (each with a key prefixed "%u."), but not both. */ 6220bcc8e5bSMarkus Armbruster if (subqobj && subqdict_entries) { 6230bcc8e5bSMarkus Armbruster return -EINVAL; 6240bcc8e5bSMarkus Armbruster } else if (!subqobj && !subqdict_entries) { 6250bcc8e5bSMarkus Armbruster break; 6260bcc8e5bSMarkus Armbruster } 6270bcc8e5bSMarkus Armbruster 6280bcc8e5bSMarkus Armbruster entries += subqdict_entries ? subqdict_entries : 1; 6290bcc8e5bSMarkus Armbruster } 6300bcc8e5bSMarkus Armbruster 6310bcc8e5bSMarkus Armbruster /* Consider everything handled that isn't part of the given sub-QDict */ 6320bcc8e5bSMarkus Armbruster for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) { 6330bcc8e5bSMarkus Armbruster if (!strstart(qdict_entry_key(entry), subqdict, NULL)) { 6340bcc8e5bSMarkus Armbruster entries++; 6350bcc8e5bSMarkus Armbruster } 6360bcc8e5bSMarkus Armbruster } 6370bcc8e5bSMarkus Armbruster 6380bcc8e5bSMarkus Armbruster /* Anything left in the sub-QDict that wasn't handled? */ 6390bcc8e5bSMarkus Armbruster if (qdict_size(src) != entries) { 6400bcc8e5bSMarkus Armbruster return -EINVAL; 6410bcc8e5bSMarkus Armbruster } 6420bcc8e5bSMarkus Armbruster 6430bcc8e5bSMarkus Armbruster return i; 6440bcc8e5bSMarkus Armbruster } 6450bcc8e5bSMarkus Armbruster 6460bcc8e5bSMarkus Armbruster /** 6470bcc8e5bSMarkus Armbruster * qdict_join(): Absorb the src QDict into the dest QDict, that is, move all 6480bcc8e5bSMarkus Armbruster * elements from src to dest. 6490bcc8e5bSMarkus Armbruster * 6500bcc8e5bSMarkus Armbruster * If an element from src has a key already present in dest, it will not be 6510bcc8e5bSMarkus Armbruster * moved unless overwrite is true. 6520bcc8e5bSMarkus Armbruster * 6530bcc8e5bSMarkus Armbruster * If overwrite is true, the conflicting values in dest will be discarded and 6540bcc8e5bSMarkus Armbruster * replaced by the corresponding values from src. 6550bcc8e5bSMarkus Armbruster * 6560bcc8e5bSMarkus Armbruster * Therefore, with overwrite being true, the src QDict will always be empty when 6570bcc8e5bSMarkus Armbruster * this function returns. If overwrite is false, the src QDict will be empty 6580bcc8e5bSMarkus Armbruster * iff there were no conflicts. 6590bcc8e5bSMarkus Armbruster */ 6600bcc8e5bSMarkus Armbruster void qdict_join(QDict *dest, QDict *src, bool overwrite) 6610bcc8e5bSMarkus Armbruster { 6620bcc8e5bSMarkus Armbruster const QDictEntry *entry, *next; 6630bcc8e5bSMarkus Armbruster 6640bcc8e5bSMarkus Armbruster entry = qdict_first(src); 6650bcc8e5bSMarkus Armbruster while (entry) { 6660bcc8e5bSMarkus Armbruster next = qdict_next(src, entry); 6670bcc8e5bSMarkus Armbruster 6680bcc8e5bSMarkus Armbruster if (overwrite || !qdict_haskey(dest, entry->key)) { 6690bcc8e5bSMarkus Armbruster qdict_put_obj(dest, entry->key, qobject_ref(entry->value)); 6700bcc8e5bSMarkus Armbruster qdict_del(src, entry->key); 6710bcc8e5bSMarkus Armbruster } 6720bcc8e5bSMarkus Armbruster 6730bcc8e5bSMarkus Armbruster entry = next; 6740bcc8e5bSMarkus Armbruster } 6750bcc8e5bSMarkus Armbruster } 6760bcc8e5bSMarkus Armbruster 6770bcc8e5bSMarkus Armbruster /** 6780bcc8e5bSMarkus Armbruster * qdict_rename_keys(): Rename keys in qdict according to the replacements 6790bcc8e5bSMarkus Armbruster * specified in the array renames. The array must be terminated by an entry 6800bcc8e5bSMarkus Armbruster * with from = NULL. 6810bcc8e5bSMarkus Armbruster * 6820bcc8e5bSMarkus Armbruster * The renames are performed individually in the order of the array, so entries 6830bcc8e5bSMarkus Armbruster * may be renamed multiple times and may or may not conflict depending on the 6840bcc8e5bSMarkus Armbruster * order of the renames array. 6850bcc8e5bSMarkus Armbruster * 6860bcc8e5bSMarkus Armbruster * Returns true for success, false in error cases. 6870bcc8e5bSMarkus Armbruster */ 6880bcc8e5bSMarkus Armbruster bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp) 6890bcc8e5bSMarkus Armbruster { 6900bcc8e5bSMarkus Armbruster QObject *qobj; 6910bcc8e5bSMarkus Armbruster 6920bcc8e5bSMarkus Armbruster while (renames->from) { 6930bcc8e5bSMarkus Armbruster if (qdict_haskey(qdict, renames->from)) { 6940bcc8e5bSMarkus Armbruster if (qdict_haskey(qdict, renames->to)) { 6950bcc8e5bSMarkus Armbruster error_setg(errp, "'%s' and its alias '%s' can't be used at the " 6960bcc8e5bSMarkus Armbruster "same time", renames->to, renames->from); 6970bcc8e5bSMarkus Armbruster return false; 6980bcc8e5bSMarkus Armbruster } 6990bcc8e5bSMarkus Armbruster 7000bcc8e5bSMarkus Armbruster qobj = qdict_get(qdict, renames->from); 7010bcc8e5bSMarkus Armbruster qdict_put_obj(qdict, renames->to, qobject_ref(qobj)); 7020bcc8e5bSMarkus Armbruster qdict_del(qdict, renames->from); 7030bcc8e5bSMarkus Armbruster } 7040bcc8e5bSMarkus Armbruster 7050bcc8e5bSMarkus Armbruster renames++; 7060bcc8e5bSMarkus Armbruster } 7070bcc8e5bSMarkus Armbruster return true; 7080bcc8e5bSMarkus Armbruster } 709af91062eSMarkus Armbruster 710af91062eSMarkus Armbruster /* 711af91062eSMarkus Armbruster * Create a QObject input visitor for flat @qdict with possibly 712af91062eSMarkus Armbruster * confused scalar types. 713af91062eSMarkus Armbruster * 714af91062eSMarkus Armbruster * The block subsystem uses this function to visit its flat QDict with 715af91062eSMarkus Armbruster * possibly confused scalar types. It should not be used for anything 716af91062eSMarkus Armbruster * else, and it should go away once the block subsystem has been 717af91062eSMarkus Armbruster * cleaned up. 718af91062eSMarkus Armbruster */ 719af91062eSMarkus Armbruster Visitor *qobject_input_visitor_new_flat_confused(QDict *qdict, 720af91062eSMarkus Armbruster Error **errp) 721af91062eSMarkus Armbruster { 722af91062eSMarkus Armbruster QObject *crumpled; 723af91062eSMarkus Armbruster Visitor *v; 724af91062eSMarkus Armbruster 725af91062eSMarkus Armbruster crumpled = qdict_crumple_for_keyval_qiv(qdict, errp); 726af91062eSMarkus Armbruster if (!crumpled) { 727af91062eSMarkus Armbruster return NULL; 728af91062eSMarkus Armbruster } 729af91062eSMarkus Armbruster 730af91062eSMarkus Armbruster v = qobject_input_visitor_new_keyval(crumpled); 731af91062eSMarkus Armbruster qobject_unref(crumpled); 732af91062eSMarkus Armbruster return v; 733af91062eSMarkus Armbruster } 734