qlist.c revision 2910f183ddd5286911bc1e3499ea93cb57de8b75
12910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* 22910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * QList data type. 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 * 92910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This work is licensed under the terms of the GNU GPL, version 2. See 102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * the COPYING file in the top-level directory. 112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qlist.h" 132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qobject.h" 142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qemu-queue.h" 152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qemu-common.h" 162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qlist_destroy_obj(QObject *obj); 182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic const QType qlist_type = { 202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner .code = QTYPE_QLIST, 212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner .destroy = qlist_destroy_obj, 222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}; 232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qlist_new(): Create a new QList 262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return strong reference. 282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQList *qlist_new(void) 302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QList *qlist; 322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qlist = qemu_malloc(sizeof(*qlist)); 342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_INIT(&qlist->head); 352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QOBJECT_INIT(qlist, &qlist_type); 362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return qlist; 382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qlist_copy_elem(QObject *obj, void *opaque) 412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QList *dst = opaque; 432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qobject_incref(obj); 452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qlist_append_obj(dst, obj); 462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQList *qlist_copy(QList *src) 492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QList *dst = qlist_new(); 512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qlist_iter(src, qlist_copy_elem, dst); 532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return dst; 552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qlist_append_obj(): Append an QObject into QList 592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * NOTE: ownership of 'value' is transferred to the QList 612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qlist_append_obj(QList *qlist, QObject *value) 632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QListEntry *entry; 652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner entry = qemu_malloc(sizeof(*entry)); 672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner entry->value = value; 682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_INSERT_TAIL(&qlist->head, entry, next); 702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qlist_iter(): Iterate over all the list's stored values. 742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * 752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * This function allows the user to provide an iterator, which will be 762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * called for each stored value in the list. 772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qlist_iter(const QList *qlist, 792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner void (*iter)(QObject *obj, void *opaque), void *opaque) 802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 812910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QListEntry *entry; 822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH(entry, &qlist->head, next) 842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner iter(entry->value, opaque); 852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQObject *qlist_pop(QList *qlist) 882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QListEntry *entry; 902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QObject *ret; 912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { 932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner entry = QTAILQ_FIRST(&qlist->head); 972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_REMOVE(&qlist->head, entry, next); 982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ret = entry->value; 1002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qemu_free(entry); 1012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return ret; 1032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQObject *qlist_peek(QList *qlist) 1062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QListEntry *entry; 1082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QObject *ret; 1092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { 1112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 1122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner entry = QTAILQ_FIRST(&qlist->head); 1152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner ret = entry->value; 1172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return ret; 1192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerint qlist_empty(const QList *qlist) 1222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return QTAILQ_EMPTY(&qlist->head); 1242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 1272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qobject_to_qlist(): Convert a QObject into a QList 1282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 1292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQList *qobject_to_qlist(const QObject *obj) 1302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner if (qobject_type(obj) != QTYPE_QLIST) { 1322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return NULL; 1332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner return container_of(obj, QList, base); 1362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 1372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/** 1392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qlist_destroy_obj(): Free all the memory allocated by a QList 1402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */ 1412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qlist_destroy_obj(QObject *obj) 1422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{ 1432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QList *qlist; 1442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QListEntry *entry, *next_entry; 1452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner assert(obj != NULL); 1472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qlist = qobject_to_qlist(obj); 1482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) { 1502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner QTAILQ_REMOVE(&qlist->head, entry, next); 1512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qobject_decref(entry->value); 1522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qemu_free(entry); 1532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner } 1542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 1552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner qemu_free(qlist); 1562910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner} 157