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