| /* | |
| * QList Module | |
| * | |
| * Copyright (C) 2009 Red Hat Inc. | |
| * | |
| * Authors: | |
| * Luiz Capitulino <lcapitulino@redhat.com> | |
| * | |
| * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. | |
| * See the COPYING.LIB file in the top-level directory. | |
| */ | |
| #include "qemu/osdep.h" | |
| #include "qobject/qbool.h" | |
| #include "qobject/qlist.h" | |
| #include "qobject/qnull.h" | |
| #include "qobject/qnum.h" | |
| #include "qobject/qstring.h" | |
| #include "qemu/queue.h" | |
| #include "qobject-internal.h" | |
| /** | |
| * qlist_new(): Create a new QList | |
| * | |
| * Return strong reference. | |
| */ | |
| QList *qlist_new(void) | |
| { | |
| QList *qlist; | |
| qlist = g_malloc(sizeof(*qlist)); | |
| qobject_init(QOBJECT(qlist), QTYPE_QLIST); | |
| QTAILQ_INIT(&qlist->head); | |
| return qlist; | |
| } | |
| QList *qlist_copy(QList *src) | |
| { | |
| QList *dst = qlist_new(); | |
| QListEntry *entry; | |
| QObject *elt; | |
| QLIST_FOREACH_ENTRY(src, entry) { | |
| elt = qlist_entry_obj(entry); | |
| qobject_ref(elt); | |
| qlist_append_obj(dst, elt); | |
| } | |
| return dst; | |
| } | |
| /** | |
| * qlist_append_obj(): Append an QObject into QList | |
| * | |
| * NOTE: ownership of 'value' is transferred to the QList | |
| */ | |
| void qlist_append_obj(QList *qlist, QObject *value) | |
| { | |
| QListEntry *entry; | |
| entry = g_malloc(sizeof(*entry)); | |
| entry->value = value; | |
| QTAILQ_INSERT_TAIL(&qlist->head, entry, next); | |
| } | |
| void qlist_append_int(QList *qlist, int64_t value) | |
| { | |
| qlist_append(qlist, qnum_from_int(value)); | |
| } | |
| void qlist_append_bool(QList *qlist, bool value) | |
| { | |
| qlist_append(qlist, qbool_from_bool(value)); | |
| } | |
| void qlist_append_str(QList *qlist, const char *value) | |
| { | |
| qlist_append(qlist, qstring_from_str(value)); | |
| } | |
| void qlist_append_null(QList *qlist) | |
| { | |
| qlist_append(qlist, qnull()); | |
| } | |
| QObject *qlist_pop(QList *qlist) | |
| { | |
| QListEntry *entry; | |
| QObject *ret; | |
| if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { | |
| return NULL; | |
| } | |
| entry = QTAILQ_FIRST(&qlist->head); | |
| QTAILQ_REMOVE(&qlist->head, entry, next); | |
| ret = entry->value; | |
| g_free(entry); | |
| return ret; | |
| } | |
| QObject *qlist_peek(QList *qlist) | |
| { | |
| QListEntry *entry; | |
| if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) { | |
| return NULL; | |
| } | |
| entry = QTAILQ_FIRST(&qlist->head); | |
| return entry->value; | |
| } | |
| int qlist_empty(const QList *qlist) | |
| { | |
| return QTAILQ_EMPTY(&qlist->head); | |
| } | |
| size_t qlist_size(const QList *qlist) | |
| { | |
| size_t count = 0; | |
| QListEntry *entry; | |
| QLIST_FOREACH_ENTRY(qlist, entry) { | |
| count++; | |
| } | |
| return count; | |
| } | |
| /** | |
| * qlist_is_equal(): Test whether the two QLists are equal | |
| * | |
| * In order to be considered equal, the respective two objects at each | |
| * index of the two lists have to compare equal (regarding | |
| * qobject_is_equal()), and both lists have to have the same number of | |
| * elements. | |
| * That means both lists have to contain equal objects in equal order. | |
| */ | |
| bool qlist_is_equal(const QObject *x, const QObject *y) | |
| { | |
| const QList *list_x = qobject_to(QList, x); | |
| const QList *list_y = qobject_to(QList, y); | |
| const QListEntry *entry_x, *entry_y; | |
| entry_x = qlist_first(list_x); | |
| entry_y = qlist_first(list_y); | |
| while (entry_x && entry_y) { | |
| if (!qobject_is_equal(qlist_entry_obj(entry_x), | |
| qlist_entry_obj(entry_y))) | |
| { | |
| return false; | |
| } | |
| entry_x = qlist_next(entry_x); | |
| entry_y = qlist_next(entry_y); | |
| } | |
| return !entry_x && !entry_y; | |
| } | |
| /** | |
| * qlist_destroy_obj(): Free all the memory allocated by a QList | |
| */ | |
| void qlist_destroy_obj(QObject *obj) | |
| { | |
| QList *qlist; | |
| QListEntry *entry, *next_entry; | |
| assert(obj != NULL); | |
| qlist = qobject_to(QList, obj); | |
| QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) { | |
| QTAILQ_REMOVE(&qlist->head, entry, next); | |
| qobject_unref(entry->value); | |
| g_free(entry); | |
| } | |
| g_free(qlist); | |
| } | |
| void qlist_unref(QList *q) | |
| { | |
| qobject_unref(q); | |
| } |