Statistics
| Branch: | Revision:

root / qlist.c @ 5a2e3c2e

History | View | Annotate | Download (3 kB)

1 a6fd08eb Luiz Capitulino
/*
2 a6fd08eb Luiz Capitulino
 * QList data type.
3 a6fd08eb Luiz Capitulino
 *
4 a6fd08eb Luiz Capitulino
 * Copyright (C) 2009 Red Hat Inc.
5 a6fd08eb Luiz Capitulino
 *
6 a6fd08eb Luiz Capitulino
 * Authors:
7 a6fd08eb Luiz Capitulino
 *  Luiz Capitulino <lcapitulino@redhat.com>
8 a6fd08eb Luiz Capitulino
 *
9 a6fd08eb Luiz Capitulino
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10 a6fd08eb Luiz Capitulino
 * the COPYING file in the top-level directory.
11 a6fd08eb Luiz Capitulino
 */
12 a6fd08eb Luiz Capitulino
#include "qlist.h"
13 a6fd08eb Luiz Capitulino
#include "qobject.h"
14 a6fd08eb Luiz Capitulino
#include "qemu-queue.h"
15 a6fd08eb Luiz Capitulino
#include "qemu-common.h"
16 a6fd08eb Luiz Capitulino
17 a6fd08eb Luiz Capitulino
static void qlist_destroy_obj(QObject *obj);
18 a6fd08eb Luiz Capitulino
19 a6fd08eb Luiz Capitulino
static const QType qlist_type = {
20 a6fd08eb Luiz Capitulino
    .code = QTYPE_QLIST,
21 a6fd08eb Luiz Capitulino
    .destroy = qlist_destroy_obj,
22 a6fd08eb Luiz Capitulino
};
23 a6fd08eb Luiz Capitulino
 
24 a6fd08eb Luiz Capitulino
/**
25 a6fd08eb Luiz Capitulino
 * qlist_new(): Create a new QList
26 a6fd08eb Luiz Capitulino
 *
27 a6fd08eb Luiz Capitulino
 * Return strong reference.
28 a6fd08eb Luiz Capitulino
 */
29 a6fd08eb Luiz Capitulino
QList *qlist_new(void)
30 a6fd08eb Luiz Capitulino
{
31 a6fd08eb Luiz Capitulino
    QList *qlist;
32 a6fd08eb Luiz Capitulino
33 a6fd08eb Luiz Capitulino
    qlist = qemu_malloc(sizeof(*qlist));
34 a6fd08eb Luiz Capitulino
    QTAILQ_INIT(&qlist->head);
35 a6fd08eb Luiz Capitulino
    QOBJECT_INIT(qlist, &qlist_type);
36 a6fd08eb Luiz Capitulino
37 a6fd08eb Luiz Capitulino
    return qlist;
38 a6fd08eb Luiz Capitulino
}
39 a6fd08eb Luiz Capitulino
40 033815fe Anthony Liguori
static void qlist_copy_elem(QObject *obj, void *opaque)
41 033815fe Anthony Liguori
{
42 033815fe Anthony Liguori
    QList *dst = opaque;
43 033815fe Anthony Liguori
44 033815fe Anthony Liguori
    qobject_incref(obj);
45 033815fe Anthony Liguori
    qlist_append_obj(dst, obj);
46 033815fe Anthony Liguori
}
47 033815fe Anthony Liguori
48 033815fe Anthony Liguori
QList *qlist_copy(QList *src)
49 033815fe Anthony Liguori
{
50 033815fe Anthony Liguori
    QList *dst = qlist_new();
51 033815fe Anthony Liguori
52 033815fe Anthony Liguori
    qlist_iter(src, qlist_copy_elem, dst);
53 033815fe Anthony Liguori
54 033815fe Anthony Liguori
    return dst;
55 033815fe Anthony Liguori
}
56 033815fe Anthony Liguori
57 a6fd08eb Luiz Capitulino
/**
58 a6fd08eb Luiz Capitulino
 * qlist_append_obj(): Append an QObject into QList
59 a6fd08eb Luiz Capitulino
 *
60 a6fd08eb Luiz Capitulino
 * NOTE: ownership of 'value' is transferred to the QList
61 a6fd08eb Luiz Capitulino
 */
62 a6fd08eb Luiz Capitulino
void qlist_append_obj(QList *qlist, QObject *value)
63 a6fd08eb Luiz Capitulino
{
64 a6fd08eb Luiz Capitulino
    QListEntry *entry;
65 a6fd08eb Luiz Capitulino
66 a6fd08eb Luiz Capitulino
    entry = qemu_malloc(sizeof(*entry));
67 a6fd08eb Luiz Capitulino
    entry->value = value;
68 a6fd08eb Luiz Capitulino
69 a6fd08eb Luiz Capitulino
    QTAILQ_INSERT_TAIL(&qlist->head, entry, next);
70 a6fd08eb Luiz Capitulino
}
71 a6fd08eb Luiz Capitulino
72 a6fd08eb Luiz Capitulino
/**
73 a6fd08eb Luiz Capitulino
 * qlist_iter(): Iterate over all the list's stored values.
74 a6fd08eb Luiz Capitulino
 *
75 a6fd08eb Luiz Capitulino
 * This function allows the user to provide an iterator, which will be
76 a6fd08eb Luiz Capitulino
 * called for each stored value in the list.
77 a6fd08eb Luiz Capitulino
 */
