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