qemu/qobject/qlist.c
<<
>>
Prefs
   1/*
   2 * QList Module
   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 LGPL, version 2.1 or later.
  10 * See the COPYING.LIB file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qapi/qmp/qlist.h"
  15#include "qapi/qmp/qobject.h"
  16#include "qemu/queue.h"
  17#include "qemu-common.h"
  18
  19/**
  20 * qlist_new(): Create a new QList
  21 *
  22 * Return strong reference.
  23 */
  24QList *qlist_new(void)
  25{
  26    QList *qlist;
  27
  28    qlist = g_malloc(sizeof(*qlist));
  29    qobject_init(QOBJECT(qlist), QTYPE_QLIST);
  30    QTAILQ_INIT(&qlist->head);
  31
  32    return qlist;
  33}
  34
  35static void qlist_copy_elem(QObject *obj, void *opaque)
  36{
  37    QList *dst = opaque;
  38
  39    qobject_incref(obj);
  40    qlist_append_obj(dst, obj);
  41}
  42
  43QList *qlist_copy(QList *src)
  44{
  45    QList *dst = qlist_new();
  46
  47    qlist_iter(src, qlist_copy_elem, dst);
  48
  49    return dst;
  50}
  51
  52/**
  53 * qlist_append_obj(): Append an QObject into QList
  54 *
  55 * NOTE: ownership of 'value' is transferred to the QList
  56 */
  57void qlist_append_obj(QList *qlist, QObject *value)
  58{
  59    QListEntry *entry;
  60
  61    entry = g_malloc(sizeof(*entry));
  62    entry->value = value;
  63
  64    QTAILQ_INSERT_TAIL(&qlist->head, entry, next);
  65}
  66
  67/**
  68 * qlist_iter(): Iterate over all the list's stored values.
  69 *
  70 * This function allows the user to provide an iterator, which will be
  71 * called for each stored value in the list.
  72 */
  73void qlist_iter(const QList *qlist,
  74                void (*iter)(QObject *obj, void *opaque), void *opaque)
  75{
  76    QListEntry *entry;
  77
  78    QTAILQ_FOREACH(entry, &qlist->head, next)
  79        iter(entry->value, opaque);
  80}
  81
  82QObject *qlist_pop(QList *qlist)
  83{
  84    QListEntry *entry;
  85    QObject *ret;
  86
  87    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
  88        return NULL;
  89    }
  90
  91    entry = QTAILQ_FIRST(&qlist->head);
  92    QTAILQ_REMOVE(&qlist->head, entry, next);
  93
  94    ret = entry->value;
  95    g_free(entry);
  96
  97    return ret;
  98}
  99
 100QObject *qlist_peek(QList *qlist)
 101{
 102    QListEntry *entry;
 103    QObject *ret;
 104
 105    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
 106        return NULL;
 107    }
 108
 109    entry = QTAILQ_FIRST(&qlist->head);
 110
 111    ret = entry->value;
 112
 113    return ret;
 114}
 115
 116int qlist_empty(const QList *qlist)
 117{
 118    return QTAILQ_EMPTY(&qlist->head);
 119}
 120
 121static void qlist_size_iter(QObject *obj, void *opaque)
 122{
 123    size_t *count = opaque;
 124    (*count)++;
 125}
 126
 127size_t qlist_size(const QList *qlist)
 128{
 129    size_t count = 0;
 130    qlist_iter(qlist, qlist_size_iter, &count);
 131    return count;
 132}
 133
 134/**
 135 * qobject_to_qlist(): Convert a QObject into a QList
 136 */
 137QList *qobject_to_qlist(const QObject *obj)
 138{
 139    if (!obj || qobject_type(obj) != QTYPE_QLIST) {
 140        return NULL;
 141    }
 142    return container_of(obj, QList, base);
 143}
 144
 145/**
 146 * qlist_destroy_obj(): Free all the memory allocated by a QList
 147 */
 148void qlist_destroy_obj(QObject *obj)
 149{
 150    QList *qlist;
 151    QListEntry *entry, *next_entry;
 152
 153    assert(obj != NULL);
 154    qlist = qobject_to_qlist(obj);
 155
 156    QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
 157        QTAILQ_REMOVE(&qlist->head, entry, next);
 158        qobject_decref(entry->value);
 159        g_free(entry);
 160    }
 161
 162    g_free(qlist);
 163}
 164