1a6fd08ebSLuiz Capitulino /* 241836a9fSLuiz Capitulino * QList Module 3a6fd08ebSLuiz Capitulino * 4a6fd08ebSLuiz Capitulino * Copyright (C) 2009 Red Hat Inc. 5a6fd08ebSLuiz Capitulino * 6a6fd08ebSLuiz Capitulino * Authors: 7a6fd08ebSLuiz Capitulino * Luiz Capitulino <lcapitulino@redhat.com> 8a6fd08ebSLuiz Capitulino * 941836a9fSLuiz Capitulino * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 1041836a9fSLuiz Capitulino * See the COPYING.LIB file in the top-level directory. 11a6fd08ebSLuiz Capitulino */ 1241836a9fSLuiz Capitulino 13*7b1b5d19SPaolo Bonzini #include "qapi/qmp/qlist.h" 14*7b1b5d19SPaolo Bonzini #include "qapi/qmp/qobject.h" 15a6fd08ebSLuiz Capitulino #include "qemu-queue.h" 16a6fd08ebSLuiz Capitulino #include "qemu-common.h" 17a6fd08ebSLuiz Capitulino 18a6fd08ebSLuiz Capitulino static void qlist_destroy_obj(QObject *obj); 19a6fd08ebSLuiz Capitulino 20a6fd08ebSLuiz Capitulino static const QType qlist_type = { 21a6fd08ebSLuiz Capitulino .code = QTYPE_QLIST, 22a6fd08ebSLuiz Capitulino .destroy = qlist_destroy_obj, 23a6fd08ebSLuiz Capitulino }; 24a6fd08ebSLuiz Capitulino 25a6fd08ebSLuiz Capitulino /** 26a6fd08ebSLuiz Capitulino * qlist_new(): Create a new QList 27a6fd08ebSLuiz Capitulino * 28a6fd08ebSLuiz Capitulino * Return strong reference. 29a6fd08ebSLuiz Capitulino */ 30a6fd08ebSLuiz Capitulino QList *qlist_new(void) 31a6fd08ebSLuiz Capitulino { 32a6fd08ebSLuiz Capitulino QList *qlist; 33a6fd08ebSLuiz Capitulino 347267c094SAnthony Liguori qlist = g_malloc(sizeof(*qlist)); 35a6fd08ebSLuiz Capitulino QTAILQ_INIT(&qlist->head); 36a6fd08ebSLuiz Capitulino QOBJECT_INIT(qlist, &qlist_type); 37a6fd08ebSLuiz Capitulino 38a6fd08ebSLuiz Capitulino return qlist; 39a6fd08ebSLuiz Capitulino } 40a6fd08ebSLuiz Capitulino 41033815feSAnthony Liguori static void qlist_copy_elem(QObject *obj, void *opaque) 42033815feSAnthony Liguori { 43033815feSAnthony Liguori QList *dst = opaque; 44033815feSAnthony Liguori 45033815feSAnthony Liguori qobject_incref(obj); 46033815feSAnthony Liguori qlist_append_obj(dst, obj); 47033815feSAnthony Liguori } 48033815feSAnthony Liguori 49033815feSAnthony Liguori QList *qlist_copy(QList *src) 50033815feSAnthony Liguori { 51033815feSAnthony Liguori QList *dst = qlist_new(); 52033815feSAnthony Liguori 53033815feSAnthony Liguori qlist_iter(src, qlist_copy_elem, dst); 54033815feSAnthony Liguori 55033815feSAnthony Liguori return dst; 56033815feSAnthony Liguori } 57033815feSAnthony Liguori 58a6fd08ebSLuiz Capitulino /** 59a6fd08ebSLuiz Capitulino * qlist_append_obj(): Append an QObject into QList 60a6fd08ebSLuiz Capitulino * 61a6fd08ebSLuiz Capitulino * NOTE: ownership of 'value' is transferred to the QList 62a6fd08ebSLuiz Capitulino */ 63a6fd08ebSLuiz Capitulino void qlist_append_obj(QList *qlist, QObject *value) 64a6fd08ebSLuiz Capitulino { 65a6fd08ebSLuiz Capitulino QListEntry *entry; 66a6fd08ebSLuiz Capitulino 677267c094SAnthony Liguori entry = g_malloc(sizeof(*entry)); 68a6fd08ebSLuiz Capitulino entry->value = value; 69a6fd08ebSLuiz Capitulino 70a6fd08ebSLuiz Capitulino QTAILQ_INSERT_TAIL(&qlist->head, entry, next); 71a6fd08ebSLuiz Capitulino } 72a6fd08ebSLuiz Capitulino 73a6fd08ebSLuiz Capitulino /** 74a6fd08ebSLuiz Capitulino * qlist_iter(): Iterate over all the list's stored values. 75a6fd08ebSLuiz Capitulino * 76a6fd08ebSLuiz Capitulino * This function allows the user to provide an iterator, which will be 77a6fd08ebSLuiz Capitulino * called for each stored value in the list. 78a6fd08ebSLuiz Capitulino */ 79a6fd08ebSLuiz Capitulino void qlist_iter(const QList *qlist, 80a6fd08ebSLuiz Capitulino void (*iter)(QObject *obj, void *opaque), void *opaque) 81a6fd08ebSLuiz Capitulino { 82a6fd08ebSLuiz Capitulino QListEntry *entry; 83a6fd08ebSLuiz Capitulino 84a6fd08ebSLuiz Capitulino QTAILQ_FOREACH(entry, &qlist->head, next) 85a6fd08ebSLuiz Capitulino iter(entry->value, opaque); 86a6fd08ebSLuiz Capitulino } 87a6fd08ebSLuiz Capitulino 88033815feSAnthony Liguori QObject *qlist_pop(QList *qlist) 89033815feSAnthony Liguori { 90033815feSAnthony Liguori QListEntry *entry; 91033815feSAnthony Liguori QObject *ret; 92033815feSAnthony Liguori 93033815feSAnthony Liguori if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { 94033815feSAnthony Liguori return NULL; 95033815feSAnthony Liguori } 96033815feSAnthony Liguori 97033815feSAnthony Liguori entry = QTAILQ_FIRST(&qlist->head); 98033815feSAnthony Liguori QTAILQ_REMOVE(&qlist->head, entry, next); 99033815feSAnthony Liguori 100033815feSAnthony Liguori ret = entry->value; 1017267c094SAnthony Liguori g_free(entry); 102033815feSAnthony Liguori 103033815feSAnthony Liguori return ret; 104033815feSAnthony Liguori } 105033815feSAnthony Liguori 106033815feSAnthony Liguori QObject *qlist_peek(QList *qlist) 107033815feSAnthony Liguori { 108033815feSAnthony Liguori QListEntry *entry; 109033815feSAnthony Liguori QObject *ret; 110033815feSAnthony Liguori 111033815feSAnthony Liguori if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { 112033815feSAnthony Liguori return NULL; 113033815feSAnthony Liguori } 114033815feSAnthony Liguori 115033815feSAnthony Liguori entry = QTAILQ_FIRST(&qlist->head); 116033815feSAnthony Liguori 117033815feSAnthony Liguori ret = entry->value; 118033815feSAnthony Liguori 119033815feSAnthony Liguori return ret; 120033815feSAnthony Liguori } 121033815feSAnthony Liguori 122033815feSAnthony Liguori int qlist_empty(const QList *qlist) 123033815feSAnthony Liguori { 124033815feSAnthony Liguori return QTAILQ_EMPTY(&qlist->head); 125033815feSAnthony Liguori } 126033815feSAnthony Liguori 127a86a4c2fSMichael Roth static void qlist_size_iter(QObject *obj, void *opaque) 128a86a4c2fSMichael Roth { 129a86a4c2fSMichael Roth size_t *count = opaque; 130a86a4c2fSMichael Roth (*count)++; 131a86a4c2fSMichael Roth } 132a86a4c2fSMichael Roth 133a86a4c2fSMichael Roth size_t qlist_size(const QList *qlist) 134a86a4c2fSMichael Roth { 135a86a4c2fSMichael Roth size_t count = 0; 136a86a4c2fSMichael Roth qlist_iter(qlist, qlist_size_iter, &count); 137a86a4c2fSMichael Roth return count; 138a86a4c2fSMichael Roth } 139a86a4c2fSMichael Roth 140a6fd08ebSLuiz Capitulino /** 141a6fd08ebSLuiz Capitulino * qobject_to_qlist(): Convert a QObject into a QList 142a6fd08ebSLuiz Capitulino */ 143a6fd08ebSLuiz Capitulino QList *qobject_to_qlist(const QObject *obj) 144a6fd08ebSLuiz Capitulino { 145a6fd08ebSLuiz Capitulino if (qobject_type(obj) != QTYPE_QLIST) { 146a6fd08ebSLuiz Capitulino return NULL; 147a6fd08ebSLuiz Capitulino } 148a6fd08ebSLuiz Capitulino 149a6fd08ebSLuiz Capitulino return container_of(obj, QList, base); 150a6fd08ebSLuiz Capitulino } 151a6fd08ebSLuiz Capitulino 152a6fd08ebSLuiz Capitulino /** 153a6fd08ebSLuiz Capitulino * qlist_destroy_obj(): Free all the memory allocated by a QList 154a6fd08ebSLuiz Capitulino */ 155a6fd08ebSLuiz Capitulino static void qlist_destroy_obj(QObject *obj) 156a6fd08ebSLuiz Capitulino { 157a6fd08ebSLuiz Capitulino QList *qlist; 158a6fd08ebSLuiz Capitulino QListEntry *entry, *next_entry; 159a6fd08ebSLuiz Capitulino 160a6fd08ebSLuiz Capitulino assert(obj != NULL); 161a6fd08ebSLuiz Capitulino qlist = qobject_to_qlist(obj); 162a6fd08ebSLuiz Capitulino 163a6fd08ebSLuiz Capitulino QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) { 164a6fd08ebSLuiz Capitulino QTAILQ_REMOVE(&qlist->head, entry, next); 165a6fd08ebSLuiz Capitulino qobject_decref(entry->value); 1667267c094SAnthony Liguori g_free(entry); 167a6fd08ebSLuiz Capitulino } 168a6fd08ebSLuiz Capitulino 1697267c094SAnthony Liguori g_free(qlist); 170a6fd08ebSLuiz Capitulino } 171