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