12910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/*
2cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * QDict Module
32910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
42910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Copyright (C) 2009 Red Hat Inc.
52910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
62910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Authors:
72910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *  Luiz Capitulino <lcapitulino@redhat.com>
82910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
9cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * See the COPYING.LIB file in the top-level directory.
112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
131c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qint.h"
141c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qfloat.h"
150fdfff3cce93e16179a454fd471cd1d9126204e0David 'Digit' Turner#include "qapi/qmp/qdict.h"
161c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qbool.h"
171c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qstring.h"
181c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qobject.h"
19031d655004e505a15e92580a16a181d1d247c4d5David 'Digit' Turner#include "qemu/queue.h"
202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qemu-common.h"
212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qdict_destroy_obj(QObject *obj);
232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic const QType qdict_type = {
252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    .code = QTYPE_QDICT,
262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    .destroy = qdict_destroy_obj,
272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner};
282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_new(): Create a new QDict
312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return strong reference.
332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQDict *qdict_new(void)
352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDict *qdict;
372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
38aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    qdict = g_malloc0(sizeof(*qdict));
392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QOBJECT_INIT(qdict, &qdict_type);
402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qdict;
422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qobject_to_qdict(): Convert a QObject into a QDict
462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQDict *qobject_to_qdict(const QObject *obj)
482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    if (qobject_type(obj) != QTYPE_QDICT)
502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        return NULL;
512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return container_of(obj, QDict, base);
532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * tdb_hash(): based on the hash agorithm from gdbm, via tdb
572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * (from module-init-tools)
582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic unsigned int tdb_hash(const char *name)
602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    unsigned value;	/* Used to compute the hash value.  */
622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    unsigned   i;	/* Used to cycle through random values. */
632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    /* Set the initial value from the key size. */
652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        value = (value + (((const unsigned char *)name)[i] << (i*5 % 24)));
672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return (1103515243 * value + 12345);
692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * alloc_entry(): allocate a new QDictEntry
732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic QDictEntry *alloc_entry(const char *key, QObject *value)
752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDictEntry *entry;
772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
78aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    entry = g_malloc0(sizeof(*entry));
79aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    entry->key = g_strdup(key);
802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    entry->value = value;
812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return entry;
832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
86cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * qdict_entry_value(): Return qdict entry value
87cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner *
88cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * Return weak reference.
89cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner */
90cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid TurnerQObject *qdict_entry_value(const QDictEntry *entry)
91cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner{
92cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    return entry->value;
93cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner}
94cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
95cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner/**
96cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * qdict_entry_key(): Return qdict entry key
97cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner *
98cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * Return a *pointer* to the string, it has to be duplicated before being
99cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * stored.
100cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner */
101cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turnerconst char *qdict_entry_key(const QDictEntry *entry)
102cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner{
103cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    return entry->key;
104cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner}
105cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
106cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner/**
1072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_find(): List lookup function
1082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic QDictEntry *qdict_find(const QDict *qdict,
110cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner                              const char *key, unsigned int bucket)
1112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDictEntry *entry;
1132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
114cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    QLIST_FOREACH(entry, &qdict->table[bucket], next)
1152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        if (!strcmp(entry->key, key))
1162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner            return entry;
1172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return NULL;
1192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_put_obj(): Put a new QObject into the dictionary
1232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
1242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Insert the pair 'key:value' into 'qdict', if 'key' already exists
1252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * its 'value' will be replaced.
1262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
1272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This is done by freeing the reference to the stored QObject and
1282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * storing the new one in the same entry.
1292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
1302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * NOTE: ownership of 'value' is transferred to the QDict
1312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qdict_put_obj(QDict *qdict, const char *key, QObject *value)
1332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
134cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    unsigned int bucket;
1352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDictEntry *entry;
1362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
137cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
138cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    entry = qdict_find(qdict, key, bucket);
1392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    if (entry) {
1402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        /* replace key's value */
1412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        qobject_decref(entry->value);
1422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        entry->value = value;
1432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    } else {
1442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        /* allocate a new entry */
1452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        entry = alloc_entry(key, value);
146cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
1472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        qdict->size++;
1482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    }
1492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get(): Lookup for a given 'key'
1532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
1542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return a weak reference to the QObject associated with 'key' if
1552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 'key' is present in the dictionary, NULL otherwise.
1562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQObject *qdict_get(const QDict *qdict, const char *key)
1582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDictEntry *entry;
1602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
161cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
1622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return (entry == NULL ? NULL : entry->value);
1632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_haskey(): Check if 'key' exists
1672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
1682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return 1 if 'key' exists in the dict, 0 otherwise
1692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qdict_haskey(const QDict *qdict, const char *key)
1712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
172cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
173cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
1742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_size(): Return the size of the dictionary
1782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnersize_t qdict_size(const QDict *qdict)
1802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qdict->size;
1822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_obj(): Get a QObject of a specific type
1862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic QObject *qdict_get_obj(const QDict *qdict, const char *key,
1882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner                              qtype_code type)
1892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QObject *obj;
1912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    obj = qdict_get(qdict, key);
1932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    assert(obj != NULL);
1942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    assert(qobject_type(obj) == type);
1952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return obj;
1972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
2009251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner * qdict_get_double(): Get an number mapped by 'key'
2019251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner *
2029251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner * This function assumes that 'key' exists and it stores a
2039251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner * QFloat or QInt object.
2049251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner *
2059251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner * Return number mapped by 'key'.
2069251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner */
2079251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turnerdouble qdict_get_double(const QDict *qdict, const char *key)
2089251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner{
2099251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner    QObject *obj = qdict_get(qdict, key);
2109251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner
2119251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner    assert(obj);
2129251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner    switch (qobject_type(obj)) {
2139251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner    case QTYPE_QFLOAT:
2149251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner        return qfloat_get_double(qobject_to_qfloat(obj));
2159251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner    case QTYPE_QINT:
2169251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner        return qint_get_int(qobject_to_qint(obj));
2179251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner    default:
218cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        abort();
2199251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner    }
2209251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner}
2219251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner
2229251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner/**
2232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_int(): Get an integer mapped by 'key'
2242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This function assumes that 'key' exists and it stores a
2262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QInt object.
2272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return integer mapped by 'key'.
2292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
2302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint64_t qdict_get_int(const QDict *qdict, const char *key)
2312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
2322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QObject *obj = qdict_get_obj(qdict, key, QTYPE_QINT);
2332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qint_get_int(qobject_to_qint(obj));
2342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
2352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
2362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
2372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_bool(): Get a bool mapped by 'key'
2382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This function assumes that 'key' exists and it stores a
2402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QBool object.
2412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return bool mapped by 'key'.
2432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
2442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qdict_get_bool(const QDict *qdict, const char *key)
2452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
2462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QObject *obj = qdict_get_obj(qdict, key, QTYPE_QBOOL);
2472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qbool_get_int(qobject_to_qbool(obj));
2482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
2492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
2502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
2512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_qlist(): Get the QList mapped by 'key'
2522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This function assumes that 'key' exists and it stores a
2542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QList object.
2552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return QList mapped by 'key'.
2572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
2582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQList *qdict_get_qlist(const QDict *qdict, const char *key)
2592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
2602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qobject_to_qlist(qdict_get_obj(qdict, key, QTYPE_QLIST));
2612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
2622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
2632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
2642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_qdict(): Get the QDict mapped by 'key'
2652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This function assumes that 'key' exists and it stores a
2672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QDict object.
2682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return QDict mapped by 'key'.
2702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
2712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQDict *qdict_get_qdict(const QDict *qdict, const char *key)
2722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
2732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qobject_to_qdict(qdict_get_obj(qdict, key, QTYPE_QDICT));
2742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
2752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
2762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
2772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_str(): Get a pointer to the stored string mapped
2782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * by 'key'
2792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This function assumes that 'key' exists and it stores a
2812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QString object.
2822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return pointer to the string mapped by 'key'.
2842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
2852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerconst char *qdict_get_str(const QDict *qdict, const char *key)
2862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
2872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING);
2882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qstring_get_str(qobject_to_qstring(obj));
2892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
2902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
2912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
2922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_try_int(): Try to get integer mapped by 'key'
2932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
2942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return integer mapped by 'key', if it is not present in
2952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * the dictionary or if the stored object is not of QInt type
296cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * 'def_value' will be returned.
2972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
2982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint64_t qdict_get_try_int(const QDict *qdict, const char *key,
299cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner                          int64_t def_value)
3002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
3012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QObject *obj;
3022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
3032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    obj = qdict_get(qdict, key);
3042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    if (!obj || qobject_type(obj) != QTYPE_QINT)
305cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        return def_value;
3062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
3072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qint_get_int(qobject_to_qint(obj));
3082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
3092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
3102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
311cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * qdict_get_try_bool(): Try to get a bool mapped by 'key'
312cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner *
313cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * Return bool mapped by 'key', if it is not present in the
314cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * dictionary or if the stored object is not of QBool type
315cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * 'def_value' will be returned.
316cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner */
317cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turnerint qdict_get_try_bool(const QDict *qdict, const char *key, int def_value)
318cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner{
319cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    QObject *obj;
320cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
321cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    obj = qdict_get(qdict, key);
322cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    if (!obj || qobject_type(obj) != QTYPE_QBOOL)
323cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        return def_value;
324cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
325cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    return qbool_get_int(qobject_to_qbool(obj));
326cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner}
327cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
328cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner/**
3292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_get_try_str(): Try to get a pointer to the stored string
3302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * mapped by 'key'
3312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
3322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return a pointer to the string mapped by 'key', if it is not present
3332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * in the dictionary or if the stored object is not of QString type
3342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * NULL will be returned.
3352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
3362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerconst char *qdict_get_try_str(const QDict *qdict, const char *key)
3372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
3382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QObject *obj;
3392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
3402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    obj = qdict_get(qdict, key);
3412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    if (!obj || qobject_type(obj) != QTYPE_QSTRING)
3422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        return NULL;
3432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
3442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qstring_get_str(qobject_to_qstring(obj));
3452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
3462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
3472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
3482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_iter(): Iterate over all the dictionary's stored values.
3492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
3502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This function allows the user to provide an iterator, which will be
3512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * called for each stored value in the dictionary.
3522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
3532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qdict_iter(const QDict *qdict,
3542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner                void (*iter)(const char *key, QObject *obj, void *opaque),
3552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner                void *opaque)
3562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
3572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    int i;
3582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDictEntry *entry;
3592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
360cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
3612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        QLIST_FOREACH(entry, &qdict->table[i], next)
3622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner            iter(entry->key, entry->value, opaque);
3632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    }
3642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
3652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
366cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turnerstatic QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
367cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner{
368cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    int i;
369cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
370cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
371cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        if (!QLIST_EMPTY(&qdict->table[i])) {
372cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner            return QLIST_FIRST(&qdict->table[i]);
373cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        }
374cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    }
375cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
376cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    return NULL;
377cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner}
378cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
379cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner/**
380cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * qdict_first(): Return first qdict entry for iteration.
381cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner */
382cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turnerconst QDictEntry *qdict_first(const QDict *qdict)
383cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner{
384cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    return qdict_next_entry(qdict, 0);
385cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner}
386cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
387cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner/**
388cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner * qdict_next(): Return next qdict entry in an iteration.
389cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner */
390cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turnerconst QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
391cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner{
392cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    QDictEntry *ret;
393cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
394cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    ret = QLIST_NEXT(entry, next);
395cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    if (!ret) {
396cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
397cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner        ret = qdict_next_entry(qdict, bucket + 1);
398cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    }
399cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
400cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    return ret;
401cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner}
402cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner
4032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
404910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * qdict_clone_shallow(): Clones a given QDict. Its entries are not copied, but
405910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * another reference is added.
406910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner */
407910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' TurnerQDict *qdict_clone_shallow(const QDict *src)
408910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
409910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    QDict *dest;
410910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    QDictEntry *entry;
411910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    int i;
412910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
413910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    dest = qdict_new();
414910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
415910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
416910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        QLIST_FOREACH(entry, &src->table[i], next) {
417910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qobject_incref(entry->value);
418910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qdict_put_obj(dest, entry->key, entry->value);
419910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        }
420910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    }
421910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
422910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return dest;
423910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}
424910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
425910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/**
4262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qentry_destroy(): Free all the memory allocated by a QDictEntry
4272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
4282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qentry_destroy(QDictEntry *e)
4292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
4302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    assert(e != NULL);
4312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    assert(e->key != NULL);
4322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    assert(e->value != NULL);
4332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
4342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qobject_decref(e->value);
435aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_free(e->key);
436aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_free(e);
4372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
4382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
4392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
4402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_del(): Delete a 'key:value' pair from the dictionary
4412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
4422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This will destroy all data allocated by this entry.
4432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
4442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qdict_del(QDict *qdict, const char *key)
4452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
4462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDictEntry *entry;
4472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
448cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
4492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    if (entry) {
4502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        QLIST_REMOVE(entry, next);
4512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        qentry_destroy(entry);
4522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        qdict->size--;
4532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    }
4542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
4552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
4562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
4572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qdict_destroy_obj(): Free all the memory allocated by a QDict
4582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
4592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qdict_destroy_obj(QObject *obj)
4602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
4612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    int i;
4622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QDict *qdict;
4632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
4642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    assert(obj != NULL);
4652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qdict = qobject_to_qdict(obj);
4662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
467cb34fa2cb61a4a838b32126fd28eb3450fd9f8ecDavid Turner    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
4682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
4692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        while (entry) {
4702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner            QDictEntry *tmp = QLIST_NEXT(entry, next);
4712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner            QLIST_REMOVE(entry, next);
4722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner            qentry_destroy(entry);
4732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner            entry = tmp;
4742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        }
4752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    }
4762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
477aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_free(qdict);
4782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
479910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
480910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnerstatic void qdict_do_flatten(QDict *qdict, QDict *target, const char *prefix)
481910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
482910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    QObject *value;
483910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    const QDictEntry *entry, *next;
484910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    char *new_key;
485910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    bool delete;
486910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
487910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    entry = qdict_first(qdict);
488910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
489910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    while (entry != NULL) {
490910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
491910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        next = qdict_next(qdict, entry);
492910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        value = qdict_entry_value(entry);
493910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        new_key = NULL;
494910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        delete = false;
495910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
496910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if (prefix) {
497910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            new_key = g_strdup_printf("%s.%s", prefix, entry->key);
498910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        }
499910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
500910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if (qobject_type(value) == QTYPE_QDICT) {
501910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            /* Entries of QDicts are processed recursively, the QDict object
502910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner             * itself disappears. */
503910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qdict_do_flatten(qobject_to_qdict(value), target,
504910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner                             new_key ? new_key : entry->key);
505910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            delete = true;
506910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        } else if (prefix) {
507910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            /* All other objects are moved to the target unchanged. */
508910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qobject_incref(value);
509910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qdict_put_obj(target, new_key, value);
510910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            delete = true;
511910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        }
512910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
513910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        g_free(new_key);
514910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
515910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if (delete) {
516910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qdict_del(qdict, entry->key);
517910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
518910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            /* Restart loop after modifying the iterated QDict */
519910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            entry = qdict_first(qdict);
520910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            continue;
521910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        }
522910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
523910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        entry = next;
524910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    }
525910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}
526910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
527910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/**
528910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * qdict_flatten(): For each nested QDict with key x, all fields with key y
529910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * are moved to this QDict and their key is renamed to "x.y". This operation
530910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * is applied recursively for nested QDicts.
531910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner */
532910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid qdict_flatten(QDict *qdict)
533910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
534910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    qdict_do_flatten(qdict, qdict, NULL);
535910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}
536910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
537910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/* extract all the src QDict entries starting by start into dst */
538910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnervoid qdict_extract_subqdict(QDict *src, QDict **dst, const char *start)
539910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
540910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
541910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    const QDictEntry *entry, *next;
542910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    const char *p;
543910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
544910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    *dst = qdict_new();
545910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    entry = qdict_first(src);
546910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
547910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    while (entry != NULL) {
548910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        next = qdict_next(src, entry);
549910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        if (strstart(entry->key, start, &p)) {
550910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qobject_incref(entry->value);
551910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qdict_put_obj(*dst, p, entry->value);
552910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner            qdict_del(src, entry->key);
553910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        }
554910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner        entry = next;
555910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    }
556910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}
557