diff options
Diffstat (limited to 'contrib/qemu/qobject/qlist.c')
| -rw-r--r-- | contrib/qemu/qobject/qlist.c | 170 | 
1 files changed, 170 insertions, 0 deletions
diff --git a/contrib/qemu/qobject/qlist.c b/contrib/qemu/qobject/qlist.c new file mode 100644 index 00000000000..1ced0de58e2 --- /dev/null +++ b/contrib/qemu/qobject/qlist.c @@ -0,0 +1,170 @@ +/* + * QList Module + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + *  Luiz Capitulino <lcapitulino@redhat.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#include "qapi/qmp/qlist.h" +#include "qapi/qmp/qobject.h" +#include "qemu/queue.h" +#include "qemu-common.h" + +static void qlist_destroy_obj(QObject *obj); + +static const QType qlist_type = { +    .code = QTYPE_QLIST, +    .destroy = qlist_destroy_obj, +}; +  +/** + * qlist_new(): Create a new QList + * + * Return strong reference. + */ +QList *qlist_new(void) +{ +    QList *qlist; + +    qlist = g_malloc(sizeof(*qlist)); +    QTAILQ_INIT(&qlist->head); +    QOBJECT_INIT(qlist, &qlist_type); + +    return qlist; +} + +static void qlist_copy_elem(QObject *obj, void *opaque) +{ +    QList *dst = opaque; + +    qobject_incref(obj); +    qlist_append_obj(dst, obj); +} + +QList *qlist_copy(QList *src) +{ +    QList *dst = qlist_new(); + +    qlist_iter(src, qlist_copy_elem, dst); + +    return dst; +} + +/** + * qlist_append_obj(): Append an QObject into QList + * + * NOTE: ownership of 'value' is transferred to the QList + */ +void qlist_append_obj(QList *qlist, QObject *value) +{ +    QListEntry *entry; + +    entry = g_malloc(sizeof(*entry)); +    entry->value = value; + +    QTAILQ_INSERT_TAIL(&qlist->head, entry, next); +} + +/** + * qlist_iter(): Iterate over all the list's stored values. + * + * This function allows the user to provide an iterator, which will be + * called for each stored value in the list. + */ +void qlist_iter(const QList *qlist, +                void (*iter)(QObject *obj, void *opaque), void *opaque) +{ +    QListEntry *entry; + +    QTAILQ_FOREACH(entry, &qlist->head, next) +        iter(entry->value, opaque); +} + +QObject *qlist_pop(QList *qlist) +{ +    QListEntry *entry; +    QObject *ret; + +    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { +        return NULL; +    } + +    entry = QTAILQ_FIRST(&qlist->head); +    QTAILQ_REMOVE(&qlist->head, entry, next); + +    ret = entry->value; +    g_free(entry); + +    return ret; +} + +QObject *qlist_peek(QList *qlist) +{ +    QListEntry *entry; +    QObject *ret; + +    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { +        return NULL; +    } + +    entry = QTAILQ_FIRST(&qlist->head); + +    ret = entry->value; + +    return ret; +} + +int qlist_empty(const QList *qlist) +{ +    return QTAILQ_EMPTY(&qlist->head); +} + +static void qlist_size_iter(QObject *obj, void *opaque) +{ +    size_t *count = opaque; +    (*count)++; +} + +size_t qlist_size(const QList *qlist) +{ +    size_t count = 0; +    qlist_iter(qlist, qlist_size_iter, &count); +    return count; +} + +/** + * qobject_to_qlist(): Convert a QObject into a QList + */ +QList *qobject_to_qlist(const QObject *obj) +{ +    if (qobject_type(obj) != QTYPE_QLIST) { +        return NULL; +    } + +    return container_of(obj, QList, base); +} + +/** + * qlist_destroy_obj(): Free all the memory allocated by a QList + */ +static void qlist_destroy_obj(QObject *obj) +{ +    QList *qlist; +    QListEntry *entry, *next_entry; + +    assert(obj != NULL); +    qlist = qobject_to_qlist(obj); + +    QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) { +        QTAILQ_REMOVE(&qlist->head, entry, next); +        qobject_decref(entry->value); +        g_free(entry); +    } + +    g_free(qlist); +}  | 
