Revision 9970bd88
b/qom/object.c | ||
---|---|---|
63 | 63 |
|
64 | 64 |
#define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE) |
65 | 65 |
|
66 |
static Type type_interface; |
|
67 |
|
|
66 | 68 |
static GHashTable *type_table_get(void) |
67 | 69 |
{ |
68 | 70 |
static GHashTable *type_table; |
... | ... | |
384 | 386 |
return false; |
385 | 387 |
} |
386 | 388 |
|
387 |
static bool object_is_type(Object *obj, const char *typename)
|
|
389 |
static bool object_is_type(Object *obj, TypeImpl *target_type)
|
|
388 | 390 |
{ |
389 |
TypeImpl *target_type; |
|
390 |
|
|
391 |
if (typename == TYPE_OBJECT) { |
|
392 |
return true; |
|
393 |
} |
|
394 |
target_type = type_get_by_name(typename); |
|
395 |
return type_is_ancestor(obj->class->type, target_type); |
|
391 |
return !target_type || type_is_ancestor(obj->class->type, target_type); |
|
396 | 392 |
} |
397 | 393 |
|
398 | 394 |
Object *object_dynamic_cast(Object *obj, const char *typename) |
399 | 395 |
{ |
396 |
TypeImpl *target_type = type_get_by_name(typename); |
|
400 | 397 |
GSList *i; |
401 | 398 |
|
402 | 399 |
/* Check if typename is a direct ancestor. Special-case TYPE_OBJECT, |
403 | 400 |
* we want to go back from interfaces to the parent. |
404 | 401 |
*/ |
405 |
if (typename && object_is_type(obj, typename)) {
|
|
402 |
if (target_type && object_is_type(obj, target_type)) {
|
|
406 | 403 |
return obj; |
407 | 404 |
} |
408 | 405 |
|
... | ... | |
410 | 407 |
* ancestor of typename. In principle we could do this test at the very |
411 | 408 |
* beginning of object_dynamic_cast, avoiding a second call to |
412 | 409 |
* object_is_type. However, casting between interfaces is relatively |
413 |
* rare, and object_is_type(obj, TYPE_INTERFACE) would fail almost always.
|
|
410 |
* rare, and object_is_type(obj, type_interface) would fail almost always.
|
|
414 | 411 |
* |
415 | 412 |
* Perhaps we could add a magic value to the object header for increased |
416 | 413 |
* (run-time) type safety and to speed up tests like this one. If we ever |
417 | 414 |
* do that we can revisit the order here. |
418 | 415 |
*/ |
419 |
if (object_is_type(obj, TYPE_INTERFACE)) {
|
|
416 |
if (object_is_type(obj, type_interface)) {
|
|
420 | 417 |
assert(!obj->interfaces); |
421 | 418 |
obj = INTERFACE(obj)->obj; |
422 |
if (object_is_type(obj, typename)) {
|
|
419 |
if (object_is_type(obj, target_type)) {
|
|
423 | 420 |
return obj; |
424 | 421 |
} |
425 | 422 |
} |
426 | 423 |
|
427 |
if (typename == TYPE_OBJECT) {
|
|
424 |
if (!target_type) {
|
|
428 | 425 |
return obj; |
429 | 426 |
} |
430 | 427 |
|
... | ... | |
432 | 429 |
for (i = obj->interfaces; i; i = i->next) { |
433 | 430 |
Interface *iface = i->data; |
434 | 431 |
|
435 |
if (object_is_type(OBJECT(iface), typename)) {
|
|
432 |
if (object_is_type(OBJECT(iface), target_type)) {
|
|
436 | 433 |
return OBJECT(iface); |
437 | 434 |
} |
438 | 435 |
} |
... | ... | |
449 | 446 |
.abstract = true, |
450 | 447 |
}; |
451 | 448 |
|
452 |
type_register_static(&interface_info); |
|
449 |
type_interface = type_register_static(&interface_info);
|
|
453 | 450 |
} |
454 | 451 |
|
455 | 452 |
device_init(register_interface); |
Also available in: Unified diff