Implement qdict_flatten()

qdict_flatten(): For each nested QDict with key x, all fields with key y
are moved to this QDict and their key is renamed to "x.y". This operation
is applied recursively for nested QDicts.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Kevin Wolf 2013-07-08 17:11:58 +02:00
parent 29c4e2b50d
commit f660dc6a2e
2 changed files with 52 additions and 0 deletions

View File

@ -65,5 +65,6 @@ int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value);
const char *qdict_get_try_str(const QDict *qdict, const char *key);
QDict *qdict_clone_shallow(const QDict *src);
void qdict_flatten(QDict *qdict);
#endif /* QDICT_H */

View File

@ -476,3 +476,54 @@ static void qdict_destroy_obj(QObject *obj)
g_free(qdict);
}
static void qdict_do_flatten(QDict *qdict, QDict *target, const char *prefix)
{
QObject *value;
const QDictEntry *entry, *next;
const char *new_key;
bool delete;
entry = qdict_first(qdict);
while (entry != NULL) {
next = qdict_next(qdict, entry);
value = qdict_entry_value(entry);
new_key = NULL;
delete = false;
if (prefix) {
qobject_incref(value);
new_key = g_strdup_printf("%s.%s", prefix, entry->key);
qdict_put_obj(target, new_key, value);
delete = true;
}
if (qobject_type(value) == QTYPE_QDICT) {
qdict_do_flatten(qobject_to_qdict(value), target,
new_key ? new_key : entry->key);
delete = true;
}
if (delete) {
qdict_del(qdict, entry->key);
/* Restart loop after modifying the iterated QDict */
entry = qdict_first(qdict);
continue;
}
entry = next;
}
}
/**
* qdict_flatten(): For each nested QDict with key x, all fields with key y
* are moved to this QDict and their key is renamed to "x.y". This operation
* is applied recursively for nested QDicts.
*/
void qdict_flatten(QDict *qdict)
{
qdict_do_flatten(qdict, qdict, NULL);
}