qapi: Add qobject_to()
This is a dynamic casting macro that, given a QObject type, returns an object as that type or NULL if the object is of a different type (or NULL itself). The macro uses lower-case letters because: 1. There does not seem to be a hard rule on whether qemu macros have to be upper-cased, 2. The current situation in qapi/qmp is inconsistent (compare e.g. QINCREF() vs. qdict_put()), 3. qobject_to() will evaluate its @obj parameter only once, thus it is generally not important to the caller whether it is a macro or not, 4. I prefer it aesthetically. The macro parameter order is chosen with typename first for consistency with other QAPI macros like QAPI_CLONE(), as well as for legibility (read it as "qobject to" type "applied to" obj). Signed-off-by: Max Reitz <mreitz@redhat.com> Message-Id: <20180224154033.29559-3-mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com> [eblake: swap parameter order to list type first, avoid clang ubsan warning on QOBJECT(NULL) and container_of(NULL,type,base)] Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
9139b56723
commit
1a56b1e2ab
@ -50,6 +50,21 @@ struct QObject {
|
||||
#define QDECREF(obj) \
|
||||
qobject_decref(obj ? QOBJECT(obj) : NULL)
|
||||
|
||||
/* Required for qobject_to() */
|
||||
#define QTYPE_CAST_TO_QNull QTYPE_QNULL
|
||||
#define QTYPE_CAST_TO_QNum QTYPE_QNUM
|
||||
#define QTYPE_CAST_TO_QString QTYPE_QSTRING
|
||||
#define QTYPE_CAST_TO_QDict QTYPE_QDICT
|
||||
#define QTYPE_CAST_TO_QList QTYPE_QLIST
|
||||
#define QTYPE_CAST_TO_QBool QTYPE_QBOOL
|
||||
|
||||
QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7,
|
||||
"The QTYPE_CAST_TO_* list needs to be extended");
|
||||
|
||||
#define qobject_to(type, obj) ({ \
|
||||
QObject *_tmp = qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)); \
|
||||
_tmp ? container_of(_tmp, type, base) : (type *)NULL; })
|
||||
|
||||
/* Initialize an object to default values */
|
||||
static inline void qobject_init(QObject *obj, QType type)
|
||||
{
|
||||
@ -102,4 +117,18 @@ static inline QType qobject_type(const QObject *obj)
|
||||
return obj->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* qobject_check_type(): Helper function for the qobject_to() macro.
|
||||
* Return @obj, but only if @obj is not NULL and @type is equal to
|
||||
* @obj's type. Return NULL otherwise.
|
||||
*/
|
||||
static inline QObject *qobject_check_type(const QObject *obj, QType type)
|
||||
{
|
||||
if (obj && qobject_type(obj) == type) {
|
||||
return (QObject *)obj;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* QOBJECT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user