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