1 /* 2 * QEMU Object Model 3 * 4 * Copyright IBM, Corp. 2011 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 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. 11 */ 12 13 #include "qemu/object.h" 14 #include "qemu-common.h" 15 #include "qapi/qapi-visit-core.h" 16 #include "qapi/string-input-visitor.h" 17 #include "qapi/string-output-visitor.h" 18 19 /* TODO: replace QObject with a simpler visitor to avoid a dependency 20 * of the QOM core on QObject? */ 21 #include "qemu/qom-qobject.h" 22 #include "qobject.h" 23 #include "qbool.h" 24 #include "qint.h" 25 #include "qstring.h" 26 27 #define MAX_INTERFACES 32 28 29 typedef struct InterfaceImpl InterfaceImpl; 30 typedef struct TypeImpl TypeImpl; 31 32 struct InterfaceImpl 33 { 34 const char *parent; 35 void (*interface_initfn)(ObjectClass *class, void *data); 36 TypeImpl *type; 37 }; 38 39 struct TypeImpl 40 { 41 const char *name; 42 43 size_t class_size; 44 45 size_t instance_size; 46 47 void (*class_init)(ObjectClass *klass, void *data); 48 void (*class_finalize)(ObjectClass *klass, void *data); 49 50 void *class_data; 51 52 void (*instance_init)(Object *obj); 53 void (*instance_finalize)(Object *obj); 54 55 bool abstract; 56 57 const char *parent; 58 TypeImpl *parent_type; 59 60 ObjectClass *class; 61 62 int num_interfaces; 63 InterfaceImpl interfaces[MAX_INTERFACES]; 64 }; 65 66 typedef struct Interface 67 { 68 Object parent; 69 Object *obj; 70 } Interface; 71 72 #define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE) 73 74 static Type type_interface; 75 76 static GHashTable *type_table_get(void) 77 { 78 static GHashTable *type_table; 79 80 if (type_table == NULL) { 81 type_table = g_hash_table_new(g_str_hash, g_str_equal); 82 } 83 84 return type_table; 85 } 86 87 static void type_table_add(TypeImpl *ti) 88 { 89 g_hash_table_insert(type_table_get(), (void *)ti->name, ti); 90 } 91 92 static TypeImpl *type_table_lookup(const char *name) 93 { 94 return g_hash_table_lookup(type_table_get(), name); 95 } 96 97 TypeImpl *type_register(const TypeInfo *info) 98 { 99 TypeImpl *ti = g_malloc0(sizeof(*ti)); 100 101 g_assert(info->name != NULL); 102 103 if (type_table_lookup(info->name) != NULL) { 104 fprintf(stderr, "Registering `%s' which already exists\n", info->name); 105 abort(); 106 } 107 108 ti->name = g_strdup(info->name); 109 ti->parent = g_strdup(info->parent); 110 111 ti->class_size = info->class_size; 112 ti->instance_size = info->instance_size; 113 114 ti->class_init = info->class_init; 115 ti->class_finalize = info->class_finalize; 116 ti->class_data = info->class_data; 117 118 ti->instance_init = info->instance_init; 119 ti->instance_finalize = info->instance_finalize; 120 121 ti->abstract = info->abstract; 122 123 if (info->interfaces) { 124 int i; 125 126 for (i = 0; info->interfaces[i].type; i++) { 127 ti->interfaces[i].parent = info->interfaces[i].type; 128 ti->interfaces[i].interface_initfn = info->interfaces[i].interface_initfn; 129 ti->num_interfaces++; 130 } 131 } 132 133 type_table_add(ti); 134 135 return ti; 136 } 137 138 TypeImpl *type_register_static(const TypeInfo *info) 139 { 140 return type_register(info); 141 } 142 143 static TypeImpl *type_get_by_name(const char *name) 144 { 145 if (name == NULL) { 146 return NULL; 147 } 148 149 return type_table_lookup(name); 150 } 151 152 static TypeImpl *type_get_parent(TypeImpl *type) 153 { 154 if (!type->parent_type && type->parent) { 155 type->parent_type = type_get_by_name(type->parent); 156 g_assert(type->parent_type != NULL); 157 } 158 159 return type->parent_type; 160 } 161 162 static bool type_has_parent(TypeImpl *type) 163 { 164 return (type->parent != NULL); 165 } 166 167 static size_t type_class_get_size(TypeImpl *ti) 168 { 169 if (ti->class_size) { 170 return ti->class_size; 171 } 172 173 if (type_has_parent(ti)) { 174 return type_class_get_size(type_get_parent(ti)); 175 } 176 177 return sizeof(ObjectClass); 178 } 179 180 static size_t type_object_get_size(TypeImpl *ti) 181 { 182 if (ti->instance_size) { 183 return ti->instance_size; 184 } 185 186 if (type_has_parent(ti)) { 187 return type_object_get_size(type_get_parent(ti)); 188 } 189 190 return 0; 191 } 192 193 static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface) 194 { 195 TypeInfo info = { 196 .instance_size = sizeof(Interface), 197 .parent = iface->parent, 198 .class_size = sizeof(InterfaceClass), 199 .class_init = iface->interface_initfn, 200 .abstract = true, 201 }; 202 char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent); 203 204 info.name = name; 205 iface->type = type_register(&info); 206 g_free(name); 207 } 208 209 static void type_initialize(TypeImpl *ti) 210 { 211 size_t class_size = sizeof(ObjectClass); 212 int i; 213 214 if (ti->class) { 215 return; 216 } 217 218 ti->class_size = type_class_get_size(ti); 219 ti->instance_size = type_object_get_size(ti); 220 221 ti->class = g_malloc0(ti->class_size); 222 ti->class->type = ti; 223 224 if (type_has_parent(ti)) { 225 TypeImpl *parent = type_get_parent(ti); 226 227 type_initialize(parent); 228 229 class_size = parent->class_size; 230 g_assert(parent->class_size <= ti->class_size); 231 232 memcpy((void *)ti->class + sizeof(ObjectClass), 233 (void *)parent->class + sizeof(ObjectClass), 234 parent->class_size - sizeof(ObjectClass)); 235 } 236 237 memset((void *)ti->class + class_size, 0, ti->class_size - class_size); 238 239 for (i = 0; i < ti->num_interfaces; i++) { 240 type_class_interface_init(ti, &ti->interfaces[i]); 241 } 242 243 if (ti->class_init) { 244 ti->class_init(ti->class, ti->class_data); 245 } 246 } 247 248 static void object_interface_init(Object *obj, InterfaceImpl *iface) 249 { 250 TypeImpl *ti = iface->type; 251 Interface *iface_obj; 252 253 iface_obj = INTERFACE(object_new(ti->name)); 254 iface_obj->obj = obj; 255 256 obj->interfaces = g_slist_prepend(obj->interfaces, iface_obj); 257 } 258 259 static void object_init_with_type(Object *obj, TypeImpl *ti) 260 { 261 int i; 262 263 if (type_has_parent(ti)) { 264 object_init_with_type(obj, type_get_parent(ti)); 265 } 266 267 for (i = 0; i < ti->num_interfaces; i++) { 268 object_interface_init(obj, &ti->interfaces[i]); 269 } 270 271 if (ti->instance_init) { 272 ti->instance_init(obj); 273 } 274 } 275 276 void object_initialize_with_type(void *data, TypeImpl *type) 277 { 278 Object *obj = data; 279 280 g_assert(type != NULL); 281 type_initialize(type); 282 283 g_assert(type->instance_size >= sizeof(Object)); 284 g_assert(type->abstract == false); 285 286 memset(obj, 0, type->instance_size); 287 obj->class = type->class; 288 QTAILQ_INIT(&obj->properties); 289 object_init_with_type(obj, type); 290 } 291 292 void object_initialize(void *data, const char *typename) 293 { 294 TypeImpl *type = type_get_by_name(typename); 295 296 object_initialize_with_type(data, type); 297 } 298 299 static void object_property_del_all(Object *obj) 300 { 301 while (!QTAILQ_EMPTY(&obj->properties)) { 302 ObjectProperty *prop = QTAILQ_FIRST(&obj->properties); 303 304 QTAILQ_REMOVE(&obj->properties, prop, node); 305 306 if (prop->release) { 307 prop->release(obj, prop->name, prop->opaque); 308 } 309 310 g_free(prop->name); 311 g_free(prop->type); 312 g_free(prop); 313 } 314 } 315 316 static void object_property_del_child(Object *obj, Object *child, Error **errp) 317 { 318 ObjectProperty *prop; 319 320 QTAILQ_FOREACH(prop, &obj->properties, node) { 321 if (strstart(prop->type, "child<", NULL) && prop->opaque == child) { 322 object_property_del(obj, prop->name, errp); 323 break; 324 } 325 } 326 } 327 328 void object_unparent(Object *obj) 329 { 330 if (obj->parent) { 331 object_property_del_child(obj->parent, obj, NULL); 332 } 333 } 334 335 static void object_deinit(Object *obj, TypeImpl *type) 336 { 337 if (type->instance_finalize) { 338 type->instance_finalize(obj); 339 } 340 341 while (obj->interfaces) { 342 Interface *iface_obj = obj->interfaces->data; 343 obj->interfaces = g_slist_delete_link(obj->interfaces, obj->interfaces); 344 object_delete(OBJECT(iface_obj)); 345 } 346 347 if (type_has_parent(type)) { 348 object_deinit(obj, type_get_parent(type)); 349 } 350 351 object_unparent(obj); 352 } 353 354 void object_finalize(void *data) 355 { 356 Object *obj = data; 357 TypeImpl *ti = obj->class->type; 358 359 object_deinit(obj, ti); 360 object_property_del_all(obj); 361 362 g_assert(obj->ref == 0); 363 } 364 365 Object *object_new_with_type(Type type) 366 { 367 Object *obj; 368 369 g_assert(type != NULL); 370 type_initialize(type); 371 372 obj = g_malloc(type->instance_size); 373 object_initialize_with_type(obj, type); 374 object_ref(obj); 375 376 return obj; 377 } 378 379 Object *object_new(const char *typename) 380 { 381 TypeImpl *ti = type_get_by_name(typename); 382 383 return object_new_with_type(ti); 384 } 385 386 void object_delete(Object *obj) 387 { 388 object_unref(obj); 389 g_assert(obj->ref == 0); 390 g_free(obj); 391 } 392 393 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) 394 { 395 assert(target_type); 396 397 /* Check if typename is a direct ancestor of type */ 398 while (type) { 399 if (type == target_type) { 400 return true; 401 } 402 403 type = type_get_parent(type); 404 } 405 406 return false; 407 } 408 409 static bool object_is_type(Object *obj, TypeImpl *target_type) 410 { 411 return !target_type || type_is_ancestor(obj->class->type, target_type); 412 } 413 414 Object *object_dynamic_cast(Object *obj, const char *typename) 415 { 416 TypeImpl *target_type = type_get_by_name(typename); 417 GSList *i; 418 419 /* Check if typename is a direct ancestor. Special-case TYPE_OBJECT, 420 * we want to go back from interfaces to the parent. 421 */ 422 if (target_type && object_is_type(obj, target_type)) { 423 return obj; 424 } 425 426 /* Check if obj is an interface and its containing object is a direct 427 * ancestor of typename. In principle we could do this test at the very 428 * beginning of object_dynamic_cast, avoiding a second call to 429 * object_is_type. However, casting between interfaces is relatively 430 * rare, and object_is_type(obj, type_interface) would fail almost always. 431 * 432 * Perhaps we could add a magic value to the object header for increased 433 * (run-time) type safety and to speed up tests like this one. If we ever 434 * do that we can revisit the order here. 435 */ 436 if (object_is_type(obj, type_interface)) { 437 assert(!obj->interfaces); 438 obj = INTERFACE(obj)->obj; 439 if (object_is_type(obj, target_type)) { 440 return obj; 441 } 442 } 443 444 if (!target_type) { 445 return obj; 446 } 447 448 /* Check if obj has an interface of typename */ 449 for (i = obj->interfaces; i; i = i->next) { 450 Interface *iface = i->data; 451 452 if (object_is_type(OBJECT(iface), target_type)) { 453 return OBJECT(iface); 454 } 455 } 456 457 return NULL; 458 } 459 460 461 static void register_types(void) 462 { 463 static TypeInfo interface_info = { 464 .name = TYPE_INTERFACE, 465 .instance_size = sizeof(Interface), 466 .abstract = true, 467 }; 468 469 type_interface = type_register_static(&interface_info); 470 } 471 472 type_init(register_types) 473 474 Object *object_dynamic_cast_assert(Object *obj, const char *typename) 475 { 476 Object *inst; 477 478 inst = object_dynamic_cast(obj, typename); 479 480 if (!inst) { 481 fprintf(stderr, "Object %p is not an instance of type %s\n", 482 obj, typename); 483 abort(); 484 } 485 486 return inst; 487 } 488 489 ObjectClass *object_class_dynamic_cast(ObjectClass *class, 490 const char *typename) 491 { 492 TypeImpl *target_type = type_get_by_name(typename); 493 TypeImpl *type = class->type; 494 495 while (type) { 496 if (type == target_type) { 497 return class; 498 } 499 500 type = type_get_parent(type); 501 } 502 503 return NULL; 504 } 505 506 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, 507 const char *typename) 508 { 509 ObjectClass *ret = object_class_dynamic_cast(class, typename); 510 511 if (!ret) { 512 fprintf(stderr, "Object %p is not an instance of type %s\n", 513 class, typename); 514 abort(); 515 } 516 517 return ret; 518 } 519 520 const char *object_get_typename(Object *obj) 521 { 522 return obj->class->type->name; 523 } 524 525 ObjectClass *object_get_class(Object *obj) 526 { 527 return obj->class; 528 } 529 530 const char *object_class_get_name(ObjectClass *klass) 531 { 532 return klass->type->name; 533 } 534 535 ObjectClass *object_class_by_name(const char *typename) 536 { 537 TypeImpl *type = type_get_by_name(typename); 538 539 if (!type) { 540 return NULL; 541 } 542 543 type_initialize(type); 544 545 return type->class; 546 } 547 548 typedef struct OCFData 549 { 550 void (*fn)(ObjectClass *klass, void *opaque); 551 const char *implements_type; 552 bool include_abstract; 553 void *opaque; 554 } OCFData; 555 556 static void object_class_foreach_tramp(gpointer key, gpointer value, 557 gpointer opaque) 558 { 559 OCFData *data = opaque; 560 TypeImpl *type = value; 561 ObjectClass *k; 562 563 type_initialize(type); 564 k = type->class; 565 566 if (!data->include_abstract && type->abstract) { 567 return; 568 } 569 570 if (data->implements_type && 571 !object_class_dynamic_cast(k, data->implements_type)) { 572 return; 573 } 574 575 data->fn(k, data->opaque); 576 } 577 578 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), 579 const char *implements_type, bool include_abstract, 580 void *opaque) 581 { 582 OCFData data = { fn, implements_type, include_abstract, opaque }; 583 584 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); 585 } 586 587 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque) 588 { 589 GSList **list = opaque; 590 591 *list = g_slist_prepend(*list, klass); 592 } 593 594 GSList *object_class_get_list(const char *implements_type, 595 bool include_abstract) 596 { 597 GSList *list = NULL; 598 599 object_class_foreach(object_class_get_list_tramp, 600 implements_type, include_abstract, &list); 601 return list; 602 } 603 604 void object_ref(Object *obj) 605 { 606 obj->ref++; 607 } 608 609 void object_unref(Object *obj) 610 { 611 g_assert(obj->ref > 0); 612 obj->ref--; 613 614 /* parent always holds a reference to its children */ 615 if (obj->ref == 0) { 616 object_finalize(obj); 617 } 618 } 619 620 void object_property_add(Object *obj, const char *name, const char *type, 621 ObjectPropertyAccessor *get, 622 ObjectPropertyAccessor *set, 623 ObjectPropertyRelease *release, 624 void *opaque, Error **errp) 625 { 626 ObjectProperty *prop = g_malloc0(sizeof(*prop)); 627 628 prop->name = g_strdup(name); 629 prop->type = g_strdup(type); 630 631 prop->get = get; 632 prop->set = set; 633 prop->release = release; 634 prop->opaque = opaque; 635 636 QTAILQ_INSERT_TAIL(&obj->properties, prop, node); 637 } 638 639 static ObjectProperty *object_property_find(Object *obj, const char *name) 640 { 641 ObjectProperty *prop; 642 643 QTAILQ_FOREACH(prop, &obj->properties, node) { 644 if (strcmp(prop->name, name) == 0) { 645 return prop; 646 } 647 } 648 649 return NULL; 650 } 651 652 void object_property_del(Object *obj, const char *name, Error **errp) 653 { 654 ObjectProperty *prop = object_property_find(obj, name); 655 656 QTAILQ_REMOVE(&obj->properties, prop, node); 657 658 prop->release(obj, prop->name, prop->opaque); 659 660 g_free(prop->name); 661 g_free(prop->type); 662 g_free(prop); 663 } 664 665 void object_property_get(Object *obj, Visitor *v, const char *name, 666 Error **errp) 667 { 668 ObjectProperty *prop = object_property_find(obj, name); 669 670 if (prop == NULL) { 671 error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); 672 return; 673 } 674 675 if (!prop->get) { 676 error_set(errp, QERR_PERMISSION_DENIED); 677 } else { 678 prop->get(obj, v, prop->opaque, name, errp); 679 } 680 } 681 682 void object_property_set(Object *obj, Visitor *v, const char *name, 683 Error **errp) 684 { 685 ObjectProperty *prop = object_property_find(obj, name); 686 687 if (prop == NULL) { 688 error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); 689 return; 690 } 691 692 if (!prop->set) { 693 error_set(errp, QERR_PERMISSION_DENIED); 694 } else { 695 prop->set(obj, v, prop->opaque, name, errp); 696 } 697 } 698 699 void object_property_set_str(Object *obj, const char *value, 700 const char *name, Error **errp) 701 { 702 QString *qstr = qstring_from_str(value); 703 object_property_set_qobject(obj, QOBJECT(qstr), name, errp); 704 705 QDECREF(qstr); 706 } 707 708 char *object_property_get_str(Object *obj, const char *name, 709 Error **errp) 710 { 711 QObject *ret = object_property_get_qobject(obj, name, errp); 712 QString *qstring; 713 char *retval; 714 715 if (!ret) { 716 return NULL; 717 } 718 qstring = qobject_to_qstring(ret); 719 if (!qstring) { 720 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 721 retval = NULL; 722 } else { 723 retval = g_strdup(qstring_get_str(qstring)); 724 } 725 726 QDECREF(qstring); 727 return retval; 728 } 729 730 void object_property_set_link(Object *obj, Object *value, 731 const char *name, Error **errp) 732 { 733 object_property_set_str(obj, object_get_canonical_path(value), 734 name, errp); 735 } 736 737 Object *object_property_get_link(Object *obj, const char *name, 738 Error **errp) 739 { 740 char *str = object_property_get_str(obj, name, errp); 741 Object *target = NULL; 742 743 if (str && *str) { 744 target = object_resolve_path(str, NULL); 745 if (!target) { 746 error_set(errp, QERR_DEVICE_NOT_FOUND, str); 747 } 748 } 749 750 g_free(str); 751 return target; 752 } 753 754 void object_property_set_bool(Object *obj, bool value, 755 const char *name, Error **errp) 756 { 757 QBool *qbool = qbool_from_int(value); 758 object_property_set_qobject(obj, QOBJECT(qbool), name, errp); 759 760 QDECREF(qbool); 761 } 762 763 bool object_property_get_bool(Object *obj, const char *name, 764 Error **errp) 765 { 766 QObject *ret = object_property_get_qobject(obj, name, errp); 767 QBool *qbool; 768 bool retval; 769 770 if (!ret) { 771 return false; 772 } 773 qbool = qobject_to_qbool(ret); 774 if (!qbool) { 775 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 776 retval = false; 777 } else { 778 retval = qbool_get_int(qbool); 779 } 780 781 QDECREF(qbool); 782 return retval; 783 } 784 785 void object_property_set_int(Object *obj, int64_t value, 786 const char *name, Error **errp) 787 { 788 QInt *qint = qint_from_int(value); 789 object_property_set_qobject(obj, QOBJECT(qint), name, errp); 790 791 QDECREF(qint); 792 } 793 794 int64_t object_property_get_int(Object *obj, const char *name, 795 Error **errp) 796 { 797 QObject *ret = object_property_get_qobject(obj, name, errp); 798 QInt *qint; 799 int64_t retval; 800 801 if (!ret) { 802 return -1; 803 } 804 qint = qobject_to_qint(ret); 805 if (!qint) { 806 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 807 retval = -1; 808 } else { 809 retval = qint_get_int(qint); 810 } 811 812 QDECREF(qint); 813 return retval; 814 } 815 816 void object_property_parse(Object *obj, const char *string, 817 const char *name, Error **errp) 818 { 819 StringInputVisitor *mi; 820 mi = string_input_visitor_new(string); 821 object_property_set(obj, string_input_get_visitor(mi), name, errp); 822 823 string_input_visitor_cleanup(mi); 824 } 825 826 char *object_property_print(Object *obj, const char *name, 827 Error **errp) 828 { 829 StringOutputVisitor *mo; 830 char *string; 831 832 mo = string_output_visitor_new(); 833 object_property_get(obj, string_output_get_visitor(mo), name, errp); 834 string = string_output_get_string(mo); 835 string_output_visitor_cleanup(mo); 836 return string; 837 } 838 839 const char *object_property_get_type(Object *obj, const char *name, Error **errp) 840 { 841 ObjectProperty *prop = object_property_find(obj, name); 842 843 if (prop == NULL) { 844 error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); 845 return NULL; 846 } 847 848 return prop->type; 849 } 850 851 Object *object_get_root(void) 852 { 853 static Object *root; 854 855 if (!root) { 856 root = object_new("container"); 857 } 858 859 return root; 860 } 861 862 static void object_get_child_property(Object *obj, Visitor *v, void *opaque, 863 const char *name, Error **errp) 864 { 865 Object *child = opaque; 866 gchar *path; 867 868 path = object_get_canonical_path(child); 869 visit_type_str(v, &path, name, errp); 870 g_free(path); 871 } 872 873 static void object_finalize_child_property(Object *obj, const char *name, 874 void *opaque) 875 { 876 Object *child = opaque; 877 878 object_unref(child); 879 } 880 881 void object_property_add_child(Object *obj, const char *name, 882 Object *child, Error **errp) 883 { 884 gchar *type; 885 886 /* Registering an interface object in the composition tree will mightily 887 * confuse object_get_canonical_path (which, on the other hand, knows how 888 * to get the canonical path of an interface object). 889 */ 890 assert(!object_is_type(obj, type_interface)); 891 892 type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); 893 894 object_property_add(obj, name, type, object_get_child_property, 895 NULL, object_finalize_child_property, child, errp); 896 897 object_ref(child); 898 g_assert(child->parent == NULL); 899 child->parent = obj; 900 901 g_free(type); 902 } 903 904 static void object_get_link_property(Object *obj, Visitor *v, void *opaque, 905 const char *name, Error **errp) 906 { 907 Object **child = opaque; 908 gchar *path; 909 910 if (*child) { 911 path = object_get_canonical_path(*child); 912 visit_type_str(v, &path, name, errp); 913 g_free(path); 914 } else { 915 path = (gchar *)""; 916 visit_type_str(v, &path, name, errp); 917 } 918 } 919 920 static void object_set_link_property(Object *obj, Visitor *v, void *opaque, 921 const char *name, Error **errp) 922 { 923 Object **child = opaque; 924 Object *old_target; 925 bool ambiguous = false; 926 const char *type; 927 char *path; 928 gchar *target_type; 929 930 type = object_property_get_type(obj, name, NULL); 931 932 visit_type_str(v, &path, name, errp); 933 934 old_target = *child; 935 *child = NULL; 936 937 if (strcmp(path, "") != 0) { 938 Object *target; 939 940 /* Go from link<FOO> to FOO. */ 941 target_type = g_strndup(&type[5], strlen(type) - 6); 942 target = object_resolve_path_type(path, target_type, &ambiguous); 943 944 if (ambiguous) { 945 error_set(errp, QERR_AMBIGUOUS_PATH, path); 946 } else if (target) { 947 object_ref(target); 948 *child = target; 949 } else { 950 target = object_resolve_path(path, &ambiguous); 951 if (target || ambiguous) { 952 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 953 } else { 954 error_set(errp, QERR_DEVICE_NOT_FOUND, path); 955 } 956 } 957 g_free(target_type); 958 } 959 960 g_free(path); 961 962 if (old_target != NULL) { 963 object_unref(old_target); 964 } 965 } 966 967 void object_property_add_link(Object *obj, const char *name, 968 const char *type, Object **child, 969 Error **errp) 970 { 971 gchar *full_type; 972 973 full_type = g_strdup_printf("link<%s>", type); 974 975 object_property_add(obj, name, full_type, 976 object_get_link_property, 977 object_set_link_property, 978 NULL, child, errp); 979 980 g_free(full_type); 981 } 982 983 gchar *object_get_canonical_path(Object *obj) 984 { 985 Object *root = object_get_root(); 986 char *newpath = NULL, *path = NULL; 987 988 if (object_is_type(obj, type_interface)) { 989 obj = INTERFACE(obj)->obj; 990 } 991 992 while (obj != root) { 993 ObjectProperty *prop = NULL; 994 995 g_assert(obj->parent != NULL); 996 997 QTAILQ_FOREACH(prop, &obj->parent->properties, node) { 998 if (!strstart(prop->type, "child<", NULL)) { 999 continue; 1000 } 1001 1002 if (prop->opaque == obj) { 1003 if (path) { 1004 newpath = g_strdup_printf("%s/%s", prop->name, path); 1005 g_free(path); 1006 path = newpath; 1007 } else { 1008 path = g_strdup(prop->name); 1009 } 1010 break; 1011 } 1012 } 1013 1014 g_assert(prop != NULL); 1015 1016 obj = obj->parent; 1017 } 1018 1019 newpath = g_strdup_printf("/%s", path); 1020 g_free(path); 1021 1022 return newpath; 1023 } 1024 1025 Object *object_resolve_path_component(Object *parent, gchar *part) 1026 { 1027 ObjectProperty *prop = object_property_find(parent, part); 1028 if (prop == NULL) { 1029 return NULL; 1030 } 1031 1032 if (strstart(prop->type, "link<", NULL)) { 1033 return *(Object **)prop->opaque; 1034 } else if (strstart(prop->type, "child<", NULL)) { 1035 return prop->opaque; 1036 } else { 1037 return NULL; 1038 } 1039 } 1040 1041 static Object *object_resolve_abs_path(Object *parent, 1042 gchar **parts, 1043 const char *typename, 1044 int index) 1045 { 1046 Object *child; 1047 1048 if (parts[index] == NULL) { 1049 return object_dynamic_cast(parent, typename); 1050 } 1051 1052 if (strcmp(parts[index], "") == 0) { 1053 return object_resolve_abs_path(parent, parts, typename, index + 1); 1054 } 1055 1056 child = object_resolve_path_component(parent, parts[index]); 1057 if (!child) { 1058 return NULL; 1059 } 1060 1061 return object_resolve_abs_path(child, parts, typename, index + 1); 1062 } 1063 1064 static Object *object_resolve_partial_path(Object *parent, 1065 gchar **parts, 1066 const char *typename, 1067 bool *ambiguous) 1068 { 1069 Object *obj; 1070 ObjectProperty *prop; 1071 1072 obj = object_resolve_abs_path(parent, parts, typename, 0); 1073 1074 QTAILQ_FOREACH(prop, &parent->properties, node) { 1075 Object *found; 1076 1077 if (!strstart(prop->type, "child<", NULL)) { 1078 continue; 1079 } 1080 1081 found = object_resolve_partial_path(prop->opaque, parts, 1082 typename, ambiguous); 1083 if (found) { 1084 if (obj) { 1085 if (ambiguous) { 1086 *ambiguous = true; 1087 } 1088 return NULL; 1089 } 1090 obj = found; 1091 } 1092 1093 if (ambiguous && *ambiguous) { 1094 return NULL; 1095 } 1096 } 1097 1098 return obj; 1099 } 1100 1101 Object *object_resolve_path_type(const char *path, const char *typename, 1102 bool *ambiguous) 1103 { 1104 bool partial_path = true; 1105 Object *obj; 1106 gchar **parts; 1107 1108 parts = g_strsplit(path, "/", 0); 1109 if (parts == NULL || parts[0] == NULL) { 1110 g_strfreev(parts); 1111 return object_get_root(); 1112 } 1113 1114 if (strcmp(parts[0], "") == 0) { 1115 partial_path = false; 1116 } 1117 1118 if (partial_path) { 1119 if (ambiguous) { 1120 *ambiguous = false; 1121 } 1122 obj = object_resolve_partial_path(object_get_root(), parts, 1123 typename, ambiguous); 1124 } else { 1125 obj = object_resolve_abs_path(object_get_root(), parts, typename, 1); 1126 } 1127 1128 g_strfreev(parts); 1129 1130 return obj; 1131 } 1132 1133 Object *object_resolve_path(const char *path, bool *ambiguous) 1134 { 1135 return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 1136 } 1137 1138 typedef struct StringProperty 1139 { 1140 char *(*get)(Object *, Error **); 1141 void (*set)(Object *, const char *, Error **); 1142 } StringProperty; 1143 1144 static void property_get_str(Object *obj, Visitor *v, void *opaque, 1145 const char *name, Error **errp) 1146 { 1147 StringProperty *prop = opaque; 1148 char *value; 1149 1150 value = prop->get(obj, errp); 1151 if (value) { 1152 visit_type_str(v, &value, name, errp); 1153 g_free(value); 1154 } 1155 } 1156 1157 static void property_set_str(Object *obj, Visitor *v, void *opaque, 1158 const char *name, Error **errp) 1159 { 1160 StringProperty *prop = opaque; 1161 char *value; 1162 Error *local_err = NULL; 1163 1164 visit_type_str(v, &value, name, &local_err); 1165 if (local_err) { 1166 error_propagate(errp, local_err); 1167 return; 1168 } 1169 1170 prop->set(obj, value, errp); 1171 g_free(value); 1172 } 1173 1174 static void property_release_str(Object *obj, const char *name, 1175 void *opaque) 1176 { 1177 StringProperty *prop = opaque; 1178 g_free(prop); 1179 } 1180 1181 void object_property_add_str(Object *obj, const char *name, 1182 char *(*get)(Object *, Error **), 1183 void (*set)(Object *, const char *, Error **), 1184 Error **errp) 1185 { 1186 StringProperty *prop = g_malloc0(sizeof(*prop)); 1187 1188 prop->get = get; 1189 prop->set = set; 1190 1191 object_property_add(obj, name, "string", 1192 get ? property_get_str : NULL, 1193 set ? property_set_str : NULL, 1194 property_release_str, 1195 prop, errp); 1196 } 1197