#ifndef QEMU_OBJECT_H
#define QEMU_OBJECT_H
-#include <glib.h>
-#include <stdint.h>
-#include <stdbool.h>
+#include "qapi-types.h"
#include "qemu/queue.h"
-#include "qapi/error.h"
-
-struct Visitor;
struct TypeImpl;
typedef struct TypeImpl *Type;
* ObjectPropertyAccessor:
* @obj: the object that owns the property
* @v: the visitor that contains the property data
- * @opaque: the object property opaque
* @name: the name of the property
+ * @opaque: the object property opaque
* @errp: a pointer to an Error that is filled if getting/setting fails.
*
* Called when trying to get/set a property.
*/
typedef void (ObjectPropertyAccessor)(Object *obj,
- struct Visitor *v,
- void *opaque,
+ Visitor *v,
const char *name,
+ void *opaque,
Error **errp);
/**
ObjectPropertyResolve *resolve;
ObjectPropertyRelease *release;
void *opaque;
-
- QTAILQ_ENTRY(ObjectProperty) node;
} ObjectProperty;
/**
const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE];
ObjectUnparent *unparent;
+
+ GHashTable *properties;
};
/**
* As a result, #Object contains a reference to the objects type as its
* first member. This allows identification of the real type of the object at
* run time.
- *
- * #Object also contains a list of #Interfaces that this object
- * implements.
*/
struct Object
{
/*< private >*/
ObjectClass *class;
ObjectFree *free;
- QTAILQ_HEAD(, ObjectProperty) properties;
+ GHashTable *properties;
uint32_t ref;
Object *parent;
};
* @class_base_init: This function is called for all base classes after all
* parent class initialization has occurred, but before the class itself
* is initialized. This is the function to use to undo the effects of
- * memcpy from the parent class to the descendents.
+ * memcpy from the parent class to the descendants.
* @class_finalize: This function is called during class destruction and is
* meant to release and dynamic parameters allocated by @class_init.
* @class_data: Data to pass to the @class_init, @class_base_init and
/**
* OBJECT_CLASS_CHECK:
- * @class: The C type to use for the return value.
- * @obj: A derivative of @type to cast.
- * @name: the QOM typename of @class.
+ * @class_type: The C type to use for the return value.
+ * @class: A derivative class of @class_type to cast.
+ * @name: the QOM typename of @class_type.
*
* A type safe version of @object_class_dynamic_cast_assert. This macro is
* typically wrapped by each type to perform type safe casts of a class to a
* specific class type.
*/
-#define OBJECT_CLASS_CHECK(class, obj, name) \
- ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name), \
+#define OBJECT_CLASS_CHECK(class_type, class, name) \
+ ((class_type *)object_class_dynamic_cast_assert(OBJECT_CLASS(class), (name), \
__FILE__, __LINE__, __func__))
/**
Object *object_new(const char *typename);
/**
- * object_new_with_type:
- * @type: The type of the object to instantiate.
+ * object_new_with_props:
+ * @typename: The name of the type of the object to instantiate.
+ * @parent: the parent object
+ * @id: The unique ID of the object
+ * @errp: pointer to error object
+ * @...: list of property names and values
*
* This function will initialize a new object using heap allocated memory.
* The returned object has a reference count of 1, and will be freed when
* the last reference is dropped.
*
- * Returns: The newly allocated and instantiated object.
+ * The @id parameter will be used when registering the object as a
+ * child of @parent in the composition tree.
+ *
+ * The variadic parameters are a list of pairs of (propname, propvalue)
+ * strings. The propname of %NULL indicates the end of the property
+ * list. If the object implements the user creatable interface, the
+ * object will be marked complete once all the properties have been
+ * processed.
+ *
+ * <example>
+ * <title>Creating an object with properties</title>
+ * <programlisting>
+ * Error *err = NULL;
+ * Object *obj;
+ *
+ * obj = object_new_with_props(TYPE_MEMORY_BACKEND_FILE,
+ * object_get_objects_root(),
+ * "hostmem0",
+ * &err,
+ * "share", "yes",
+ * "mem-path", "/dev/shm/somefile",
+ * "prealloc", "yes",
+ * "size", "1048576",
+ * NULL);
+ *
+ * if (!obj) {
+ * g_printerr("Cannot create memory backend: %s\n",
+ * error_get_pretty(err));
+ * }
+ * </programlisting>
+ * </example>
+ *
+ * The returned object will have one stable reference maintained
+ * for as long as it is present in the object hierarchy.
+ *
+ * Returns: The newly allocated, instantiated & initialized object.
*/
-Object *object_new_with_type(Type type);
+Object *object_new_with_props(const char *typename,
+ Object *parent,
+ const char *id,
+ Error **errp,
+ ...) QEMU_SENTINEL;
/**
- * object_initialize_with_type:
- * @data: A pointer to the memory to be used for the object.
- * @size: The maximum size available at @data for the object.
- * @type: The type of the object to instantiate.
+ * object_new_with_propv:
+ * @typename: The name of the type of the object to instantiate.
+ * @parent: the parent object
+ * @id: The unique ID of the object
+ * @errp: pointer to error object
+ * @vargs: list of property names and values
*
- * This function will initialize an object. The memory for the object should
- * have already been allocated. The returned object has a reference count of 1,
- * and will be finalized when the last reference is dropped.
+ * See object_new_with_props() for documentation.
+ */
+Object *object_new_with_propv(const char *typename,
+ Object *parent,
+ const char *id,
+ Error **errp,
+ va_list vargs);
+
+/**
+ * object_set_props:
+ * @obj: the object instance to set properties on
+ * @errp: pointer to error object
+ * @...: list of property names and values
+ *
+ * This function will set a list of properties on an existing object
+ * instance.
+ *
+ * The variadic parameters are a list of pairs of (propname, propvalue)
+ * strings. The propname of %NULL indicates the end of the property
+ * list.
+ *
+ * <example>
+ * <title>Update an object's properties</title>
+ * <programlisting>
+ * Error *err = NULL;
+ * Object *obj = ...get / create object...;
+ *
+ * obj = object_set_props(obj,
+ * &err,
+ * "share", "yes",
+ * "mem-path", "/dev/shm/somefile",
+ * "prealloc", "yes",
+ * "size", "1048576",
+ * NULL);
+ *
+ * if (!obj) {
+ * g_printerr("Cannot set properties: %s\n",
+ * error_get_pretty(err));
+ * }
+ * </programlisting>
+ * </example>
+ *
+ * The returned object will have one stable reference maintained
+ * for as long as it is present in the object hierarchy.
+ *
+ * Returns: -1 on error, 0 on success
*/
-void object_initialize_with_type(void *data, size_t size, Type type);
+int object_set_props(Object *obj,
+ Error **errp,
+ ...) QEMU_SENTINEL;
+
+/**
+ * object_set_propv:
+ * @obj: the object instance to set properties on
+ * @errp: pointer to error object
+ * @vargs: list of property names and values
+ *
+ * See object_set_props() for documentation.
+ *
+ * Returns: -1 on error, 0 on success
+ */
+int object_set_propv(Object *obj,
+ Error **errp,
+ va_list vargs);
/**
* object_initialize:
*
* Returns: The QOM typename of @obj.
*/
-const char *object_get_typename(Object *obj);
+const char *object_get_typename(const Object *obj);
/**
* type_register_static:
void object_ref(Object *obj);
/**
- * qdef_unref:
+ * object_unref:
* @obj: the object
*
* Decrease the reference count of a object. A object cannot be freed as long
void object_property_del(Object *obj, const char *name, Error **errp);
+ObjectProperty *object_class_property_add(ObjectClass *klass, const char *name,
+ const char *type,
+ ObjectPropertyAccessor *get,
+ ObjectPropertyAccessor *set,
+ ObjectPropertyRelease *release,
+ void *opaque, Error **errp);
+
/**
* object_property_find:
* @obj: the object
*/
ObjectProperty *object_property_find(Object *obj, const char *name,
Error **errp);
+ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
+ Error **errp);
+
+typedef struct ObjectPropertyIterator {
+ ObjectClass *nextclass;
+ GHashTableIter iter;
+} ObjectPropertyIterator;
+
+/**
+ * object_property_iter_init:
+ * @obj: the object
+ *
+ * Initializes an iterator for traversing all properties
+ * registered against an object instance, its class and all parent classes.
+ *
+ * It is forbidden to modify the property list while iterating,
+ * whether removing or adding properties.
+ *
+ * Typical usage pattern would be
+ *
+ * <example>
+ * <title>Using object property iterators</title>
+ * <programlisting>
+ * ObjectProperty *prop;
+ * ObjectPropertyIterator iter;
+ *
+ * object_property_iter_init(&iter, obj);
+ * while ((prop = object_property_iter_next(&iter))) {
+ * ... do something with prop ...
+ * }
+ * </programlisting>
+ * </example>
+ */
+void object_property_iter_init(ObjectPropertyIterator *iter,
+ Object *obj);
+
+/**
+ * object_property_iter_next:
+ * @iter: the iterator instance
+ *
+ * Return the next available property. If no further properties
+ * are available, a %NULL value will be returned and the @iter
+ * pointer should not be used again after this point without
+ * re-initializing it.
+ *
+ * Returns: the next property, or %NULL when all properties
+ * have been traversed.
+ */
+ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter);
void object_unparent(Object *obj);
*
* Reads a property from a object.
*/
-void object_property_get(Object *obj, struct Visitor *v, const char *name,
+void object_property_get(Object *obj, Visitor *v, const char *name,
Error **errp);
/**
* @name: the name of the property
* @errp: returns an error if this function fails
*
- * Returns: the value of the property, converted to an integer, or NULL if
+ * Returns: the value of the property, converted to an integer, or negative if
* an error occurs (including when the property value is not an integer).
*/
int64_t object_property_get_int(Object *obj, const char *name,
Error **errp);
+/**
+ * object_property_set_uint:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an unsigned integer value to a property.
+ */
+void object_property_set_uint(Object *obj, uint64_t value,
+ const char *name, Error **errp);
+
+/**
+ * object_property_get_uint:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an unsigned integer, or 0
+ * an error occurs (including when the property value is not an integer).
+ */
+uint64_t object_property_get_uint(Object *obj, const char *name,
+ Error **errp);
+
/**
* object_property_get_enum:
* @obj: the object
* @name: the name of the property
- * @strings: strings corresponding to enums
+ * @typename: the name of the enum data type
* @errp: returns an error if this function fails
*
* Returns: the value of the property, converted to an integer, or
* an enum).
*/
int object_property_get_enum(Object *obj, const char *name,
- const char *strings[], Error **errp);
+ const char *typename, Error **errp);
/**
* object_property_get_uint16List:
*
* Writes a property to a object.
*/
-void object_property_set(Object *obj, struct Visitor *v, const char *name,
+void object_property_set(Object *obj, Visitor *v, const char *name,
Error **errp);
/**
*/
Object *object_get_root(void);
+
+/**
+ * object_get_objects_root:
+ *
+ * Get the container object that holds user created
+ * object instances. This is the object at path
+ * "/objects"
+ *
+ * Returns: the user object container
+ */
+Object *object_get_objects_root(void);
+
/**
* object_get_canonical_path_component:
*
* callback function. It allows the link property to be set and never returns
* an error.
*/
-void object_property_allow_set_link(Object *, const char *,
+void object_property_allow_set_link(const Object *, const char *,
Object *, Error **);
/**
*/
void object_property_add_link(Object *obj, const char *name,
const char *type, Object **child,
- void (*check)(Object *obj, const char *name,
+ void (*check)(const Object *obj, const char *name,
Object *val, Error **errp),
ObjectPropertyLinkFlags flags,
Error **errp);
void (*set)(Object *, const char *, Error **),
Error **errp);
+void object_class_property_add_str(ObjectClass *klass, const char *name,
+ char *(*get)(Object *, Error **),
+ void (*set)(Object *, const char *,
+ Error **),
+ Error **errp);
+
/**
* object_property_add_bool:
* @obj: the object to add a property to
void (*set)(Object *, bool, Error **),
Error **errp);
+void object_class_property_add_bool(ObjectClass *klass, const char *name,
+ bool (*get)(Object *, Error **),
+ void (*set)(Object *, bool, Error **),
+ Error **errp);
+
+/**
+ * object_property_add_enum:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @typename: the name of the enum data type
+ * @get: the getter or %NULL if the property is write-only.
+ * @set: the setter or %NULL if the property is read-only
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an enum property using getters/setters. This function will add a
+ * property of type '@typename'.
+ */
+void object_property_add_enum(Object *obj, const char *name,
+ const char *typename,
+ const QEnumLookup *lookup,
+ int (*get)(Object *, Error **),
+ void (*set)(Object *, int, Error **),
+ Error **errp);
+
+void object_class_property_add_enum(ObjectClass *klass, const char *name,
+ const char *typename,
+ const QEnumLookup *lookup,
+ int (*get)(Object *, Error **),
+ void (*set)(Object *, int, Error **),
+ Error **errp);
+
/**
* object_property_add_tm:
* @obj: the object to add a property to
void (*get)(Object *, struct tm *, Error **),
Error **errp);
+void object_class_property_add_tm(ObjectClass *klass, const char *name,
+ void (*get)(Object *, struct tm *, Error **),
+ Error **errp);
+
/**
* object_property_add_uint8_ptr:
* @obj: the object to add a property to
*/
void object_property_add_uint8_ptr(Object *obj, const char *name,
const uint8_t *v, Error **errp);
+void object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
+ const uint8_t *v, Error **errp);
/**
* object_property_add_uint16_ptr:
*/
void object_property_add_uint16_ptr(Object *obj, const char *name,
const uint16_t *v, Error **errp);
+void object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
+ const uint16_t *v, Error **errp);
/**
* object_property_add_uint32_ptr:
*/
void object_property_add_uint32_ptr(Object *obj, const char *name,
const uint32_t *v, Error **errp);
+void object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
+ const uint32_t *v, Error **errp);
/**
* object_property_add_uint64_ptr:
*/
void object_property_add_uint64_ptr(Object *obj, const char *name,
const uint64_t *v, Error **Errp);
+void object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
+ const uint64_t *v, Error **Errp);
/**
* object_property_add_alias:
Object *target_obj, const char *target_name,
Error **errp);
+/**
+ * object_property_add_const_link:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @target: the object to be referred by the link
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add an unmodifiable link for a property on an object. This function will
+ * add a property of type link<TYPE> where TYPE is the type of @target.
+ *
+ * The caller must ensure that @target stays alive as long as
+ * this property exists. In the case @target is a child of @obj,
+ * this will be the case. Otherwise, the caller is responsible for
+ * taking a reference.
+ */
+void object_property_add_const_link(Object *obj, const char *name,
+ Object *target, Error **errp);
+
/**
* object_property_set_description:
* @obj: the object owning the property
*/
void object_property_set_description(Object *obj, const char *name,
const char *description, Error **errp);
+void object_class_property_set_description(ObjectClass *klass, const char *name,
+ const char *description,
+ Error **errp);
/**
* object_child_foreach:
* Call @fn passing each child of @obj and @opaque to it, until @fn returns
* non-zero.
*
+ * It is forbidden to add or remove children from @obj from the @fn
+ * callback.
+ *
* Returns: The last value returned by @fn, or 0 if there is no child.
*/
int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
void *opaque);
+/**
+ * object_child_foreach_recursive:
+ * @obj: the object whose children will be navigated
+ * @fn: the iterator function to be called
+ * @opaque: an opaque value that will be passed to the iterator
+ *
+ * Call @fn passing each child of @obj and @opaque to it, until @fn returns
+ * non-zero. Calls recursively, all child nodes of @obj will also be passed
+ * all the way down to the leaf nodes of the tree. Depth first ordering.
+ *
+ * It is forbidden to add or remove children from @obj (or its
+ * child nodes) from the @fn callback.
+ *
+ * Returns: The last value returned by @fn, or 0 if there is no child.
+ */
+int object_child_foreach_recursive(Object *obj,
+ int (*fn)(Object *child, void *opaque),
+ void *opaque);
/**
* container_get:
* @root: root of the #path, e.g., object_get_root()
*/
Object *container_get(Object *root, const char *path);
-
+/**
+ * object_type_get_instance_size:
+ * @typename: Name of the Type whose instance_size is required
+ *
+ * Returns the instance_size of the given @typename.
+ */
+size_t object_type_get_instance_size(const char *typename);
#endif