Revision f660dc6a
b/include/qapi/qmp/qdict.h | ||
---|---|---|
65 | 65 |
const char *qdict_get_try_str(const QDict *qdict, const char *key); |
66 | 66 |
|
67 | 67 |
QDict *qdict_clone_shallow(const QDict *src); |
68 |
void qdict_flatten(QDict *qdict); |
|
68 | 69 |
|
69 | 70 |
#endif /* QDICT_H */ |
b/qobject/qdict.c | ||
---|---|---|
476 | 476 |
|
477 | 477 |
g_free(qdict); |
478 | 478 |
} |
479 |
|
|
480 |
static void qdict_do_flatten(QDict *qdict, QDict *target, const char *prefix) |
|
481 |
{ |
|
482 |
QObject *value; |
|
483 |
const QDictEntry *entry, *next; |
|
484 |
const char *new_key; |
|
485 |
bool delete; |
|
486 |
|
|
487 |
entry = qdict_first(qdict); |
|
488 |
|
|
489 |
while (entry != NULL) { |
|
490 |
|
|
491 |
next = qdict_next(qdict, entry); |
|
492 |
value = qdict_entry_value(entry); |
|
493 |
new_key = NULL; |
|
494 |
delete = false; |
|
495 |
|
|
496 |
if (prefix) { |
|
497 |
qobject_incref(value); |
|
498 |
new_key = g_strdup_printf("%s.%s", prefix, entry->key); |
|
499 |
qdict_put_obj(target, new_key, value); |
|
500 |
delete = true; |
|
501 |
} |
|
502 |
|
|
503 |
if (qobject_type(value) == QTYPE_QDICT) { |
|
504 |
qdict_do_flatten(qobject_to_qdict(value), target, |
|
505 |
new_key ? new_key : entry->key); |
|
506 |
delete = true; |
|
507 |
} |
|
508 |
|
|
509 |
if (delete) { |
|
510 |
qdict_del(qdict, entry->key); |
|
511 |
|
|
512 |
/* Restart loop after modifying the iterated QDict */ |
|
513 |
entry = qdict_first(qdict); |
|
514 |
continue; |
|
515 |
} |
|
516 |
|
|
517 |
entry = next; |
|
518 |
} |
|
519 |
} |
|
520 |
|
|
521 |
/** |
|
522 |
* qdict_flatten(): For each nested QDict with key x, all fields with key y |
|
523 |
* are moved to this QDict and their key is renamed to "x.y". This operation |
|
524 |
* is applied recursively for nested QDicts. |
|
525 |
*/ |
|
526 |
void qdict_flatten(QDict *qdict) |
|
527 |
{ |
|
528 |
qdict_do_flatten(qdict, qdict, NULL); |
|
529 |
} |
Also available in: Unified diff