155e1819cSEric Blake /*
255e1819cSEric Blake * QObject
355e1819cSEric Blake *
455e1819cSEric Blake * Copyright (C) 2015 Red Hat, Inc.
555e1819cSEric Blake *
655e1819cSEric Blake * This work is licensed under the terms of the GNU LGPL, version 2.1
755e1819cSEric Blake * or later. See the COPYING.LIB file in the top-level directory.
855e1819cSEric Blake */
955e1819cSEric Blake
10f2ad72b3SPeter Maydell #include "qemu/osdep.h"
116b673957SMarkus Armbruster #include "qapi/qmp/qbool.h"
1215280c36SMarkus Armbruster #include "qapi/qmp/qnull.h"
1315280c36SMarkus Armbruster #include "qapi/qmp/qnum.h"
146b673957SMarkus Armbruster #include "qapi/qmp/qdict.h"
1547e6b297SMarkus Armbruster #include "qapi/qmp/qlist.h"
166b673957SMarkus Armbruster #include "qapi/qmp/qstring.h"
17*80d71121SMarkus Armbruster #include "qobject-internal.h"
1855e1819cSEric Blake
197ee9edfdSMarc-André Lureau QEMU_BUILD_BUG_MSG(
207ee9edfdSMarc-André Lureau offsetof(QNull, base) != 0 ||
217ee9edfdSMarc-André Lureau offsetof(QNum, base) != 0 ||
227ee9edfdSMarc-André Lureau offsetof(QString, base) != 0 ||
237ee9edfdSMarc-André Lureau offsetof(QDict, base) != 0 ||
247ee9edfdSMarc-André Lureau offsetof(QList, base) != 0 ||
257ee9edfdSMarc-André Lureau offsetof(QBool, base) != 0,
267ee9edfdSMarc-André Lureau "base qobject must be at offset 0");
277ee9edfdSMarc-André Lureau
287264f5c5SEric Blake static void (*qdestroy[QTYPE__MAX])(QObject *) = {
2955e1819cSEric Blake [QTYPE_NONE] = NULL, /* No such object exists */
3055e1819cSEric Blake [QTYPE_QNULL] = NULL, /* qnull_ is indestructible */
3101b2ffceSMarc-André Lureau [QTYPE_QNUM] = qnum_destroy_obj,
3255e1819cSEric Blake [QTYPE_QSTRING] = qstring_destroy_obj,
3355e1819cSEric Blake [QTYPE_QDICT] = qdict_destroy_obj,
3455e1819cSEric Blake [QTYPE_QLIST] = qlist_destroy_obj,
3555e1819cSEric Blake [QTYPE_QBOOL] = qbool_destroy_obj,
3655e1819cSEric Blake };
3755e1819cSEric Blake
qobject_destroy(QObject * obj)3855e1819cSEric Blake void qobject_destroy(QObject *obj)
3955e1819cSEric Blake {
403d3eacaeSMarc-André Lureau assert(!obj->base.refcnt);
413d3eacaeSMarc-André Lureau assert(QTYPE_QNULL < obj->base.type && obj->base.type < QTYPE__MAX);
423d3eacaeSMarc-André Lureau qdestroy[obj->base.type](obj);
4355e1819cSEric Blake }
44b38dd678SMax Reitz
45b38dd678SMax Reitz
46b38dd678SMax Reitz static bool (*qis_equal[QTYPE__MAX])(const QObject *, const QObject *) = {
47b38dd678SMax Reitz [QTYPE_NONE] = NULL, /* No such object exists */
48b38dd678SMax Reitz [QTYPE_QNULL] = qnull_is_equal,
49b38dd678SMax Reitz [QTYPE_QNUM] = qnum_is_equal,
50b38dd678SMax Reitz [QTYPE_QSTRING] = qstring_is_equal,
51b38dd678SMax Reitz [QTYPE_QDICT] = qdict_is_equal,
52b38dd678SMax Reitz [QTYPE_QLIST] = qlist_is_equal,
53b38dd678SMax Reitz [QTYPE_QBOOL] = qbool_is_equal,
54b38dd678SMax Reitz };
55b38dd678SMax Reitz
qobject_is_equal(const QObject * x,const QObject * y)56b38dd678SMax Reitz bool qobject_is_equal(const QObject *x, const QObject *y)
57b38dd678SMax Reitz {
58b38dd678SMax Reitz /* We cannot test x == y because an object does not need to be
59b38dd678SMax Reitz * equal to itself (e.g. NaN floats are not). */
60b38dd678SMax Reitz
61b38dd678SMax Reitz if (!x && !y) {
62b38dd678SMax Reitz return true;
63b38dd678SMax Reitz }
64b38dd678SMax Reitz
653d3eacaeSMarc-André Lureau if (!x || !y || x->base.type != y->base.type) {
66b38dd678SMax Reitz return false;
67b38dd678SMax Reitz }
68b38dd678SMax Reitz
693d3eacaeSMarc-André Lureau assert(QTYPE_NONE < x->base.type && x->base.type < QTYPE__MAX);
70b38dd678SMax Reitz
713d3eacaeSMarc-André Lureau return qis_equal[x->base.type](x, y);
72b38dd678SMax Reitz }
73