78 a6fd08eb Luiz Capitulino
void qlist_iter(const QList *qlist,
79 a6fd08eb Luiz Capitulino
                void (*iter)(QObject *obj, void *opaque), void *opaque)
80 a6fd08eb Luiz Capitulino
{
81 a6fd08eb Luiz Capitulino
    QListEntry *entry;
82 a6fd08eb Luiz Capitulino
83 a6fd08eb Luiz Capitulino
    QTAILQ_FOREACH(entry, &qlist->head, next)
84 a6fd08eb Luiz Capitulino
        iter(entry->value, opaque);
85 a6fd08eb Luiz Capitulino
}
86 a6fd08eb Luiz Capitulino
87 033815fe Anthony Liguori
QObject *qlist_pop(QList *qlist)
88 033815fe Anthony Liguori
{
89 033815fe Anthony Liguori
    QListEntry *entry;
90 033815fe Anthony Liguori
    QObject *ret;
91 033815fe Anthony Liguori
92 033815fe Anthony Liguori
    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
93 033815fe Anthony Liguori
        return NULL;
94 033815fe Anthony Liguori
    }
95 033815fe Anthony Liguori
96 033815fe Anthony Liguori
    entry = QTAILQ_FIRST(&qlist->head);
97 033815fe Anthony Liguori
    QTAILQ_REMOVE(&qlist->head, entry, next);
98 033815fe Anthony Liguori
99 033815fe Anthony Liguori
    ret = entry->value;
100 033815fe Anthony Liguori
    qemu_free(entry);
101 033815fe Anthony Liguori
102 033815fe Anthony Liguori
    return ret;
103 033815fe Anthony Liguori
}
104 033815fe Anthony Liguori
105 033815fe Anthony Liguori
QObject *qlist_peek(QList *qlist)
106 033815fe Anthony Liguori
{
107 033815fe Anthony Liguori
    QListEntry *entry;
108 033815fe Anthony Liguori
    QObject *ret;
109 033815fe Anthony Liguori
110 033815fe Anthony Liguori
    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
111 033815fe Anthony Liguori
        return NULL;
112 033815fe Anthony Liguori
    }
113 033815fe Anthony Liguori
114 033815fe Anthony Liguori
    entry = QTAILQ_FIRST(&qlist->head);
115 033815fe Anthony Liguori
116 033815fe Anthony Liguori
    ret = entry->value;
117 033815fe Anthony Liguori
118 033815fe Anthony Liguori
    return ret;
119 033815fe Anthony Liguori
}
120 033815fe Anthony Liguori
121 033815fe Anthony Liguori
int qlist_empty(const QList *qlist)
122 033815fe Anthony Liguori
{
123 033815fe Anthony Liguori
    return QTAILQ_EMPTY(&qlist->head);
124 033815fe Anthony Liguori
}
125 033815fe Anthony Liguori
126 a6fd08eb Luiz Capitulino
/**
127 a6fd08eb Luiz Capitulino
 * qobject_to_qlist(): Convert a QObject into a QList
128 a6fd08eb Luiz Capitulino
 */
129 a6fd08eb Luiz Capitulino
QList *qobject_to_qlist(const QObject *obj)
130 a6fd08eb Luiz Capitulino
{
131 a6fd08eb Luiz Capitulino
    if (qobject_type(obj) != QTYPE_QLIST) {
132 a6fd08eb Luiz Capitulino
        return NULL;
133 a6fd08eb Luiz Capitulino
    }
134 a6fd08eb Luiz Capitulino
135 a6fd08eb Luiz Capitulino
    return container_of(obj, QList, base);
136 a6fd08eb Luiz Capitulino
}
137 a6fd08eb Luiz Capitulino
138 a6fd08eb Luiz Capitulino
/**
139 a6fd08eb Luiz Capitulino
 * qlist_destroy_obj(): Free all the memory allocated by a QList
140 a6fd08eb Luiz Capitulino
 */
141 a6fd08eb Luiz Capitulino
static void qlist_destroy_obj(QObject *obj)
142 a6fd08eb Luiz Capitulino
{
143 a6fd08eb Luiz Capitulino
    QList *qlist;
144 a6fd08eb Luiz Capitulino
    QListEntry *entry, *next_entry;
145 a6fd08eb Luiz Capitulino
146 a6fd08eb Luiz Capitulino
    assert(obj != NULL);
147 a6fd08eb Luiz Capitulino
    qlist = qobject_to_qlist(obj);
148 a6fd08eb Luiz Capitulino
149 a6fd08eb Luiz Capitulino
    QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
150 a6fd08eb Luiz Capitulino
        QTAILQ_REMOVE(&qlist->head, entry, next);
151 a6fd08eb Luiz Capitulino
        qobject_decref(entry->value);
152 a6fd08eb Luiz Capitulino
        qemu_free(entry);
153 a6fd08eb Luiz Capitulino
    }
154 a6fd08eb Luiz Capitulino
155 a6fd08eb Luiz Capitulino
    qemu_free(qlist);
156 a6fd08eb Luiz Capitulino
}