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/qbool.h"
  15#include "qapi/qmp/qlist.h"
  16#include "qapi/qmp/qnull.h"
  17#include "qapi/qmp/qnum.h"
  18#include "qapi/qmp/qstring.h"
  19#include "qemu/queue.h"
  20
  21/**
  22 * qlist_new(): Create a new QList
  23 *
  24 * Return strong reference.
  25 */
  26QList *qlist_new(void)
  27{
  28    QList *qlist;
  29
  30    qlist = g_malloc(sizeof(*qlist));
  31    qobject_init(QOBJECT(qlist), QTYPE_QLIST);
  32    QTAILQ_INIT(&qlist->head);
  33
  34    return qlist;
  35}
  36
  37QList *qlist_copy(QList *src)
  38{
  39    QList *dst = qlist_new();
  40    QListEntry *entry;
  41    QObject *elt;
  42
  43    QLIST_FOREACH_ENTRY(src, entry) {
  44        elt = qlist_entry_obj(entry);
  45        qobject_ref(elt);
  46        qlist_append_obj(dst, elt);
  47    }
  48    return dst;
  49}
  50
  51/**
  52 * qlist_append_obj(): Append an QObject into QList
  53 *
  54 * NOTE: ownership of 'value' is transferred to the QList
  55 */
  56void qlist_append_obj(QList *qlist, QObject *value)
  57{
  58    QListEntry *entry;
  59
  60    entry = g_malloc(sizeof(*entry));
  61    entry->value = value;
  62
  63    QTAILQ_INSERT_TAIL(&qlist->head, entry, next);
  64}
  65
  66void qlist_append_int(QList *qlist, int64_t value)
  67{
  68    qlist_append(qlist, qnum_from_int(value));
  69}
  70
  71void qlist_append_bool(QList *qlist, bool value)
  72{
  73    qlist_append(qlist, qbool_from_bool(value));
  74}
  75
  76void qlist_append_str(QList *qlist, const char *value)
  77{
  78    qlist_append(qlist, qstring_from_str(value));
  79}
  80
  81void qlist_append_null(QList *qlist)
  82{
  83    qlist_append(qlist, qnull());
  84}
  85
  86QObject *qlist_pop(QList *qlist)
  87{
  88    QListEntry *entry;
  89    QObject *ret;
  90
  91    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
  92        return NULL;
  93    }
  94
  95    entry = QTAILQ_FIRST(&qlist->head);
  96    QTAILQ_REMOVE(&qlist->head, entry, next);
  97
  98    ret = entry->value;
  99    g_free(entry);
 100
 101    return ret;
 102}
 103
 104QObject *qlist_peek(QList *qlist)
 105{
 106    QListEntry *entry;
 107
 108    if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
 109        return NULL;
 110    }
 111
 112    entry = QTAILQ_FIRST(&qlist->head);
 113
 114    return entry->value;
 115}
 116
 117int qlist_empty(const QList *qlist)
 118{
 119    return QTAILQ_EMPTY(&qlist->head);
 120}
 121
 122size_t qlist_size(const QList *qlist)
 123{
 124    size_t count = 0;
 125    QListEntry *entry;
 126
 127    QLIST_FOREACH_ENTRY(qlist, entry) {
 128        count++;
 129    }
 130    return count;
 131}
 132
 133/**
 134 * qlist_is_equal(): Test whether the two QLists are equal
 135 *
 136 * In order to be considered equal, the respective two objects at each
 137 * index of the two lists have to compare equal (regarding
 138 * qobject_is_equal()), and both lists have to have the same number of
 139 * elements.
 140 * That means both lists have to contain equal objects in equal order.
 141 */
 142bool qlist_is_equal(const QObject *x, const QObject *y)
 143{
 144    const QList *list_x = qobject_to(QList, x);
 145    const QList *list_y = qobject_to(QList, y);
 146    const QListEntry *entry_x, *entry_y;
 147
 148    entry_x = qlist_first(list_x);
 149    entry_y = qlist_first(list_y);
 150
 151    while (entry_x && entry_y) {
 152        if (!qobject_is_equal(qlist_entry_obj(entry_x),
 153                              qlist_entry_obj(entry_y)))
 154        {
 155            return false;
 156        }
 157
 158        entry_x = qlist_next(entry_x);
 159        entry_y = qlist_next(entry_y);
 160    }
 161
 162    return !entry_x && !entry_y;
 163}
 164
 165/**
 166 * qlist_destroy_obj(): Free all the memory allocated by a QList
 167 */
 168void qlist_destroy_obj(QObject *obj)
 169{
 170    QList *qlist;
 171    QListEntry *entry, *next_entry;
 172
 173    assert(obj != NULL);
 174    qlist = qobject_to(QList, obj);
 175
 176    QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
 177        QTAILQ_REMOVE(&qlist->head, entry, next);
 178        qobject_unref(entry->value);
 179        g_free(entry);
 180    }
 181
 182    g_free(qlist);
 183}
 184