• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * QList data type.
3  *
4  * Copyright (C) 2009 Red Hat Inc.
5  *
6  * Authors:
7  *  Luiz Capitulino <lcapitulino@redhat.com>
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  */
qlist_new(void)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 
qlist_copy_elem(QObject * obj,void * opaque)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 
qlist_copy(QList * src)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  */
qlist_append_obj(QList * qlist,QObject * value)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  */
qlist_iter(const QList * qlist,void (* iter)(QObject * obj,void * opaque),void * opaque)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 
qlist_pop(QList * qlist)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 
qlist_peek(QList * qlist)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 
qlist_empty(const QList * qlist)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  */
qobject_to_qlist(const QObject * obj)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  */
qlist_destroy_obj(QObject * obj)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 }
157