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