Annotation of qemu/qdict.c, revision 1.1.1.3

1.1       root        1: /*
1.1.1.2   root        2:  * QDict Module
1.1       root        3:  *
                      4:  * Copyright (C) 2009 Red Hat Inc.
                      5:  *
                      6:  * Authors:
                      7:  *  Luiz Capitulino <lcapitulino@redhat.com>
                      8:  *
1.1.1.2   root        9:  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
                     10:  * See the COPYING.LIB file in the top-level directory.
1.1       root       11:  */
                     12: 
                     13: #include "qint.h"
1.1.1.2   root       14: #include "qfloat.h"
1.1       root       15: #include "qdict.h"
                     16: #include "qbool.h"
                     17: #include "qstring.h"
                     18: #include "qobject.h"
                     19: #include "qemu-queue.h"
                     20: #include "qemu-common.h"
                     21: 
                     22: static void qdict_destroy_obj(QObject *obj);
                     23: 
                     24: static const QType qdict_type = {
                     25:     .code = QTYPE_QDICT,
                     26:     .destroy = qdict_destroy_obj,
                     27: };
                     28: 
                     29: /**
                     30:  * qdict_new(): Create a new QDict
                     31:  *
                     32:  * Return strong reference.
                     33:  */
                     34: QDict *qdict_new(void)
                     35: {
                     36:     QDict *qdict;
                     37: 
1.1.1.3 ! root       38:     qdict = g_malloc0(sizeof(*qdict));
1.1       root       39:     QOBJECT_INIT(qdict, &qdict_type);
                     40: 
                     41:     return qdict;
                     42: }
                     43: 
                     44: /**
                     45:  * qobject_to_qdict(): Convert a QObject into a QDict
                     46:  */
                     47: QDict *qobject_to_qdict(const QObject *obj)
                     48: {
                     49:     if (qobject_type(obj) != QTYPE_QDICT)
                     50:         return NULL;
                     51: 
                     52:     return container_of(obj, QDict, base);
                     53: }
                     54: 
                     55: /**
                     56:  * tdb_hash(): based on the hash agorithm from gdbm, via tdb
                     57:  * (from module-init-tools)
                     58:  */
                     59: static unsigned int tdb_hash(const char *name)
                     60: {
                     61:     unsigned value;    /* Used to compute the hash value.  */
                     62:     unsigned   i;      /* Used to cycle through random values. */
                     63: 
                     64:     /* Set the initial value from the key size. */
                     65:     for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
                     66:         value = (value + (((const unsigned char *)name)[i] << (i*5 % 24)));
                     67: 
                     68:     return (1103515243 * value + 12345);
                     69: }
                     70: 
                     71: /**
                     72:  * alloc_entry(): allocate a new QDictEntry
                     73:  */
                     74: static QDictEntry *alloc_entry(const char *key, QObject *value)
                     75: {
                     76:     QDictEntry *entry;
                     77: 
1.1.1.3 ! root       78:     entry = g_malloc0(sizeof(*entry));
        !            79:     entry->key = g_strdup(key);
1.1       root       80:     entry->value = value;
                     81: 
                     82:     return entry;
                     83: }
                     84: 
                     85: /**
1.1.1.2   root       86:  * qdict_entry_value(): Return qdict entry value
                     87:  *
                     88:  * Return weak reference.
                     89:  */
                     90: QObject *qdict_entry_value(const QDictEntry *entry)
                     91: {
                     92:     return entry->value;
                     93: }
                     94: 
                     95: /**
                     96:  * qdict_entry_key(): Return qdict entry key
                     97:  *
                     98:  * Return a *pointer* to the string, it has to be duplicated before being
                     99:  * stored.
                    100:  */
                    101: const char *qdict_entry_key(const QDictEntry *entry)
                    102: {
                    103:     return entry->key;
                    104: }
                    105: 
                    106: /**
1.1       root      107:  * qdict_find(): List lookup function
                    108:  */
                    109: static QDictEntry *qdict_find(const QDict *qdict,
1.1.1.2   root      110:                               const char *key, unsigned int bucket)
1.1       root      111: {
                    112:     QDictEntry *entry;
                    113: 
1.1.1.2   root      114:     QLIST_FOREACH(entry, &qdict->table[bucket], next)
1.1       root      115:         if (!strcmp(entry->key, key))
                    116:             return entry;
                    117: 
                    118:     return NULL;
                    119: }
                    120: 
                    121: /**
                    122:  * qdict_put_obj(): Put a new QObject into the dictionary
                    123:  *
                    124:  * Insert the pair 'key:value' into 'qdict', if 'key' already exists
                    125:  * its 'value' will be replaced.
                    126:  *
                    127:  * This is done by freeing the reference to the stored QObject and
                    128:  * storing the new one in the same entry.
                    129:  *
                    130:  * NOTE: ownership of 'value' is transferred to the QDict
                    131:  */
                    132: void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
                    133: {
1.1.1.2   root      134:     unsigned int bucket;
1.1       root      135:     QDictEntry *entry;
                    136: 
1.1.1.2   root      137:     bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
                    138:     entry = qdict_find(qdict, key, bucket);
1.1       root      139:     if (entry) {
                    140:         /* replace key's value */
                    141:         qobject_decref(entry->value);
                    142:         entry->value = value;
                    143:     } else {
                    144:         /* allocate a new entry */
                    145:         entry = alloc_entry(key, value);
1.1.1.2   root      146:         QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
1.1       root      147:         qdict->size++;
                    148:     }
                    149: }
                    150: 
                    151: /**
                    152:  * qdict_get(): Lookup for a given 'key'
                    153:  *
                    154:  * Return a weak reference to the QObject associated with 'key' if
                    155:  * 'key' is present in the dictionary, NULL otherwise.
                    156:  */
                    157: QObject *qdict_get(const QDict *qdict, const char *key)
                    158: {
                    159:     QDictEntry *entry;
                    160: 
1.1.1.2   root      161:     entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
1.1       root      162:     return (entry == NULL ? NULL : entry->value);
                    163: }
                    164: 
                    165: /**
                    166:  * qdict_haskey(): Check if 'key' exists
                    167:  *
                    168:  * Return 1 if 'key' exists in the dict, 0 otherwise
                    169:  */
                    170: int qdict_haskey(const QDict *qdict, const char *key)
                    171: {
1.1.1.2   root      172:     unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
                    173:     return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
1.1       root      174: }
                    175: 
                    176: /**
                    177:  * qdict_size(): Return the size of the dictionary
                    178:  */
                    179: size_t qdict_size(const QDict *qdict)
                    180: {
                    181:     return qdict->size;
                    182: }
                    183: 
                    184: /**
                    185:  * qdict_get_obj(): Get a QObject of a specific type
                    186:  */
                    187: static QObject *qdict_get_obj(const QDict *qdict, const char *key,
                    188:                               qtype_code type)
                    189: {
                    190:     QObject *obj;
                    191: 
                    192:     obj = qdict_get(qdict, key);
                    193:     assert(obj != NULL);
                    194:     assert(qobject_type(obj) == type);
                    195: 
                    196:     return obj;
                    197: }
                    198: 
                    199: /**
1.1.1.2   root      200:  * qdict_get_double(): Get an number mapped by 'key'
                    201:  *
                    202:  * This function assumes that 'key' exists and it stores a
                    203:  * QFloat or QInt object.
                    204:  *
                    205:  * Return number mapped by 'key'.
                    206:  */
                    207: double qdict_get_double(const QDict *qdict, const char *key)
                    208: {
                    209:     QObject *obj = qdict_get(qdict, key);
                    210: 
                    211:     assert(obj);
                    212:     switch (qobject_type(obj)) {
                    213:     case QTYPE_QFLOAT:
                    214:         return qfloat_get_double(qobject_to_qfloat(obj));
                    215:     case QTYPE_QINT:
                    216:         return qint_get_int(qobject_to_qint(obj));
                    217:     default:
                    218:         abort();
                    219:     }
                    220: }
                    221: 
                    222: /**
1.1       root      223:  * qdict_get_int(): Get an integer mapped by 'key'
                    224:  *
                    225:  * This function assumes that 'key' exists and it stores a
                    226:  * QInt object.
                    227:  *
                    228:  * Return integer mapped by 'key'.
                    229:  */
                    230: int64_t qdict_get_int(const QDict *qdict, const char *key)
                    231: {
                    232:     QObject *obj = qdict_get_obj(qdict, key, QTYPE_QINT);
                    233:     return qint_get_int(qobject_to_qint(obj));
                    234: }
                    235: 
                    236: /**
                    237:  * qdict_get_bool(): Get a bool mapped by 'key'
                    238:  *
                    239:  * This function assumes that 'key' exists and it stores a
                    240:  * QBool object.
                    241:  *
                    242:  * Return bool mapped by 'key'.
                    243:  */
                    244: int qdict_get_bool(const QDict *qdict, const char *key)
                    245: {
                    246:     QObject *obj = qdict_get_obj(qdict, key, QTYPE_QBOOL);
                    247:     return qbool_get_int(qobject_to_qbool(obj));
                    248: }
                    249: 
                    250: /**
                    251:  * qdict_get_qlist(): Get the QList mapped by 'key'
                    252:  *
                    253:  * This function assumes that 'key' exists and it stores a
                    254:  * QList object.
                    255:  *
                    256:  * Return QList mapped by 'key'.
                    257:  */
                    258: QList *qdict_get_qlist(const QDict *qdict, const char *key)
                    259: {
                    260:     return qobject_to_qlist(qdict_get_obj(qdict, key, QTYPE_QLIST));
                    261: }
                    262: 
                    263: /**
1.1.1.2   root      264:  * qdict_get_qdict(): Get the QDict mapped by 'key'
                    265:  *
                    266:  * This function assumes that 'key' exists and it stores a
                    267:  * QDict object.
                    268:  *
                    269:  * Return QDict mapped by 'key'.
                    270:  */
                    271: QDict *qdict_get_qdict(const QDict *qdict, const char *key)
                    272: {
                    273:     return qobject_to_qdict(qdict_get_obj(qdict, key, QTYPE_QDICT));
                    274: }
                    275: 
                    276: /**
1.1       root      277:  * qdict_get_str(): Get a pointer to the stored string mapped
                    278:  * by 'key'
                    279:  *
                    280:  * This function assumes that 'key' exists and it stores a
                    281:  * QString object.
                    282:  *
                    283:  * Return pointer to the string mapped by 'key'.
                    284:  */
                    285: const char *qdict_get_str(const QDict *qdict, const char *key)
                    286: {
                    287:     QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING);
                    288:     return qstring_get_str(qobject_to_qstring(obj));
                    289: }
                    290: 
                    291: /**
                    292:  * qdict_get_try_int(): Try to get integer mapped by 'key'
                    293:  *
                    294:  * Return integer mapped by 'key', if it is not present in
                    295:  * the dictionary or if the stored object is not of QInt type
1.1.1.2   root      296:  * 'def_value' will be returned.
1.1       root      297:  */
                    298: int64_t qdict_get_try_int(const QDict *qdict, const char *key,
1.1.1.2   root      299:                           int64_t def_value)
1.1       root      300: {
                    301:     QObject *obj;
                    302: 
                    303:     obj = qdict_get(qdict, key);
                    304:     if (!obj || qobject_type(obj) != QTYPE_QINT)
1.1.1.2   root      305:         return def_value;
1.1       root      306: 
                    307:     return qint_get_int(qobject_to_qint(obj));
                    308: }
                    309: 
                    310: /**
1.1.1.2   root      311:  * qdict_get_try_bool(): Try to get a bool mapped by 'key'
                    312:  *
                    313:  * Return bool mapped by 'key', if it is not present in the
                    314:  * dictionary or if the stored object is not of QBool type
                    315:  * 'def_value' will be returned.
                    316:  */
                    317: int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value)
                    318: {
                    319:     QObject *obj;
                    320: 
                    321:     obj = qdict_get(qdict, key);
                    322:     if (!obj || qobject_type(obj) != QTYPE_QBOOL)
                    323:         return def_value;
                    324: 
                    325:     return qbool_get_int(qobject_to_qbool(obj));
                    326: }
                    327: 
                    328: /**
1.1       root      329:  * qdict_get_try_str(): Try to get a pointer to the stored string
                    330:  * mapped by 'key'
                    331:  *
                    332:  * Return a pointer to the string mapped by 'key', if it is not present
                    333:  * in the dictionary or if the stored object is not of QString type
                    334:  * NULL will be returned.
                    335:  */
                    336: const char *qdict_get_try_str(const QDict *qdict, const char *key)
                    337: {
                    338:     QObject *obj;
                    339: 
                    340:     obj = qdict_get(qdict, key);
                    341:     if (!obj || qobject_type(obj) != QTYPE_QSTRING)
                    342:         return NULL;
                    343: 
                    344:     return qstring_get_str(qobject_to_qstring(obj));
                    345: }
                    346: 
                    347: /**
                    348:  * qdict_iter(): Iterate over all the dictionary's stored values.
                    349:  *
                    350:  * This function allows the user to provide an iterator, which will be
                    351:  * called for each stored value in the dictionary.
                    352:  */
                    353: void qdict_iter(const QDict *qdict,
                    354:                 void (*iter)(const char *key, QObject *obj, void *opaque),
                    355:                 void *opaque)
                    356: {
                    357:     int i;
                    358:     QDictEntry *entry;
                    359: 
1.1.1.2   root      360:     for (i = 0; i < QDICT_BUCKET_MAX; i++) {
1.1       root      361:         QLIST_FOREACH(entry, &qdict->table[i], next)
                    362:             iter(entry->key, entry->value, opaque);
                    363:     }
                    364: }
                    365: 
