2015-12-02 05:20:45 +00:00
|
|
|
/*
|
|
|
|
* QObject
|
|
|
|
*
|
|
|
|
* Copyright (C) 2015 Red Hat, Inc.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2016-01-29 17:50:01 +00:00
|
|
|
#include "qemu/osdep.h"
|
2015-12-02 05:20:45 +00:00
|
|
|
#include "qemu-common.h"
|
2018-02-01 11:18:35 +00:00
|
|
|
#include "qapi/qmp/qbool.h"
|
2018-02-01 11:18:36 +00:00
|
|
|
#include "qapi/qmp/qnull.h"
|
|
|
|
#include "qapi/qmp/qnum.h"
|
2018-02-01 11:18:35 +00:00
|
|
|
#include "qapi/qmp/qdict.h"
|
2018-02-01 11:18:38 +00:00
|
|
|
#include "qapi/qmp/qlist.h"
|
2018-02-01 11:18:35 +00:00
|
|
|
#include "qapi/qmp/qstring.h"
|
2015-12-02 05:20:45 +00:00
|
|
|
|
2018-04-19 15:01:41 +00:00
|
|
|
QEMU_BUILD_BUG_MSG(
|
|
|
|
offsetof(QNull, base) != 0 ||
|
|
|
|
offsetof(QNum, base) != 0 ||
|
|
|
|
offsetof(QString, base) != 0 ||
|
|
|
|
offsetof(QDict, base) != 0 ||
|
|
|
|
offsetof(QList, base) != 0 ||
|
|
|
|
offsetof(QBool, base) != 0,
|
|
|
|
"base qobject must be at offset 0");
|
|
|
|
|
qapi: Convert QType into QAPI built-in enum type
What's more meta than using qapi to define qapi? :)
Convert QType into a full-fledged[*] builtin qapi enum type, so
that a subsequent patch can then use it as the discriminator
type of qapi alternate types. Fortunately, the judicious use of
'prefix' in the qapi definition avoids churn to the spelling of
the enum constants.
To avoid circular definitions, we have to flip the order of
inclusion between "qobject.h" vs. "qapi-types.h". Back in commit
28770e0, we had the latter include the former, so that we could
use 'QObject *' for our implementation of 'any'. But that usage
also works with only a forward declaration, whereas the
definition of QObject requires QType to be a complete type.
[*] The type has to be builtin, rather than declared in
qapi/common.json, because we want to use it for alternates even
when common.json is not included. But since it is the first
builtin enum type, we have to add special cases to qapi-types
and qapi-visit to only emit definitions once, even when two
qapi files are being compiled into the same binary (the way we
already handled builtin list types like 'intList'). We may
need to revisit how multiple qapi files share common types,
but that's a project for another day.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1449033659-25497-4-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-12-02 05:20:47 +00:00
|
|
|
static void (*qdestroy[QTYPE__MAX])(QObject *) = {
|
2015-12-02 05:20:45 +00:00
|
|
|
[QTYPE_NONE] = NULL, /* No such object exists */
|
|
|
|
[QTYPE_QNULL] = NULL, /* qnull_ is indestructible */
|
2017-06-07 16:35:58 +00:00
|
|
|
[QTYPE_QNUM] = qnum_destroy_obj,
|
2015-12-02 05:20:45 +00:00
|
|
|
[QTYPE_QSTRING] = qstring_destroy_obj,
|
|
|
|
[QTYPE_QDICT] = qdict_destroy_obj,
|
|
|
|
[QTYPE_QLIST] = qlist_destroy_obj,
|
|
|
|
[QTYPE_QBOOL] = qbool_destroy_obj,
|
|
|
|
};
|
|
|
|
|
|
|
|
void qobject_destroy(QObject *obj)
|
|
|
|
{
|
2018-04-19 15:01:42 +00:00
|
|
|
assert(!obj->base.refcnt);
|
|
|
|
assert(QTYPE_QNULL < obj->base.type && obj->base.type < QTYPE__MAX);
|
|
|
|
qdestroy[obj->base.type](obj);
|
2015-12-02 05:20:45 +00:00
|
|
|
}
|
2017-11-14 18:01:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
static bool (*qis_equal[QTYPE__MAX])(const QObject *, const QObject *) = {
|
|
|
|
[QTYPE_NONE] = NULL, /* No such object exists */
|
|
|
|
[QTYPE_QNULL] = qnull_is_equal,
|
|
|
|
[QTYPE_QNUM] = qnum_is_equal,
|
|
|
|
[QTYPE_QSTRING] = qstring_is_equal,
|
|
|
|
[QTYPE_QDICT] = qdict_is_equal,
|
|
|
|
[QTYPE_QLIST] = qlist_is_equal,
|
|
|
|
[QTYPE_QBOOL] = qbool_is_equal,
|
|
|
|
};
|
|
|
|
|
|
|
|
bool qobject_is_equal(const QObject *x, const QObject *y)
|
|
|
|
{
|
|
|
|
/* We cannot test x == y because an object does not need to be
|
|
|
|
* equal to itself (e.g. NaN floats are not). */
|
|
|
|
|
|
|
|
if (!x && !y) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:01:42 +00:00
|
|
|
if (!x || !y || x->base.type != y->base.type) {
|
2017-11-14 18:01:25 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-04-19 15:01:42 +00:00
|
|
|
assert(QTYPE_NONE < x->base.type && x->base.type < QTYPE__MAX);
|
2017-11-14 18:01:25 +00:00
|
|
|
|
2018-04-19 15:01:42 +00:00
|
|
|
return qis_equal[x->base.type](x, y);
|
2017-11-14 18:01:25 +00:00
|
|
|
}
|