Statistics
| Branch: | Revision:

root / qlist.c @ d86f0e32

History | View | Annotate | Download (3 kB)

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
 */
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
}