1.1.1.2   root      366: static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
                    367: {
                    368:     int i;
                    369: 
                    370:     for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
                    371:         if (!QLIST_EMPTY(&qdict->table[i])) {
                    372:             return QLIST_FIRST(&qdict->table[i]);
                    373:         }
                    374:     }
                    375: 
                    376:     return NULL;
                    377: }
                    378: 
                    379: /**
                    380:  * qdict_first(): Return first qdict entry for iteration.
                    381:  */
                    382: const QDictEntry *qdict_first(const QDict *qdict)
                    383: {
                    384:     return qdict_next_entry(qdict, 0);
                    385: }
                    386: 
                    387: /**
                    388:  * qdict_next(): Return next qdict entry in an iteration.
                    389:  */
                    390: const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
                    391: {
                    392:     QDictEntry *ret;
                    393: 
                    394:     ret = QLIST_NEXT(entry, next);
                    395:     if (!ret) {
                    396:         unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
                    397:         ret = qdict_next_entry(qdict, bucket + 1);
                    398:     }
                    399: 
                    400:     return ret;
                    401: }
                    402: 
1.1       root      403: /**
                    404:  * qentry_destroy(): Free all the memory allocated by a QDictEntry
                    405:  */
                    406: static void qentry_destroy(QDictEntry *e)
                    407: {
                    408:     assert(e != NULL);
                    409:     assert(e->key != NULL);
                    410:     assert(e->value != NULL);
                    411: 
                    412:     qobject_decref(e->value);
1.1.1.3 ! root      413:     g_free(e->key);
        !           414:     g_free(e);
1.1       root      415: }
                    416: 
                    417: /**
                    418:  * qdict_del(): Delete a 'key:value' pair from the dictionary
                    419:  *
                    420:  * This will destroy all data allocated by this entry.
                    421:  */
                    422: void qdict_del(QDict *qdict, const char *key)
                    423: {
                    424:     QDictEntry *entry;
                    425: 
1.1.1.2   root      426:     entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
1.1       root      427:     if (entry) {
                    428:         QLIST_REMOVE(entry, next);
                    429:         qentry_destroy(entry);
                    430:         qdict->size--;
                    431:     }
                    432: }
                    433: 
                    434: /**
                    435:  * qdict_destroy_obj(): Free all the memory allocated by a QDict
                    436:  */
                    437: static void qdict_destroy_obj(QObject *obj)
                    438: {
                    439:     int i;
                    440:     QDict *qdict;
                    441: 
                    442:     assert(obj != NULL);
                    443:     qdict = qobject_to_qdict(obj);
                    444: 
1.1.1.2   root      445:     for (i = 0; i < QDICT_BUCKET_MAX; i++) {
1.1       root      446:         QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
                    447:         while (entry) {
                    448:             QDictEntry *tmp = QLIST_NEXT(entry, next);
                    449:             QLIST_REMOVE(entry, next);
                    450:             qentry_destroy(entry);
                    451:             entry = tmp;
                    452:         }
                    453:     }
                    454: 
1.1.1.3 ! root      455:     g_free(qdict);
1.1       root      456: }

unix.superglobalmegacorp.com