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