4 * Copyright IBM, Corp. 2011
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qom/object.h"
14 #include "qom/object_interfaces.h"
15 #include "qemu-common.h"
16 #include "qapi/visitor.h"
17 #include "qapi-visit.h"
18 #include "qapi/string-input-visitor.h"
19 #include "qapi/string-output-visitor.h"
20 #include "qapi/qmp/qerror.h"
23 /* TODO: replace QObject with a simpler visitor to avoid a dependency
24 * of the QOM core on QObject? */
25 #include "qom/qom-qobject.h"
26 #include "qapi/qmp/qobject.h"
27 #include "qapi/qmp/qbool.h"
28 #include "qapi/qmp/qint.h"
29 #include "qapi/qmp/qstring.h"
31 #define MAX_INTERFACES 32
33 typedef struct InterfaceImpl InterfaceImpl
;
34 typedef struct TypeImpl TypeImpl
;
49 void (*class_init
)(ObjectClass
*klass
, void *data
);
50 void (*class_base_init
)(ObjectClass
*klass
, void *data
);
51 void (*class_finalize
)(ObjectClass
*klass
, void *data
);
55 void (*instance_init
)(Object
*obj
);
56 void (*instance_post_init
)(Object
*obj
);
57 void (*instance_finalize
)(Object
*obj
);
62 TypeImpl
*parent_type
;
67 InterfaceImpl interfaces
[MAX_INTERFACES
];
70 struct ObjectPropertyIterator
{
74 static Type type_interface
;
76 static GHashTable
*type_table_get(void)
78 static GHashTable
*type_table
;
80 if (type_table
== NULL
) {
81 type_table
= g_hash_table_new(g_str_hash
, g_str_equal
);
87 static bool enumerating_types
;
89 static void type_table_add(TypeImpl
*ti
)
91 assert(!enumerating_types
);
92 g_hash_table_insert(type_table_get(), (void *)ti
->name
, ti
);
95 static TypeImpl
*type_table_lookup(const char *name
)
97 return g_hash_table_lookup(type_table_get(), name
);
100 static TypeImpl
*type_new(const TypeInfo
*info
)
102 TypeImpl
*ti
= g_malloc0(sizeof(*ti
));
105 g_assert(info
->name
!= NULL
);
107 if (type_table_lookup(info
->name
) != NULL
) {
108 fprintf(stderr
, "Registering `%s' which already exists\n", info
->name
);
112 ti
->name
= g_strdup(info
->name
);
113 ti
->parent
= g_strdup(info
->parent
);
115 ti
->class_size
= info
->class_size
;
116 ti
->instance_size
= info
->instance_size
;
118 ti
->class_init
= info
->class_init
;
119 ti
->class_base_init
= info
->class_base_init
;
120 ti
->class_finalize
= info
->class_finalize
;
121 ti
->class_data
= info
->class_data
;
123 ti
->instance_init
= info
->instance_init
;
124 ti
->instance_post_init
= info
->instance_post_init
;
125 ti
->instance_finalize
= info
->instance_finalize
;
127 ti
->abstract
= info
->abstract
;
129 for (i
= 0; info
->interfaces
&& info
->interfaces
[i
].type
; i
++) {
130 ti
->interfaces
[i
].typename
= g_strdup(info
->interfaces
[i
].type
);
132 ti
->num_interfaces
= i
;
137 static TypeImpl
*type_register_internal(const TypeInfo
*info
)
146 TypeImpl
*type_register(const TypeInfo
*info
)
148 assert(info
->parent
);
149 return type_register_internal(info
);
152 TypeImpl
*type_register_static(const TypeInfo
*info
)
154 return type_register(info
);
157 static TypeImpl
*type_get_by_name(const char *name
)
163 return type_table_lookup(name
);
166 static TypeImpl
*type_get_parent(TypeImpl
*type
)
168 if (!type
->parent_type
&& type
->parent
) {
169 type
->parent_type
= type_get_by_name(type
->parent
);
170 g_assert(type
->parent_type
!= NULL
);
173 return type
->parent_type
;
176 static bool type_has_parent(TypeImpl
*type
)
178 return (type
->parent
!= NULL
);
181 static size_t type_class_get_size(TypeImpl
*ti
)
183 if (ti
->class_size
) {
184 return ti
->class_size
;
187 if (type_has_parent(ti
)) {
188 return type_class_get_size(type_get_parent(ti
));
191 return sizeof(ObjectClass
);
194 static size_t type_object_get_size(TypeImpl
*ti
)
196 if (ti
->instance_size
) {
197 return ti
->instance_size
;
200 if (type_has_parent(ti
)) {
201 return type_object_get_size(type_get_parent(ti
));
207 static bool type_is_ancestor(TypeImpl
*type
, TypeImpl
*target_type
)
211 /* Check if target_type is a direct ancestor of type */
213 if (type
== target_type
) {
217 type
= type_get_parent(type
);
223 static void type_initialize(TypeImpl
*ti
);
225 static void type_initialize_interface(TypeImpl
*ti
, TypeImpl
*interface_type
,
226 TypeImpl
*parent_type
)
228 InterfaceClass
*new_iface
;
230 TypeImpl
*iface_impl
;
232 info
.parent
= parent_type
->name
;
233 info
.name
= g_strdup_printf("%s::%s", ti
->name
, interface_type
->name
);
234 info
.abstract
= true;
236 iface_impl
= type_new(&info
);
237 iface_impl
->parent_type
= parent_type
;
238 type_initialize(iface_impl
);
239 g_free((char *)info
.name
);
241 new_iface
= (InterfaceClass
*)iface_impl
->class;
242 new_iface
->concrete_class
= ti
->class;
243 new_iface
->interface_type
= interface_type
;
245 ti
->class->interfaces
= g_slist_append(ti
->class->interfaces
,
249 static void type_initialize(TypeImpl
*ti
)
257 ti
->class_size
= type_class_get_size(ti
);
258 ti
->instance_size
= type_object_get_size(ti
);
260 ti
->class = g_malloc0(ti
->class_size
);
262 parent
= type_get_parent(ti
);
264 type_initialize(parent
);
268 g_assert_cmpint(parent
->class_size
, <=, ti
->class_size
);
269 memcpy(ti
->class, parent
->class, parent
->class_size
);
270 ti
->class->interfaces
= NULL
;
272 for (e
= parent
->class->interfaces
; e
; e
= e
->next
) {
273 InterfaceClass
*iface
= e
->data
;
274 ObjectClass
*klass
= OBJECT_CLASS(iface
);
276 type_initialize_interface(ti
, iface
->interface_type
, klass
->type
);
279 for (i
= 0; i
< ti
->num_interfaces
; i
++) {
280 TypeImpl
*t
= type_get_by_name(ti
->interfaces
[i
].typename
);
281 for (e
= ti
->class->interfaces
; e
; e
= e
->next
) {
282 TypeImpl
*target_type
= OBJECT_CLASS(e
->data
)->type
;
284 if (type_is_ancestor(target_type
, t
)) {
293 type_initialize_interface(ti
, t
, t
);
297 ti
->class->type
= ti
;
300 if (parent
->class_base_init
) {
301 parent
->class_base_init(ti
->class, ti
->class_data
);
303 parent
= type_get_parent(parent
);
306 if (ti
->class_init
) {
307 ti
->class_init(ti
->class, ti
->class_data
);
311 static void object_init_with_type(Object
*obj
, TypeImpl
*ti
)
313 if (type_has_parent(ti
)) {
314 object_init_with_type(obj
, type_get_parent(ti
));
317 if (ti
->instance_init
) {
318 ti
->instance_init(obj
);
322 static void object_post_init_with_type(Object
*obj
, TypeImpl
*ti
)
324 if (ti
->instance_post_init
) {
325 ti
->instance_post_init(obj
);
328 if (type_has_parent(ti
)) {
329 object_post_init_with_type(obj
, type_get_parent(ti
));
333 static void object_property_free(gpointer data
)
335 ObjectProperty
*prop
= data
;
339 g_free(prop
->description
);
343 void object_initialize_with_type(void *data
, size_t size
, TypeImpl
*type
)
347 g_assert(type
!= NULL
);
348 type_initialize(type
);
350 g_assert_cmpint(type
->instance_size
, >=, sizeof(Object
));
351 g_assert(type
->abstract
== false);
352 g_assert_cmpint(size
, >=, type
->instance_size
);
354 memset(obj
, 0, type
->instance_size
);
355 obj
->class = type
->class;
357 obj
->properties
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
358 NULL
, object_property_free
);
359 object_init_with_type(obj
, type
);
360 object_post_init_with_type(obj
, type
);
363 void object_initialize(void *data
, size_t size
, const char *typename
)
365 TypeImpl
*type
= type_get_by_name(typename
);
367 object_initialize_with_type(data
, size
, type
);
370 static inline bool object_property_is_child(ObjectProperty
*prop
)
372 return strstart(prop
->type
, "child<", NULL
);
375 static void object_property_del_all(Object
*obj
)
377 ObjectProperty
*prop
;
384 g_hash_table_iter_init(&iter
, obj
->properties
);
385 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
388 prop
->release(obj
, prop
->name
, prop
->opaque
);
389 prop
->release
= NULL
;
393 g_hash_table_iter_remove(&iter
);
397 g_hash_table_unref(obj
->properties
);
400 static void object_property_del_child(Object
*obj
, Object
*child
, Error
**errp
)
402 ObjectProperty
*prop
;
406 g_hash_table_iter_init(&iter
, obj
->properties
);
407 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
409 if (object_property_is_child(prop
) && prop
->opaque
== child
) {
411 prop
->release(obj
, prop
->name
, prop
->opaque
);
412 prop
->release
= NULL
;
417 g_hash_table_iter_init(&iter
, obj
->properties
);
418 while (g_hash_table_iter_next(&iter
, &key
, &value
)) {
420 if (object_property_is_child(prop
) && prop
->opaque
== child
) {
421 g_hash_table_iter_remove(&iter
);
427 void object_unparent(Object
*obj
)
430 object_property_del_child(obj
->parent
, obj
, NULL
);
434 static void object_deinit(Object
*obj
, TypeImpl
*type
)
436 if (type
->instance_finalize
) {
437 type
->instance_finalize(obj
);
440 if (type_has_parent(type
)) {
441 object_deinit(obj
, type_get_parent(type
));
445 static void object_finalize(void *data
)
448 TypeImpl
*ti
= obj
->class->type
;
450 object_property_del_all(obj
);
451 object_deinit(obj
, ti
);
453 g_assert_cmpint(obj
->ref
, ==, 0);
459 Object
*object_new_with_type(Type type
)
463 g_assert(type
!= NULL
);
464 type_initialize(type
);
466 obj
= g_malloc(type
->instance_size
);
467 object_initialize_with_type(obj
, type
->instance_size
, type
);
473 Object
*object_new(const char *typename
)
475 TypeImpl
*ti
= type_get_by_name(typename
);
477 return object_new_with_type(ti
);
481 Object
*object_new_with_props(const char *typename
,
490 va_start(vargs
, errp
);
491 obj
= object_new_with_propv(typename
, parent
, id
, errp
, vargs
);
498 Object
*object_new_with_propv(const char *typename
,
506 Error
*local_err
= NULL
;
508 klass
= object_class_by_name(typename
);
510 error_setg(errp
, "invalid object type: %s", typename
);
514 if (object_class_is_abstract(klass
)) {
515 error_setg(errp
, "object type '%s' is abstract", typename
);
518 obj
= object_new(typename
);
520 if (object_set_propv(obj
, &local_err
, vargs
) < 0) {
524 object_property_add_child(parent
, id
, obj
, &local_err
);
529 if (object_dynamic_cast(obj
, TYPE_USER_CREATABLE
)) {
530 user_creatable_complete(obj
, &local_err
);
532 object_unparent(obj
);
537 object_unref(OBJECT(obj
));
542 error_propagate(errp
, local_err
);
549 int object_set_props(Object
*obj
,
556 va_start(vargs
, errp
);
557 ret
= object_set_propv(obj
, errp
, vargs
);
564 int object_set_propv(Object
*obj
,
568 const char *propname
;
569 Error
*local_err
= NULL
;
571 propname
= va_arg(vargs
, char *);
572 while (propname
!= NULL
) {
573 const char *value
= va_arg(vargs
, char *);
575 g_assert(value
!= NULL
);
576 object_property_parse(obj
, value
, propname
, &local_err
);
578 error_propagate(errp
, local_err
);
581 propname
= va_arg(vargs
, char *);
588 Object
*object_dynamic_cast(Object
*obj
, const char *typename
)
590 if (obj
&& object_class_dynamic_cast(object_get_class(obj
), typename
)) {
597 Object
*object_dynamic_cast_assert(Object
*obj
, const char *typename
,
598 const char *file
, int line
, const char *func
)
600 trace_object_dynamic_cast_assert(obj
? obj
->class->type
->name
: "(null)",
601 typename
, file
, line
, func
);
603 #ifdef CONFIG_QOM_CAST_DEBUG
607 for (i
= 0; obj
&& i
< OBJECT_CLASS_CAST_CACHE
; i
++) {
608 if (obj
->class->object_cast_cache
[i
] == typename
) {
613 inst
= object_dynamic_cast(obj
, typename
);
616 fprintf(stderr
, "%s:%d:%s: Object %p is not an instance of type %s\n",
617 file
, line
, func
, obj
, typename
);
623 if (obj
&& obj
== inst
) {
624 for (i
= 1; i
< OBJECT_CLASS_CAST_CACHE
; i
++) {
625 obj
->class->object_cast_cache
[i
- 1] =
626 obj
->class->object_cast_cache
[i
];
628 obj
->class->object_cast_cache
[i
- 1] = typename
;
636 ObjectClass
*object_class_dynamic_cast(ObjectClass
*class,
637 const char *typename
)
639 ObjectClass
*ret
= NULL
;
640 TypeImpl
*target_type
;
647 /* A simple fast path that can trigger a lot for leaf classes. */
649 if (type
->name
== typename
) {
653 target_type
= type_get_by_name(typename
);
655 /* target class type unknown, so fail the cast */
659 if (type
->class->interfaces
&&
660 type_is_ancestor(target_type
, type_interface
)) {
664 for (i
= class->interfaces
; i
; i
= i
->next
) {
665 ObjectClass
*target_class
= i
->data
;
667 if (type_is_ancestor(target_class
->type
, target_type
)) {
673 /* The match was ambiguous, don't allow a cast */
677 } else if (type_is_ancestor(type
, target_type
)) {
684 ObjectClass
*object_class_dynamic_cast_assert(ObjectClass
*class,
685 const char *typename
,
686 const char *file
, int line
,
691 trace_object_class_dynamic_cast_assert(class ? class->type
->name
: "(null)",
692 typename
, file
, line
, func
);
694 #ifdef CONFIG_QOM_CAST_DEBUG
697 for (i
= 0; class && i
< OBJECT_CLASS_CAST_CACHE
; i
++) {
698 if (class->class_cast_cache
[i
] == typename
) {
704 if (!class || !class->interfaces
) {
709 ret
= object_class_dynamic_cast(class, typename
);
711 fprintf(stderr
, "%s:%d:%s: Object %p is not an instance of type %s\n",
712 file
, line
, func
, class, typename
);
716 #ifdef CONFIG_QOM_CAST_DEBUG
717 if (class && ret
== class) {
718 for (i
= 1; i
< OBJECT_CLASS_CAST_CACHE
; i
++) {
719 class->class_cast_cache
[i
- 1] = class->class_cast_cache
[i
];
721 class->class_cast_cache
[i
- 1] = typename
;
728 const char *object_get_typename(Object
*obj
)
730 return obj
->class->type
->name
;
733 ObjectClass
*object_get_class(Object
*obj
)
738 bool object_class_is_abstract(ObjectClass
*klass
)
740 return klass
->type
->abstract
;
743 const char *object_class_get_name(ObjectClass
*klass
)
745 return klass
->type
->name
;
748 ObjectClass
*object_class_by_name(const char *typename
)
750 TypeImpl
*type
= type_get_by_name(typename
);
756 type_initialize(type
);
761 ObjectClass
*object_class_get_parent(ObjectClass
*class)
763 TypeImpl
*type
= type_get_parent(class->type
);
769 type_initialize(type
);
774 typedef struct OCFData
776 void (*fn
)(ObjectClass
*klass
, void *opaque
);
777 const char *implements_type
;
778 bool include_abstract
;
782 static void object_class_foreach_tramp(gpointer key
, gpointer value
,
785 OCFData
*data
= opaque
;
786 TypeImpl
*type
= value
;
789 type_initialize(type
);
792 if (!data
->include_abstract
&& type
->abstract
) {
796 if (data
->implements_type
&&
797 !object_class_dynamic_cast(k
, data
->implements_type
)) {
801 data
->fn(k
, data
->opaque
);
804 void object_class_foreach(void (*fn
)(ObjectClass
*klass
, void *opaque
),
805 const char *implements_type
, bool include_abstract
,
808 OCFData data
= { fn
, implements_type
, include_abstract
, opaque
};
810 enumerating_types
= true;
811 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp
, &data
);
812 enumerating_types
= false;
815 static int do_object_child_foreach(Object
*obj
,
816 int (*fn
)(Object
*child
, void *opaque
),
817 void *opaque
, bool recurse
)
820 ObjectProperty
*prop
;
823 g_hash_table_iter_init(&iter
, obj
->properties
);
824 while (g_hash_table_iter_next(&iter
, NULL
, (gpointer
*)&prop
)) {
825 if (object_property_is_child(prop
)) {
826 Object
*child
= prop
->opaque
;
828 ret
= fn(child
, opaque
);
833 do_object_child_foreach(child
, fn
, opaque
, true);
840 int object_child_foreach(Object
*obj
, int (*fn
)(Object
*child
, void *opaque
),
843 return do_object_child_foreach(obj
, fn
, opaque
, false);
846 int object_child_foreach_recursive(Object
*obj
,
847 int (*fn
)(Object
*child
, void *opaque
),
850 return do_object_child_foreach(obj
, fn
, opaque
, true);
853 static void object_class_get_list_tramp(ObjectClass
*klass
, void *opaque
)
855 GSList
**list
= opaque
;
857 *list
= g_slist_prepend(*list
, klass
);
860 GSList
*object_class_get_list(const char *implements_type
,
861 bool include_abstract
)
865 object_class_foreach(object_class_get_list_tramp
,
866 implements_type
, include_abstract
, &list
);
870 void object_ref(Object
*obj
)
875 atomic_inc(&obj
->ref
);
878 void object_unref(Object
*obj
)
883 g_assert_cmpint(obj
->ref
, >, 0);
885 /* parent always holds a reference to its children */
886 if (atomic_fetch_dec(&obj
->ref
) == 1) {
887 object_finalize(obj
);
892 object_property_add(Object
*obj
, const char *name
, const char *type
,
893 ObjectPropertyAccessor
*get
,
894 ObjectPropertyAccessor
*set
,
895 ObjectPropertyRelease
*release
,
896 void *opaque
, Error
**errp
)
898 ObjectProperty
*prop
;
899 size_t name_len
= strlen(name
);
901 if (name_len
>= 3 && !memcmp(name
+ name_len
- 3, "[*]", 4)) {
904 char *name_no_array
= g_strdup(name
);
906 name_no_array
[name_len
- 3] = '\0';
908 char *full_name
= g_strdup_printf("%s[%d]", name_no_array
, i
);
910 ret
= object_property_add(obj
, full_name
, type
, get
, set
,
911 release
, opaque
, NULL
);
917 g_free(name_no_array
);
921 if (g_hash_table_lookup(obj
->properties
, name
) != NULL
) {
922 error_setg(errp
, "attempt to add duplicate property '%s'"
923 " to object (type '%s')", name
,
924 object_get_typename(obj
));
928 prop
= g_malloc0(sizeof(*prop
));
930 prop
->name
= g_strdup(name
);
931 prop
->type
= g_strdup(type
);
935 prop
->release
= release
;
936 prop
->opaque
= opaque
;
938 g_hash_table_insert(obj
->properties
, prop
->name
, prop
);
942 ObjectProperty
*object_property_find(Object
*obj
, const char *name
,
945 ObjectProperty
*prop
;
947 prop
= g_hash_table_lookup(obj
->properties
, name
);
952 error_setg(errp
, "Property '.%s' not found", name
);
956 ObjectPropertyIterator
*object_property_iter_init(Object
*obj
)
958 ObjectPropertyIterator
*ret
= g_new0(ObjectPropertyIterator
, 1);
959 g_hash_table_iter_init(&ret
->iter
, obj
->properties
);
963 void object_property_iter_free(ObjectPropertyIterator
*iter
)
971 ObjectProperty
*object_property_iter_next(ObjectPropertyIterator
*iter
)
974 if (!g_hash_table_iter_next(&iter
->iter
, &key
, &val
)) {
980 void object_property_del(Object
*obj
, const char *name
, Error
**errp
)
982 ObjectProperty
*prop
= g_hash_table_lookup(obj
->properties
, name
);
985 error_setg(errp
, "Property '.%s' not found", name
);
990 prop
->release(obj
, name
, prop
->opaque
);
992 g_hash_table_remove(obj
->properties
, name
);
995 void object_property_get(Object
*obj
, Visitor
*v
, const char *name
,
998 ObjectProperty
*prop
= object_property_find(obj
, name
, errp
);
1004 error_setg(errp
, QERR_PERMISSION_DENIED
);
1006 prop
->get(obj
, v
, prop
->opaque
, name
, errp
);
1010 void object_property_set(Object
*obj
, Visitor
*v
, const char *name
,
1013 ObjectProperty
*prop
= object_property_find(obj
, name
, errp
);
1019 error_setg(errp
, QERR_PERMISSION_DENIED
);
1021 prop
->set(obj
, v
, prop
->opaque
, name
, errp
);
1025 void object_property_set_str(Object
*obj
, const char *value
,
1026 const char *name
, Error
**errp
)
1028 QString
*qstr
= qstring_from_str(value
);
1029 object_property_set_qobject(obj
, QOBJECT(qstr
), name
, errp
);
1034 char *object_property_get_str(Object
*obj
, const char *name
,
1037 QObject
*ret
= object_property_get_qobject(obj
, name
, errp
);
1044 qstring
= qobject_to_qstring(ret
);
1046 error_setg(errp
, QERR_INVALID_PARAMETER_TYPE
, name
, "string");
1049 retval
= g_strdup(qstring_get_str(qstring
));
1056 void object_property_set_link(Object
*obj
, Object
*value
,
1057 const char *name
, Error
**errp
)
1060 gchar
*path
= object_get_canonical_path(value
);
1061 object_property_set_str(obj
, path
, name
, errp
);
1064 object_property_set_str(obj
, "", name
, errp
);
1068 Object
*object_property_get_link(Object
*obj
, const char *name
,
1071 char *str
= object_property_get_str(obj
, name
, errp
);
1072 Object
*target
= NULL
;
1075 target
= object_resolve_path(str
, NULL
);
1077 error_set(errp
, ERROR_CLASS_DEVICE_NOT_FOUND
,
1078 "Device '%s' not found", str
);
1086 void object_property_set_bool(Object
*obj
, bool value
,
1087 const char *name
, Error
**errp
)
1089 QBool
*qbool
= qbool_from_bool(value
);
1090 object_property_set_qobject(obj
, QOBJECT(qbool
), name
, errp
);
1095 bool object_property_get_bool(Object
*obj
, const char *name
,
1098 QObject
*ret
= object_property_get_qobject(obj
, name
, errp
);
1105 qbool
= qobject_to_qbool(ret
);
1107 error_setg(errp
, QERR_INVALID_PARAMETER_TYPE
, name
, "boolean");
1110 retval
= qbool_get_bool(qbool
);
1117 void object_property_set_int(Object
*obj
, int64_t value
,
1118 const char *name
, Error
**errp
)
1120 QInt
*qint
= qint_from_int(value
);
1121 object_property_set_qobject(obj
, QOBJECT(qint
), name
, errp
);
1126 int64_t object_property_get_int(Object
*obj
, const char *name
,
1129 QObject
*ret
= object_property_get_qobject(obj
, name
, errp
);
1136 qint
= qobject_to_qint(ret
);
1138 error_setg(errp
, QERR_INVALID_PARAMETER_TYPE
, name
, "int");
1141 retval
= qint_get_int(qint
);
1148 typedef struct EnumProperty
{
1149 const char * const *strings
;
1150 int (*get
)(Object
*, Error
**);
1151 void (*set
)(Object
*, int, Error
**);
1154 int object_property_get_enum(Object
*obj
, const char *name
,
1155 const char *typename
, Error
**errp
)
1158 StringOutputVisitor
*sov
;
1159 StringInputVisitor
*siv
;
1162 ObjectProperty
*prop
= object_property_find(obj
, name
, errp
);
1163 EnumProperty
*enumprop
;
1169 if (!g_str_equal(prop
->type
, typename
)) {
1170 error_setg(errp
, "Property %s on %s is not '%s' enum type",
1171 name
, object_class_get_name(
1172 object_get_class(obj
)), typename
);
1176 enumprop
= prop
->opaque
;
1178 sov
= string_output_visitor_new(false);
1179 object_property_get(obj
, string_output_get_visitor(sov
), name
, &err
);
1181 error_propagate(errp
, err
);
1182 string_output_visitor_cleanup(sov
);
1185 str
= string_output_get_string(sov
);
1186 siv
= string_input_visitor_new(str
);
1187 string_output_visitor_cleanup(sov
);
1188 visit_type_enum(string_input_get_visitor(siv
),
1189 &ret
, enumprop
->strings
, NULL
, name
, errp
);
1192 string_input_visitor_cleanup(siv
);
1197 void object_property_get_uint16List(Object
*obj
, const char *name
,
1198 uint16List
**list
, Error
**errp
)
1201 StringOutputVisitor
*ov
;
1202 StringInputVisitor
*iv
;
1205 ov
= string_output_visitor_new(false);
1206 object_property_get(obj
, string_output_get_visitor(ov
),
1209 error_propagate(errp
, err
);
1212 str
= string_output_get_string(ov
);
1213 iv
= string_input_visitor_new(str
);
1214 visit_type_uint16List(string_input_get_visitor(iv
),
1218 string_input_visitor_cleanup(iv
);
1220 string_output_visitor_cleanup(ov
);
1223 void object_property_parse(Object
*obj
, const char *string
,
1224 const char *name
, Error
**errp
)
1226 StringInputVisitor
*siv
;
1227 siv
= string_input_visitor_new(string
);
1228 object_property_set(obj
, string_input_get_visitor(siv
), name
, errp
);
1230 string_input_visitor_cleanup(siv
);
1233 char *object_property_print(Object
*obj
, const char *name
, bool human
,
1236 StringOutputVisitor
*sov
;
1237 char *string
= NULL
;
1238 Error
*local_err
= NULL
;
1240 sov
= string_output_visitor_new(human
);
1241 object_property_get(obj
, string_output_get_visitor(sov
), name
, &local_err
);
1243 error_propagate(errp
, local_err
);
1247 string
= string_output_get_string(sov
);
1250 string_output_visitor_cleanup(sov
);
1254 const char *object_property_get_type(Object
*obj
, const char *name
, Error
**errp
)
1256 ObjectProperty
*prop
= object_property_find(obj
, name
, errp
);
1264 Object
*object_get_root(void)
1266 static Object
*root
;
1269 root
= object_new("container");
1275 Object
*object_get_objects_root(void)
1277 return container_get(object_get_root(), "/objects");
1280 static void object_get_child_property(Object
*obj
, Visitor
*v
, void *opaque
,
1281 const char *name
, Error
**errp
)
1283 Object
*child
= opaque
;
1286 path
= object_get_canonical_path(child
);
1287 visit_type_str(v
, &path
, name
, errp
);
1291 static Object
*object_resolve_child_property(Object
*parent
, void *opaque
, const gchar
*part
)
1296 static void object_finalize_child_property(Object
*obj
, const char *name
,
1299 Object
*child
= opaque
;
1301 if (child
->class->unparent
) {
1302 (child
->class->unparent
)(child
);
1304 child
->parent
= NULL
;
1305 object_unref(child
);
1308 void object_property_add_child(Object
*obj
, const char *name
,
1309 Object
*child
, Error
**errp
)
1311 Error
*local_err
= NULL
;
1315 if (child
->parent
!= NULL
) {
1316 error_setg(errp
, "child object is already parented");
1320 type
= g_strdup_printf("child<%s>", object_get_typename(OBJECT(child
)));
1322 op
= object_property_add(obj
, name
, type
, object_get_child_property
, NULL
,
1323 object_finalize_child_property
, child
, &local_err
);
1325 error_propagate(errp
, local_err
);
1329 op
->resolve
= object_resolve_child_property
;
1331 child
->parent
= obj
;
1337 void object_property_allow_set_link(Object
*obj
, const char *name
,
1338 Object
*val
, Error
**errp
)
1340 /* Allow the link to be set, always */
1345 void (*check
)(Object
*, const char *, Object
*, Error
**);
1346 ObjectPropertyLinkFlags flags
;
1349 static void object_get_link_property(Object
*obj
, Visitor
*v
, void *opaque
,
1350 const char *name
, Error
**errp
)
1352 LinkProperty
*lprop
= opaque
;
1353 Object
**child
= lprop
->child
;
1357 path
= object_get_canonical_path(*child
);
1358 visit_type_str(v
, &path
, name
, errp
);
1362 visit_type_str(v
, &path
, name
, errp
);
1367 * object_resolve_link:
1369 * Lookup an object and ensure its type matches the link property type. This
1370 * is similar to object_resolve_path() except type verification against the
1371 * link property is performed.
1373 * Returns: The matched object or NULL on path lookup failures.
1375 static Object
*object_resolve_link(Object
*obj
, const char *name
,
1376 const char *path
, Error
**errp
)
1380 bool ambiguous
= false;
1383 /* Go from link<FOO> to FOO. */
1384 type
= object_property_get_type(obj
, name
, NULL
);
1385 target_type
= g_strndup(&type
[5], strlen(type
) - 6);
1386 target
= object_resolve_path_type(path
, target_type
, &ambiguous
);
1389 error_setg(errp
, "Path '%s' does not uniquely identify an object",
1391 } else if (!target
) {
1392 target
= object_resolve_path(path
, &ambiguous
);
1393 if (target
|| ambiguous
) {
1394 error_setg(errp
, QERR_INVALID_PARAMETER_TYPE
, name
, target_type
);
1396 error_set(errp
, ERROR_CLASS_DEVICE_NOT_FOUND
,
1397 "Device '%s' not found", path
);
1401 g_free(target_type
);
1406 static void object_set_link_property(Object
*obj
, Visitor
*v
, void *opaque
,
1407 const char *name
, Error
**errp
)
1409 Error
*local_err
= NULL
;
1410 LinkProperty
*prop
= opaque
;
1411 Object
**child
= prop
->child
;
1412 Object
*old_target
= *child
;
1413 Object
*new_target
= NULL
;
1416 visit_type_str(v
, &path
, name
, &local_err
);
1418 if (!local_err
&& strcmp(path
, "") != 0) {
1419 new_target
= object_resolve_link(obj
, name
, path
, &local_err
);
1424 error_propagate(errp
, local_err
);
1428 prop
->check(obj
, name
, new_target
, &local_err
);
1430 error_propagate(errp
, local_err
);
1434 object_ref(new_target
);
1435 *child
= new_target
;
1436 object_unref(old_target
);
1439 static Object
*object_resolve_link_property(Object
*parent
, void *opaque
, const gchar
*part
)
1441 LinkProperty
*lprop
= opaque
;
1443 return *lprop
->child
;
1446 static void object_release_link_property(Object
*obj
, const char *name
,
1449 LinkProperty
*prop
= opaque
;
1451 if ((prop
->flags
& OBJ_PROP_LINK_UNREF_ON_RELEASE
) && *prop
->child
) {
1452 object_unref(*prop
->child
);
1457 void object_property_add_link(Object
*obj
, const char *name
,
1458 const char *type
, Object
**child
,
1459 void (*check
)(Object
*, const char *,
1460 Object
*, Error
**),
1461 ObjectPropertyLinkFlags flags
,
1464 Error
*local_err
= NULL
;
1465 LinkProperty
*prop
= g_malloc(sizeof(*prop
));
1469 prop
->child
= child
;
1470 prop
->check
= check
;
1471 prop
->flags
= flags
;
1473 full_type
= g_strdup_printf("link<%s>", type
);
1475 op
= object_property_add(obj
, name
, full_type
,
1476 object_get_link_property
,
1477 check
? object_set_link_property
: NULL
,
1478 object_release_link_property
,
1482 error_propagate(errp
, local_err
);
1487 op
->resolve
= object_resolve_link_property
;
1493 void object_property_add_const_link(Object
*obj
, const char *name
,
1494 Object
*target
, Error
**errp
)
1499 link_type
= g_strdup_printf("link<%s>", object_get_typename(target
));
1500 op
= object_property_add(obj
, name
, link_type
,
1501 object_get_child_property
, NULL
,
1502 NULL
, target
, errp
);
1504 op
->resolve
= object_resolve_child_property
;
1509 gchar
*object_get_canonical_path_component(Object
*obj
)
1511 ObjectProperty
*prop
= NULL
;
1512 GHashTableIter iter
;
1515 g_assert(obj
->parent
!= NULL
);
1517 g_hash_table_iter_init(&iter
, obj
->parent
->properties
);
1518 while (g_hash_table_iter_next(&iter
, NULL
, (gpointer
*)&prop
)) {
1519 if (!object_property_is_child(prop
)) {
1523 if (prop
->opaque
== obj
) {
1524 return g_strdup(prop
->name
);
1528 /* obj had a parent but was not a child, should never happen */
1529 g_assert_not_reached();
1533 gchar
*object_get_canonical_path(Object
*obj
)
1535 Object
*root
= object_get_root();
1536 char *newpath
, *path
= NULL
;
1538 while (obj
!= root
) {
1539 char *component
= object_get_canonical_path_component(obj
);
1542 newpath
= g_strdup_printf("%s/%s", component
, path
);
1553 newpath
= g_strdup_printf("/%s", path
? path
: "");
1559 Object
*object_resolve_path_component(Object
*parent
, const gchar
*part
)
1561 ObjectProperty
*prop
= object_property_find(parent
, part
, NULL
);
1566 if (prop
->resolve
) {
1567 return prop
->resolve(parent
, prop
->opaque
, part
);
1573 static Object
*object_resolve_abs_path(Object
*parent
,
1575 const char *typename
,
1580 if (parts
[index
] == NULL
) {
1581 return object_dynamic_cast(parent
, typename
);
1584 if (strcmp(parts
[index
], "") == 0) {
1585 return object_resolve_abs_path(parent
, parts
, typename
, index
+ 1);
1588 child
= object_resolve_path_component(parent
, parts
[index
]);
1593 return object_resolve_abs_path(child
, parts
, typename
, index
+ 1);
1596 static Object
*object_resolve_partial_path(Object
*parent
,
1598 const char *typename
,
1602 GHashTableIter iter
;
1603 ObjectProperty
*prop
;
1605 obj
= object_resolve_abs_path(parent
, parts
, typename
, 0);
1607 g_hash_table_iter_init(&iter
, parent
->properties
);
1608 while (g_hash_table_iter_next(&iter
, NULL
, (gpointer
*)&prop
)) {
1611 if (!object_property_is_child(prop
)) {
1615 found
= object_resolve_partial_path(prop
->opaque
, parts
,
1616 typename
, ambiguous
);
1627 if (ambiguous
&& *ambiguous
) {
1635 Object
*object_resolve_path_type(const char *path
, const char *typename
,
1641 parts
= g_strsplit(path
, "/", 0);
1644 if (parts
[0] == NULL
|| strcmp(parts
[0], "") != 0) {
1648 obj
= object_resolve_partial_path(object_get_root(), parts
,
1649 typename
, ambiguous
);
1651 obj
= object_resolve_abs_path(object_get_root(), parts
, typename
, 1);
1659 Object
*object_resolve_path(const char *path
, bool *ambiguous
)
1661 return object_resolve_path_type(path
, TYPE_OBJECT
, ambiguous
);
1664 typedef struct StringProperty
1666 char *(*get
)(Object
*, Error
**);
1667 void (*set
)(Object
*, const char *, Error
**);
1670 static void property_get_str(Object
*obj
, Visitor
*v
, void *opaque
,
1671 const char *name
, Error
**errp
)
1673 StringProperty
*prop
= opaque
;
1677 value
= prop
->get(obj
, &err
);
1679 error_propagate(errp
, err
);
1683 visit_type_str(v
, &value
, name
, errp
);
1687 static void property_set_str(Object
*obj
, Visitor
*v
, void *opaque
,
1688 const char *name
, Error
**errp
)
1690 StringProperty
*prop
= opaque
;
1692 Error
*local_err
= NULL
;
1694 visit_type_str(v
, &value
, name
, &local_err
);
1696 error_propagate(errp
, local_err
);
1700 prop
->set(obj
, value
, errp
);
1704 static void property_release_str(Object
*obj
, const char *name
,
1707 StringProperty
*prop
= opaque
;
1711 void object_property_add_str(Object
*obj
, const char *name
,
1712 char *(*get
)(Object
*, Error
**),
1713 void (*set
)(Object
*, const char *, Error
**),
1716 Error
*local_err
= NULL
;
1717 StringProperty
*prop
= g_malloc0(sizeof(*prop
));
1722 object_property_add(obj
, name
, "string",
1723 get
? property_get_str
: NULL
,
1724 set
? property_set_str
: NULL
,
1725 property_release_str
,
1728 error_propagate(errp
, local_err
);
1733 typedef struct BoolProperty
1735 bool (*get
)(Object
*, Error
**);
1736 void (*set
)(Object
*, bool, Error
**);
1739 static void property_get_bool(Object
*obj
, Visitor
*v
, void *opaque
,
1740 const char *name
, Error
**errp
)
1742 BoolProperty
*prop
= opaque
;
1746 value
= prop
->get(obj
, &err
);
1748 error_propagate(errp
, err
);
1752 visit_type_bool(v
, &value
, name
, errp
);
1755 static void property_set_bool(Object
*obj
, Visitor
*v
, void *opaque
,
1756 const char *name
, Error
**errp
)
1758 BoolProperty
*prop
= opaque
;
1760 Error
*local_err
= NULL
;
1762 visit_type_bool(v
, &value
, name
, &local_err
);
1764 error_propagate(errp
, local_err
);
1768 prop
->set(obj
, value
, errp
);
1771 static void property_release_bool(Object
*obj
, const char *name
,
1774 BoolProperty
*prop
= opaque
;
1778 void object_property_add_bool(Object
*obj
, const char *name
,
1779 bool (*get
)(Object
*, Error
**),
1780 void (*set
)(Object
*, bool, Error
**),
1783 Error
*local_err
= NULL
;
1784 BoolProperty
*prop
= g_malloc0(sizeof(*prop
));
1789 object_property_add(obj
, name
, "bool",
1790 get
? property_get_bool
: NULL
,
1791 set
? property_set_bool
: NULL
,
1792 property_release_bool
,
1795 error_propagate(errp
, local_err
);
1800 static void property_get_enum(Object
*obj
, Visitor
*v
, void *opaque
,
1801 const char *name
, Error
**errp
)
1803 EnumProperty
*prop
= opaque
;
1807 value
= prop
->get(obj
, &err
);
1809 error_propagate(errp
, err
);
1813 visit_type_enum(v
, &value
, prop
->strings
, NULL
, name
, errp
);
1816 static void property_set_enum(Object
*obj
, Visitor
*v
, void *opaque
,
1817 const char *name
, Error
**errp
)
1819 EnumProperty
*prop
= opaque
;
1823 visit_type_enum(v
, &value
, prop
->strings
, NULL
, name
, &err
);
1825 error_propagate(errp
, err
);
1828 prop
->set(obj
, value
, errp
);
1831 static void property_release_enum(Object
*obj
, const char *name
,
1834 EnumProperty
*prop
= opaque
;
1838 void object_property_add_enum(Object
*obj
, const char *name
,
1839 const char *typename
,
1840 const char * const *strings
,
1841 int (*get
)(Object
*, Error
**),
1842 void (*set
)(Object
*, int, Error
**),
1845 Error
*local_err
= NULL
;
1846 EnumProperty
*prop
= g_malloc(sizeof(*prop
));
1848 prop
->strings
= strings
;
1852 object_property_add(obj
, name
, typename
,
1853 get
? property_get_enum
: NULL
,
1854 set
? property_set_enum
: NULL
,
1855 property_release_enum
,
1858 error_propagate(errp
, local_err
);
1863 typedef struct TMProperty
{
1864 void (*get
)(Object
*, struct tm
*, Error
**);
1867 static void property_get_tm(Object
*obj
, Visitor
*v
, void *opaque
,
1868 const char *name
, Error
**errp
)
1870 TMProperty
*prop
= opaque
;
1874 prop
->get(obj
, &value
, &err
);
1879 visit_start_struct(v
, NULL
, "struct tm", name
, 0, &err
);
1883 visit_type_int32(v
, &value
.tm_year
, "tm_year", &err
);
1887 visit_type_int32(v
, &value
.tm_mon
, "tm_mon", &err
);
1891 visit_type_int32(v
, &value
.tm_mday
, "tm_mday", &err
);
1895 visit_type_int32(v
, &value
.tm_hour
, "tm_hour", &err
);
1899 visit_type_int32(v
, &value
.tm_min
, "tm_min", &err
);
1903 visit_type_int32(v
, &value
.tm_sec
, "tm_sec", &err
);
1908 error_propagate(errp
, err
);
1910 visit_end_struct(v
, errp
);
1912 error_propagate(errp
, err
);
1916 static void property_release_tm(Object
*obj
, const char *name
,
1919 TMProperty
*prop
= opaque
;
1923 void object_property_add_tm(Object
*obj
, const char *name
,
1924 void (*get
)(Object
*, struct tm
*, Error
**),
1927 Error
*local_err
= NULL
;
1928 TMProperty
*prop
= g_malloc0(sizeof(*prop
));
1932 object_property_add(obj
, name
, "struct tm",
1933 get
? property_get_tm
: NULL
, NULL
,
1934 property_release_tm
,
1937 error_propagate(errp
, local_err
);
1942 static char *qdev_get_type(Object
*obj
, Error
**errp
)
1944 return g_strdup(object_get_typename(obj
));
1947 static void property_get_uint8_ptr(Object
*obj
, Visitor
*v
,
1948 void *opaque
, const char *name
,
1951 uint8_t value
= *(uint8_t *)opaque
;
1952 visit_type_uint8(v
, &value
, name
, errp
);
1955 static void property_get_uint16_ptr(Object
*obj
, Visitor
*v
,
1956 void *opaque
, const char *name
,
1959 uint16_t value
= *(uint16_t *)opaque
;
1960 visit_type_uint16(v
, &value
, name
, errp
);
1963 static void property_get_uint32_ptr(Object
*obj
, Visitor
*v
,
1964 void *opaque
, const char *name
,
1967 uint32_t value
= *(uint32_t *)opaque
;
1968 visit_type_uint32(v
, &value
, name
, errp
);
1971 static void property_get_uint64_ptr(Object
*obj
, Visitor
*v
,
1972 void *opaque
, const char *name
,
1975 uint64_t value
= *(uint64_t *)opaque
;
1976 visit_type_uint64(v
, &value
, name
, errp
);
1979 void object_property_add_uint8_ptr(Object
*obj
, const char *name
,
1980 const uint8_t *v
, Error
**errp
)
1982 object_property_add(obj
, name
, "uint8", property_get_uint8_ptr
,
1983 NULL
, NULL
, (void *)v
, errp
);
1986 void object_property_add_uint16_ptr(Object
*obj
, const char *name
,
1987 const uint16_t *v
, Error
**errp
)
1989 object_property_add(obj
, name
, "uint16", property_get_uint16_ptr
,
1990 NULL
, NULL
, (void *)v
, errp
);
1993 void object_property_add_uint32_ptr(Object
*obj
, const char *name
,
1994 const uint32_t *v
, Error
**errp
)
1996 object_property_add(obj
, name
, "uint32", property_get_uint32_ptr
,
1997 NULL
, NULL
, (void *)v
, errp
);
2000 void object_property_add_uint64_ptr(Object
*obj
, const char *name
,
2001 const uint64_t *v
, Error
**errp
)
2003 object_property_add(obj
, name
, "uint64", property_get_uint64_ptr
,
2004 NULL
, NULL
, (void *)v
, errp
);
2012 static void property_get_alias(Object
*obj
, struct Visitor
*v
, void *opaque
,
2013 const char *name
, Error
**errp
)
2015 AliasProperty
*prop
= opaque
;
2017 object_property_get(prop
->target_obj
, v
, prop
->target_name
, errp
);
2020 static void property_set_alias(Object
*obj
, struct Visitor
*v
, void *opaque
,
2021 const char *name
, Error
**errp
)
2023 AliasProperty
*prop
= opaque
;
2025 object_property_set(prop
->target_obj
, v
, prop
->target_name
, errp
);
2028 static Object
*property_resolve_alias(Object
*obj
, void *opaque
,
2031 AliasProperty
*prop
= opaque
;
2033 return object_resolve_path_component(prop
->target_obj
, prop
->target_name
);
2036 static void property_release_alias(Object
*obj
, const char *name
, void *opaque
)
2038 AliasProperty
*prop
= opaque
;
2040 g_free(prop
->target_name
);
2044 void object_property_add_alias(Object
*obj
, const char *name
,
2045 Object
*target_obj
, const char *target_name
,
2048 AliasProperty
*prop
;
2050 ObjectProperty
*target_prop
;
2052 Error
*local_err
= NULL
;
2054 target_prop
= object_property_find(target_obj
, target_name
, errp
);
2059 if (object_property_is_child(target_prop
)) {
2060 prop_type
= g_strdup_printf("link%s",
2061 target_prop
->type
+ strlen("child"));
2063 prop_type
= g_strdup(target_prop
->type
);
2066 prop
= g_malloc(sizeof(*prop
));
2067 prop
->target_obj
= target_obj
;
2068 prop
->target_name
= g_strdup(target_name
);
2070 op
= object_property_add(obj
, name
, prop_type
,
2073 property_release_alias
,
2076 error_propagate(errp
, local_err
);
2080 op
->resolve
= property_resolve_alias
;
2082 object_property_set_description(obj
, op
->name
,
2083 target_prop
->description
,
2090 void object_property_set_description(Object
*obj
, const char *name
,
2091 const char *description
, Error
**errp
)
2095 op
= object_property_find(obj
, name
, errp
);
2100 g_free(op
->description
);
2101 op
->description
= g_strdup(description
);
2104 static void object_instance_init(Object
*obj
)
2106 object_property_add_str(obj
, "type", qdev_get_type
, NULL
, NULL
);
2109 static void register_types(void)
2111 static TypeInfo interface_info
= {
2112 .name
= TYPE_INTERFACE
,
2113 .class_size
= sizeof(InterfaceClass
),
2117 static TypeInfo object_info
= {
2118 .name
= TYPE_OBJECT
,
2119 .instance_size
= sizeof(Object
),
2120 .instance_init
= object_instance_init
,
2124 type_interface
= type_register_internal(&interface_info
);
2125 type_register_internal(&object_info
);
2128 type_init(register_types
)