/*
 * QEMU Object Model.
 *
 * Based on ideas by Avi Kivity <avi@redhat.com>
 *
 * Copyright (C) 2009, 2015 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.
 *
 * QObject Reference Counts Terminology
 * ------------------------------------
 *
 *  - Returning references: A function that returns an object may
 *  return it as either a weak or a strong reference.  If the
 *  reference is strong, you are responsible for calling
 *  qobject_unref() on the reference when you are done.
 *
 *  If the reference is weak, the owner of the reference may free it at
 *  any time in the future.  Before storing the reference anywhere, you
 *  should call qobject_ref() to make the reference strong.
 *
 *  - Transferring ownership: when you transfer ownership of a reference
 *  by calling a function, you are no longer responsible for calling
 *  qobject_unref() when the reference is no longer needed.  In other words,
 *  when the function returns you must behave as if the reference to the
 *  passed object was weak.
 */
#ifndef QOBJECT_H
#define QOBJECT_H

#include "qapi/qapi-builtin-types.h"

/* Not for use outside include/qapi/qmp/ */
struct QObjectBase_ {
    QType type;
    size_t refcnt;
};

/* this struct must have no other members than base */
struct QObject {
    struct QObjectBase_ base;
};

#define QOBJECT(obj) ({                                         \
    typeof(obj) _obj = (obj);                                   \
    _obj ? container_of(&(_obj)->base, QObject, base) : 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)                                       \
    ((type *)qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)))

/* Initialize an object to default values */
static inline void qobject_init(QObject *obj, QType type)
{
    assert(QTYPE_NONE < type && type < QTYPE__MAX);
    obj->base.refcnt = 1;
    obj->base.type = type;
}

static inline void qobject_ref_impl(QObject *obj)
{
    if (obj) {
        obj->base.refcnt++;
    }
}

/**
 * qobject_is_equal(): Return whether the two objects are equal.
 *
 * Any of the pointers may be NULL; return true if both are.  Always
 * return false if only one is (therefore a QNull object is not
 * considered equal to a NULL pointer).
 */
bool qobject_is_equal(const QObject *x, const QObject *y);

/**
 * qobject_destroy(): Free resources used by the object
 */
void qobject_destroy(QObject *obj);

static inline void qobject_unref_impl(QObject *obj)
{
    assert(!obj || obj->base.refcnt);
    if (obj && --obj->base.refcnt == 0) {
        qobject_destroy(obj);
    }
}

/**
 * qobject_ref(): Increment QObject's reference count
 *
 * Returns: the same @obj. The type of @obj will be propagated to the
 * return type.
 */
#define qobject_ref(obj) ({                     \
    typeof(obj) _o = (obj);                     \
    qobject_ref_impl(QOBJECT(_o));              \
    _o;                                         \
})

/**
 * qobject_unref(): Decrement QObject's reference count, deallocate
 * when it reaches zero
 */
#define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))

/**
 * qobject_type(): Return the QObject's type
 */
static inline QType qobject_type(const QObject *obj)
{
    assert(QTYPE_NONE < obj->base.type && obj->base.type < QTYPE__MAX);
    return obj->base.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 */
