mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 02:24:58 -06:00
qom: Add object_new_with_props() / object_new_withpropv() helpers
It is reasonably common to want to create an object, set a number of properties, register it in the hierarchy and then mark it as complete (if a user creatable type). This requires quite a lot of error prone, verbose, boilerplate code to achieve. First a pair of functions object_set_props() / object_set_propv() are added which allow for a list of objects to be set in one single API call. Then object_new_with_props() / object_new_with_propv() constructors are added which simplify the sequence of calls to create an object, populate properties, register in the object composition tree and mark the object complete, into a single method call. Usage would be: Error *err = NULL; Object *obj; obj = object_new_with_propv(TYPE_MEMORY_BACKEND_FILE, object_get_objects_root(), "hostmem0", &err, "share", "yes", "mem-path", "/dev/shm/somefile", "prealloc", "yes", "size", "1048576", NULL); Note all property values are passed in string form and will be parsed into their required data types, using normal QOM semantics for parsing from string format. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
parent
bc2256c4ae
commit
a31bdae5a7
6 changed files with 434 additions and 1 deletions
109
qom/object.c
109
qom/object.c
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "qom/object.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "qapi-visit.h"
|
||||
|
@ -439,6 +440,114 @@ Object *object_new(const char *typename)
|
|||
return object_new_with_type(ti);
|
||||
}
|
||||
|
||||
|
||||
Object *object_new_with_props(const char *typename,
|
||||
Object *parent,
|
||||
const char *id,
|
||||
Error **errp,
|
||||
...)
|
||||
{
|
||||
va_list vargs;
|
||||
Object *obj;
|
||||
|
||||
va_start(vargs, errp);
|
||||
obj = object_new_with_propv(typename, parent, id, errp, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
Object *object_new_with_propv(const char *typename,
|
||||
Object *parent,
|
||||
const char *id,
|
||||
Error **errp,
|
||||
va_list vargs)
|
||||
{
|
||||
Object *obj;
|
||||
ObjectClass *klass;
|
||||
Error *local_err = NULL;
|
||||
|
||||
klass = object_class_by_name(typename);
|
||||
if (!klass) {
|
||||
error_setg(errp, "invalid object type: %s", typename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (object_class_is_abstract(klass)) {
|
||||
error_setg(errp, "object type '%s' is abstract", typename);
|
||||
return NULL;
|
||||
}
|
||||
obj = object_new(typename);
|
||||
|
||||
if (object_set_propv(obj, &local_err, vargs) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
object_property_add_child(parent, id, obj, &local_err);
|
||||
if (local_err) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
|
||||
user_creatable_complete(obj, &local_err);
|
||||
if (local_err) {
|
||||
object_unparent(obj);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
object_unref(OBJECT(obj));
|
||||
return obj;
|
||||
|
||||
error:
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
object_unref(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int object_set_props(Object *obj,
|
||||
Error **errp,
|
||||
...)
|
||||
{
|
||||
va_list vargs;
|
||||
int ret;
|
||||
|
||||
va_start(vargs, errp);
|
||||
ret = object_set_propv(obj, errp, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int object_set_propv(Object *obj,
|
||||
Error **errp,
|
||||
va_list vargs)
|
||||
{
|
||||
const char *propname;
|
||||
Error *local_err = NULL;
|
||||
|
||||
propname = va_arg(vargs, char *);
|
||||
while (propname != NULL) {
|
||||
const char *value = va_arg(vargs, char *);
|
||||
|
||||
g_assert(value != NULL);
|
||||
object_property_parse(obj, value, propname, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return -1;
|
||||
}
|
||||
propname = va_arg(vargs, char *);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Object *object_dynamic_cast(Object *obj, const char *typename)
|
||||
{
|
||||
if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue