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