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 "qemu/object.h"
14 #include "qemu-common.h"
16 #define MAX_INTERFACES 32
18 typedef struct InterfaceImpl InterfaceImpl
;
19 typedef struct TypeImpl TypeImpl
;
24 void (*interface_initfn
)(ObjectClass
*class, void *data
);
36 void (*class_init
)(ObjectClass
*klass
, void *data
);
37 void (*class_finalize
)(ObjectClass
*klass
, void *data
);
41 void (*instance_init
)(Object
*obj
);
42 void (*instance_finalize
)(Object
*obj
);
47 TypeImpl
*parent_type
;
52 InterfaceImpl interfaces
[MAX_INTERFACES
];
55 typedef struct Interface
61 #define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE)
63 static GHashTable
*type_table_get(void)
65 static GHashTable
*type_table
;
67 if (type_table
== NULL
) {
68 type_table
= g_hash_table_new(g_str_hash
, g_str_equal
);
74 static void type_table_add(TypeImpl
*ti
)
76 g_hash_table_insert(type_table_get(), (void *)ti
->name
, ti
);
79 static TypeImpl
*type_table_lookup(const char *name
)
81 return g_hash_table_lookup(type_table_get(), name
);
84 TypeImpl
*type_register(const TypeInfo
*info
)
86 TypeImpl
*ti
= g_malloc0(sizeof(*ti
));
88 g_assert(info
->name
!= NULL
);
90 ti
->name
= g_strdup(info
->name
);
91 ti
->parent
= g_strdup(info
->parent
);
93 ti
->class_size
= info
->class_size
;
94 ti
->instance_size
= info
->instance_size
;
96 ti
->class_init
= info
->class_init
;
97 ti
->class_finalize
= info
->class_finalize
;
98 ti
->class_data
= info
->class_data
;
100 ti
->instance_init
= info
->instance_init
;
101 ti
->instance_finalize
= info
->instance_finalize
;
103 ti
->abstract
= info
->abstract
;
105 if (info
->interfaces
) {
108 for (i
= 0; info
->interfaces
[i
].type
; i
++) {
109 ti
->interfaces
[i
].parent
= info
->interfaces
[i
].type
;
110 ti
->interfaces
[i
].interface_initfn
= info
->interfaces
[i
].interface_initfn
;
111 ti
->num_interfaces
++;
120 TypeImpl
*type_register_static(const TypeInfo
*info
)
122 return type_register(info
);
125 static TypeImpl
*type_get_by_name(const char *name
)
131 return type_table_lookup(name
);
134 static TypeImpl
*type_get_parent(TypeImpl
*type
)
136 if (!type
->parent_type
&& type
->parent
) {
137 type
->parent_type
= type_get_by_name(type
->parent
);
138 g_assert(type
->parent_type
!= NULL
);
141 return type
->parent_type
;
144 static bool type_has_parent(TypeImpl
*type
)
146 return (type
->parent
!= NULL
);
149 static size_t type_class_get_size(TypeImpl
*ti
)
151 if (ti
->class_size
) {
152 return ti
->class_size
;
155 if (type_has_parent(ti
)) {
156 return type_class_get_size(type_get_parent(ti
));
159 return sizeof(ObjectClass
);
162 static void type_class_interface_init(TypeImpl
*ti
, InterfaceImpl
*iface
)
165 .instance_size
= sizeof(Interface
),
166 .parent
= iface
->parent
,
167 .class_size
= sizeof(InterfaceClass
),
168 .class_init
= iface
->interface_initfn
,
171 char *name
= g_strdup_printf("<%s::%s>", ti
->name
, iface
->parent
);
174 iface
->type
= type_register(&info
);
178 static void type_class_init(TypeImpl
*ti
)
180 size_t class_size
= sizeof(ObjectClass
);
187 ti
->class_size
= type_class_get_size(ti
);
189 ti
->class = g_malloc0(ti
->class_size
);
190 ti
->class->type
= ti
;
192 if (type_has_parent(ti
)) {
193 TypeImpl
*parent
= type_get_parent(ti
);
195 type_class_init(parent
);
197 class_size
= parent
->class_size
;
198 g_assert(parent
->class_size
<= ti
->class_size
);
200 memcpy((void *)ti
->class + sizeof(ObjectClass
),
201 (void *)parent
->class + sizeof(ObjectClass
),
202 parent
->class_size
- sizeof(ObjectClass
));
205 memset((void *)ti
->class + class_size
, 0, ti
->class_size
- class_size
);
207 for (i
= 0; i
< ti
->num_interfaces
; i
++) {
208 type_class_interface_init(ti
, &ti
->interfaces
[i
]);
211 if (ti
->class_init
) {
212 ti
->class_init(ti
->class, ti
->class_data
);
216 static void object_interface_init(Object
*obj
, InterfaceImpl
*iface
)
218 TypeImpl
*ti
= iface
->type
;
219 Interface
*iface_obj
;
221 iface_obj
= INTERFACE(object_new(ti
->name
));
222 iface_obj
->obj
= obj
;
224 obj
->interfaces
= g_slist_prepend(obj
->interfaces
, iface_obj
);
227 static void object_init_with_type(Object
*obj
, TypeImpl
*ti
)
231 if (type_has_parent(ti
)) {
232 object_init_with_type(obj
, type_get_parent(ti
));
235 for (i
= 0; i
< ti
->num_interfaces
; i
++) {
236 object_interface_init(obj
, &ti
->interfaces
[i
]);
239 if (ti
->instance_init
) {
240 ti
->instance_init(obj
);
244 void object_initialize_with_type(void *data
, TypeImpl
*type
)
248 g_assert(type
!= NULL
);
249 g_assert(type
->instance_size
>= sizeof(ObjectClass
));
251 type_class_init(type
);
252 g_assert(type
->abstract
== false);
254 memset(obj
, 0, type
->instance_size
);
255 obj
->class = type
->class;
256 object_init_with_type(obj
, type
);
259 void object_initialize(void *data
, const char *typename
)
261 TypeImpl
*type
= type_get_by_name(typename
);
263 object_initialize_with_type(data
, type
);
266 static void object_deinit(Object
*obj
, TypeImpl
*type
)
268 if (type
->instance_finalize
) {
269 type
->instance_finalize(obj
);
272 while (obj
->interfaces
) {
273 Interface
*iface_obj
= obj
->interfaces
->data
;
274 obj
->interfaces
= g_slist_delete_link(obj
->interfaces
, obj
->interfaces
);
275 object_delete(OBJECT(iface_obj
));
278 if (type_has_parent(type
)) {
279 object_deinit(obj
, type_get_parent(type
));
283 void object_finalize(void *data
)
286 TypeImpl
*ti
= obj
->class->type
;
288 object_deinit(obj
, ti
);
291 Object
*object_new_with_type(Type type
)
295 g_assert(type
!= NULL
);
297 obj
= g_malloc(type
->instance_size
);
298 object_initialize_with_type(obj
, type
);
303 Object
*object_new(const char *typename
)
305 TypeImpl
*ti
= type_get_by_name(typename
);
307 return object_new_with_type(ti
);
310 void object_delete(Object
*obj
)
312 object_finalize(obj
);
316 static bool object_is_type(Object
*obj
, const char *typename
)
318 TypeImpl
*target_type
= type_get_by_name(typename
);
319 TypeImpl
*type
= obj
->class->type
;
322 /* Check if typename is a direct ancestor of type */
324 if (type
== target_type
) {
328 type
= type_get_parent(type
);
331 /* Check if obj has an interface of typename */
332 for (i
= obj
->interfaces
; i
; i
= i
->next
) {
333 Interface
*iface
= i
->data
;
335 if (object_is_type(OBJECT(iface
), typename
)) {
343 Object
*object_dynamic_cast(Object
*obj
, const char *typename
)
347 /* Check if typename is a direct ancestor */
348 if (object_is_type(obj
, typename
)) {
352 /* Check if obj has an interface of typename */
353 for (i
= obj
->interfaces
; i
; i
= i
->next
) {
354 Interface
*iface
= i
->data
;
356 if (object_is_type(OBJECT(iface
), typename
)) {
357 return OBJECT(iface
);
361 /* Check if obj is an interface and its containing object is a direct
362 * ancestor of typename */
363 if (object_is_type(obj
, TYPE_INTERFACE
)) {
364 Interface
*iface
= INTERFACE(obj
);
366 if (object_is_type(iface
->obj
, typename
)) {
375 static void register_interface(void)
377 static TypeInfo interface_info
= {
378 .name
= TYPE_INTERFACE
,
379 .instance_size
= sizeof(Interface
),
383 type_register_static(&interface_info
);
386 device_init(register_interface
);
388 Object
*object_dynamic_cast_assert(Object
*obj
, const char *typename
)
392 inst
= object_dynamic_cast(obj
, typename
);
395 fprintf(stderr
, "Object %p is not an instance of type %s\n",
403 ObjectClass
*object_class_dynamic_cast(ObjectClass
*class,
404 const char *typename
)
406 TypeImpl
*target_type
= type_get_by_name(typename
);
407 TypeImpl
*type
= class->type
;
410 if (type
== target_type
) {
414 type
= type_get_parent(type
);
420 ObjectClass
*object_class_dynamic_cast_assert(ObjectClass
*class,
421 const char *typename
)
423 ObjectClass
*ret
= object_class_dynamic_cast(class, typename
);
426 fprintf(stderr
, "Object %p is not an instance of type %s\n",
434 const char *object_get_typename(Object
*obj
)
436 return obj
->class->type
->name
;
439 ObjectClass
*object_get_class(Object
*obj
)
444 const char *object_class_get_name(ObjectClass
*klass
)
446 return klass
->type
->name
;
449 ObjectClass
*object_class_by_name(const char *typename
)
451 TypeImpl
*type
= type_get_by_name(typename
);
457 type_class_init(type
);
462 typedef struct OCFData
464 void (*fn
)(ObjectClass
*klass
, void *opaque
);
468 static void object_class_foreach_tramp(gpointer key
, gpointer value
,
471 OCFData
*data
= opaque
;
472 TypeImpl
*type
= value
;
474 type_class_init(type
);
476 data
->fn(value
, type
->class);
479 void object_class_foreach(void (*fn
)(ObjectClass
*klass
, void *opaque
),
482 OCFData data
= { fn
, opaque
};
484 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp
, &data
);