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/osdep.h" 14 #include "hw/qdev-core.h" 15 #include "qapi/error.h" 16 #include "qom/object.h" 17 #include "qom/object_interfaces.h" 18 #include "qemu/cutils.h" 19 #include "qemu/memalign.h" 20 #include "qapi/visitor.h" 21 #include "qapi/string-input-visitor.h" 22 #include "qapi/string-output-visitor.h" 23 #include "qapi/qobject-input-visitor.h" 24 #include "qapi/forward-visitor.h" 25 #include "qapi/qapi-builtin-visit.h" 26 #include "qapi/qmp/qerror.h" 27 #include "qapi/qmp/qjson.h" 28 #include "trace.h" 29 30 /* TODO: replace QObject with a simpler visitor to avoid a dependency 31 * of the QOM core on QObject? */ 32 #include "qom/qom-qobject.h" 33 #include "qapi/qmp/qbool.h" 34 #include "qapi/qmp/qnum.h" 35 #include "qapi/qmp/qstring.h" 36 #include "qemu/error-report.h" 37 38 #define MAX_INTERFACES 32 39 40 typedef struct InterfaceImpl InterfaceImpl; 41 typedef struct TypeImpl TypeImpl; 42 43 struct InterfaceImpl 44 { 45 const char *typename; 46 }; 47 48 struct TypeImpl 49 { 50 const char *name; 51 52 size_t class_size; 53 54 size_t instance_size; 55 size_t instance_align; 56 57 void (*class_init)(ObjectClass *klass, void *data); 58 void (*class_base_init)(ObjectClass *klass, void *data); 59 60 void *class_data; 61 62 void (*instance_init)(Object *obj); 63 void (*instance_post_init)(Object *obj); 64 void (*instance_finalize)(Object *obj); 65 66 bool abstract; 67 68 const char *parent; 69 TypeImpl *parent_type; 70 71 ObjectClass *class; 72 73 int num_interfaces; 74 InterfaceImpl interfaces[MAX_INTERFACES]; 75 }; 76 77 static Type type_interface; 78 79 static GHashTable *type_table_get(void) 80 { 81 static GHashTable *type_table; 82 83 if (type_table == NULL) { 84 type_table = g_hash_table_new(g_str_hash, g_str_equal); 85 } 86 87 return type_table; 88 } 89 90 static bool enumerating_types; 91 92 static void type_table_add(TypeImpl *ti) 93 { 94 assert(!enumerating_types); 95 g_hash_table_insert(type_table_get(), (void *)ti->name, ti); 96 } 97 98 static TypeImpl *type_table_lookup(const char *name) 99 { 100 return g_hash_table_lookup(type_table_get(), name); 101 } 102 103 static TypeImpl *type_new(const TypeInfo *info) 104 { 105 TypeImpl *ti = g_malloc0(sizeof(*ti)); 106 int i; 107 108 g_assert(info->name != NULL); 109 110 if (type_table_lookup(info->name) != NULL) { 111 fprintf(stderr, "Registering `%s' which already exists\n", info->name); 112 abort(); 113 } 114 115 ti->name = g_strdup(info->name); 116 ti->parent = g_strdup(info->parent); 117 118 ti->class_size = info->class_size; 119 ti->instance_size = info->instance_size; 120 ti->instance_align = info->instance_align; 121 122 ti->class_init = info->class_init; 123 ti->class_base_init = info->class_base_init; 124 ti->class_data = info->class_data; 125 126 ti->instance_init = info->instance_init; 127 ti->instance_post_init = info->instance_post_init; 128 ti->instance_finalize = info->instance_finalize; 129 130 ti->abstract = info->abstract; 131 132 for (i = 0; info->interfaces && info->interfaces[i].type; i++) { 133 ti->interfaces[i].typename = g_strdup(info->interfaces[i].type); 134 } 135 ti->num_interfaces = i; 136 137 return ti; 138 } 139 140 static TypeImpl *type_register_internal(const TypeInfo *info) 141 { 142 TypeImpl *ti; 143 ti = type_new(info); 144 145 type_table_add(ti); 146 return ti; 147 } 148 149 TypeImpl *type_register(const TypeInfo *info) 150 { 151 assert(info->parent); 152 return type_register_internal(info); 153 } 154 155 TypeImpl *type_register_static(const TypeInfo *info) 156 { 157 return type_register(info); 158 } 159 160 void type_register_static_array(const TypeInfo *infos, int nr_infos) 161 { 162 int i; 163 164 for (i = 0; i < nr_infos; i++) { 165 type_register_static(&infos[i]); 166 } 167 } 168 169 static TypeImpl *type_get_by_name(const char *name) 170 { 171 if (name == NULL) { 172 return NULL; 173 } 174 175 return type_table_lookup(name); 176 } 177 178 static TypeImpl *type_get_parent(TypeImpl *type) 179 { 180 if (!type->parent_type && type->parent) { 181 type->parent_type = type_get_by_name(type->parent); 182 if (!type->parent_type) { 183 fprintf(stderr, "Type '%s' is missing its parent '%s'\n", 184 type->name, type->parent); 185 abort(); 186 } 187 } 188 189 return type->parent_type; 190 } 191 192 static bool type_has_parent(TypeImpl *type) 193 { 194 return (type->parent != NULL); 195 } 196 197 static size_t type_class_get_size(TypeImpl *ti) 198 { 199 if (ti->class_size) { 200 return ti->class_size; 201 } 202 203 if (type_has_parent(ti)) { 204 return type_class_get_size(type_get_parent(ti)); 205 } 206 207 return sizeof(ObjectClass); 208 } 209 210 static size_t type_object_get_size(TypeImpl *ti) 211 { 212 if (ti->instance_size) { 213 return ti->instance_size; 214 } 215 216 if (type_has_parent(ti)) { 217 return type_object_get_size(type_get_parent(ti)); 218 } 219 220 return 0; 221 } 222 223 size_t object_type_get_instance_size(const char *typename) 224 { 225 TypeImpl *type = type_get_by_name(typename); 226 227 g_assert(type != NULL); 228 return type_object_get_size(type); 229 } 230 231 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) 232 { 233 assert(target_type); 234 235 /* Check if target_type is a direct ancestor of type */ 236 while (type) { 237 if (type == target_type) { 238 return true; 239 } 240 241 type = type_get_parent(type); 242 } 243 244 return false; 245 } 246 247 static void type_initialize(TypeImpl *ti); 248 249 static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, 250 TypeImpl *parent_type) 251 { 252 InterfaceClass *new_iface; 253 TypeInfo info = { }; 254 TypeImpl *iface_impl; 255 256 info.parent = parent_type->name; 257 info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name); 258 info.abstract = true; 259 260 iface_impl = type_new(&info); 261 iface_impl->parent_type = parent_type; 262 type_initialize(iface_impl); 263 g_free((char *)info.name); 264 265 new_iface = (InterfaceClass *)iface_impl->class; 266 new_iface->concrete_class = ti->class; 267 new_iface->interface_type = interface_type; 268 269 ti->class->interfaces = g_slist_append(ti->class->interfaces, new_iface); 270 } 271 272 static void object_property_free(gpointer data) 273 { 274 ObjectProperty *prop = data; 275 276 if (prop->defval) { 277 qobject_unref(prop->defval); 278 prop->defval = NULL; 279 } 280 g_free(prop->name); 281 g_free(prop->type); 282 g_free(prop->description); 283 g_free(prop); 284 } 285 286 static void type_initialize(TypeImpl *ti) 287 { 288 TypeImpl *parent; 289 290 if (ti->class) { 291 return; 292 } 293 294 ti->class_size = type_class_get_size(ti); 295 ti->instance_size = type_object_get_size(ti); 296 /* Any type with zero instance_size is implicitly abstract. 297 * This means interface types are all abstract. 298 */ 299 if (ti->instance_size == 0) { 300 ti->abstract = true; 301 } 302 if (type_is_ancestor(ti, type_interface)) { 303 assert(ti->instance_size == 0); 304 assert(ti->abstract); 305 assert(!ti->instance_init); 306 assert(!ti->instance_post_init); 307 assert(!ti->instance_finalize); 308 assert(!ti->num_interfaces); 309 } 310 ti->class = g_malloc0(ti->class_size); 311 312 parent = type_get_parent(ti); 313 if (parent) { 314 type_initialize(parent); 315 GSList *e; 316 int i; 317 318 g_assert(parent->class_size <= ti->class_size); 319 g_assert(parent->instance_size <= ti->instance_size); 320 memcpy(ti->class, parent->class, parent->class_size); 321 ti->class->interfaces = NULL; 322 323 for (e = parent->class->interfaces; e; e = e->next) { 324 InterfaceClass *iface = e->data; 325 ObjectClass *klass = OBJECT_CLASS(iface); 326 327 type_initialize_interface(ti, iface->interface_type, klass->type); 328 } 329 330 for (i = 0; i < ti->num_interfaces; i++) { 331 TypeImpl *t = type_get_by_name(ti->interfaces[i].typename); 332 if (!t) { 333 error_report("missing interface '%s' for object '%s'", 334 ti->interfaces[i].typename, parent->name); 335 abort(); 336 } 337 for (e = ti->class->interfaces; e; e = e->next) { 338 TypeImpl *target_type = OBJECT_CLASS(e->data)->type; 339 340 if (type_is_ancestor(target_type, t)) { 341 break; 342 } 343 } 344 345 if (e) { 346 continue; 347 } 348 349 type_initialize_interface(ti, t, t); 350 } 351 } 352 353 ti->class->properties = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, 354 object_property_free); 355 356 ti->class->type = ti; 357 358 while (parent) { 359 if (parent->class_base_init) { 360 parent->class_base_init(ti->class, ti->class_data); 361 } 362 parent = type_get_parent(parent); 363 } 364 365 if (ti->class_init) { 366 ti->class_init(ti->class, ti->class_data); 367 } 368 } 369 370 static void object_init_with_type(Object *obj, TypeImpl *ti) 371 { 372 if (type_has_parent(ti)) { 373 object_init_with_type(obj, type_get_parent(ti)); 374 } 375 376 if (ti->instance_init) { 377 ti->instance_init(obj); 378 } 379 } 380 381 static void object_post_init_with_type(Object *obj, TypeImpl *ti) 382 { 383 if (ti->instance_post_init) { 384 ti->instance_post_init(obj); 385 } 386 387 if (type_has_parent(ti)) { 388 object_post_init_with_type(obj, type_get_parent(ti)); 389 } 390 } 391 392 bool object_apply_global_props(Object *obj, const GPtrArray *props, 393 Error **errp) 394 { 395 int i; 396 397 if (!props) { 398 return true; 399 } 400 401 for (i = 0; i < props->len; i++) { 402 GlobalProperty *p = g_ptr_array_index(props, i); 403 Error *err = NULL; 404 405 if (object_dynamic_cast(obj, p->driver) == NULL) { 406 continue; 407 } 408 if (p->optional && !object_property_find(obj, p->property)) { 409 continue; 410 } 411 p->used = true; 412 if (!object_property_parse(obj, p->property, p->value, &err)) { 413 error_prepend(&err, "can't apply global %s.%s=%s: ", 414 p->driver, p->property, p->value); 415 /* 416 * If errp != NULL, propagate error and return. 417 * If errp == NULL, report a warning, but keep going 418 * with the remaining globals. 419 */ 420 if (errp) { 421 error_propagate(errp, err); 422 return false; 423 } else { 424 warn_report_err(err); 425 } 426 } 427 } 428 429 return true; 430 } 431 432 /* 433 * Global property defaults 434 * Slot 0: accelerator's global property defaults 435 * Slot 1: machine's global property defaults 436 * Slot 2: global properties from legacy command line option 437 * Each is a GPtrArray of of GlobalProperty. 438 * Applied in order, later entries override earlier ones. 439 */ 440 static GPtrArray *object_compat_props[3]; 441 442 /* 443 * Retrieve @GPtrArray for global property defined with options 444 * other than "-global". These are generally used for syntactic 445 * sugar and legacy command line options. 446 */ 447 void object_register_sugar_prop(const char *driver, const char *prop, 448 const char *value, bool optional) 449 { 450 GlobalProperty *g; 451 if (!object_compat_props[2]) { 452 object_compat_props[2] = g_ptr_array_new(); 453 } 454 g = g_new0(GlobalProperty, 1); 455 g->driver = g_strdup(driver); 456 g->property = g_strdup(prop); 457 g->value = g_strdup(value); 458 g->optional = optional; 459 g_ptr_array_add(object_compat_props[2], g); 460 } 461 462 /* 463 * Set machine's global property defaults to @compat_props. 464 * May be called at most once. 465 */ 466 void object_set_machine_compat_props(GPtrArray *compat_props) 467 { 468 assert(!object_compat_props[1]); 469 object_compat_props[1] = compat_props; 470 } 471 472 /* 473 * Set accelerator's global property defaults to @compat_props. 474 * May be called at most once. 475 */ 476 void object_set_accelerator_compat_props(GPtrArray *compat_props) 477 { 478 assert(!object_compat_props[0]); 479 object_compat_props[0] = compat_props; 480 } 481 482 void object_apply_compat_props(Object *obj) 483 { 484 int i; 485 486 for (i = 0; i < ARRAY_SIZE(object_compat_props); i++) { 487 object_apply_global_props(obj, object_compat_props[i], 488 i == 2 ? &error_fatal : &error_abort); 489 } 490 } 491 492 static void object_class_property_init_all(Object *obj) 493 { 494 ObjectPropertyIterator iter; 495 ObjectProperty *prop; 496 497 object_class_property_iter_init(&iter, object_get_class(obj)); 498 while ((prop = object_property_iter_next(&iter))) { 499 if (prop->init) { 500 prop->init(obj, prop); 501 } 502 } 503 } 504 505 static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type) 506 { 507 type_initialize(type); 508 509 g_assert(type->instance_size >= sizeof(Object)); 510 g_assert(type->abstract == false); 511 g_assert(size >= type->instance_size); 512 513 memset(obj, 0, type->instance_size); 514 obj->class = type->class; 515 object_ref(obj); 516 object_class_property_init_all(obj); 517 obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal, 518 NULL, object_property_free); 519 object_init_with_type(obj, type); 520 object_post_init_with_type(obj, type); 521 } 522 523 void object_initialize(void *data, size_t size, const char *typename) 524 { 525 TypeImpl *type = type_get_by_name(typename); 526 527 #ifdef CONFIG_MODULES 528 if (!type) { 529 int rv = module_load_qom(typename, &error_fatal); 530 if (rv > 0) { 531 type = type_get_by_name(typename); 532 } else { 533 error_report("missing object type '%s'", typename); 534 exit(1); 535 } 536 } 537 #endif 538 if (!type) { 539 error_report("missing object type '%s'", typename); 540 abort(); 541 } 542 543 object_initialize_with_type(data, size, type); 544 } 545 546 bool object_initialize_child_with_props(Object *parentobj, 547 const char *propname, 548 void *childobj, size_t size, 549 const char *type, 550 Error **errp, ...) 551 { 552 va_list vargs; 553 bool ok; 554 555 va_start(vargs, errp); 556 ok = object_initialize_child_with_propsv(parentobj, propname, 557 childobj, size, type, errp, 558 vargs); 559 va_end(vargs); 560 return ok; 561 } 562 563 bool object_initialize_child_with_propsv(Object *parentobj, 564 const char *propname, 565 void *childobj, size_t size, 566 const char *type, 567 Error **errp, va_list vargs) 568 { 569 bool ok = false; 570 Object *obj; 571 UserCreatable *uc; 572 573 object_initialize(childobj, size, type); 574 obj = OBJECT(childobj); 575 576 if (!object_set_propv(obj, errp, vargs)) { 577 goto out; 578 } 579 580 object_property_add_child(parentobj, propname, obj); 581 582 uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE); 583 if (uc) { 584 if (!user_creatable_complete(uc, errp)) { 585 object_unparent(obj); 586 goto out; 587 } 588 } 589 590 ok = true; 591 592 out: 593 /* 594 * We want @obj's reference to be 1 on success, 0 on failure. 595 * On success, it's 2: one taken by object_initialize(), and one 596 * by object_property_add_child(). 597 * On failure in object_initialize() or earlier, it's 1. 598 * On failure afterwards, it's also 1: object_unparent() releases 599 * the reference taken by object_property_add_child(). 600 */ 601 object_unref(obj); 602 return ok; 603 } 604 605 void object_initialize_child_internal(Object *parent, 606 const char *propname, 607 void *child, size_t size, 608 const char *type) 609 { 610 object_initialize_child_with_props(parent, propname, child, size, type, 611 &error_abort, NULL); 612 } 613 614 static inline bool object_property_is_child(ObjectProperty *prop) 615 { 616 return strstart(prop->type, "child<", NULL); 617 } 618 619 static void object_property_del_all(Object *obj) 620 { 621 g_autoptr(GHashTable) done = g_hash_table_new(NULL, NULL); 622 ObjectProperty *prop; 623 ObjectPropertyIterator iter; 624 bool released; 625 626 do { 627 released = false; 628 object_property_iter_init(&iter, obj); 629 while ((prop = object_property_iter_next(&iter)) != NULL) { 630 if (g_hash_table_add(done, prop)) { 631 if (prop->release) { 632 prop->release(obj, prop->name, prop->opaque); 633 released = true; 634 break; 635 } 636 } 637 } 638 } while (released); 639 640 g_hash_table_unref(obj->properties); 641 } 642 643 static void object_property_del_child(Object *obj, Object *child) 644 { 645 ObjectProperty *prop; 646 GHashTableIter iter; 647 gpointer key, value; 648 649 g_hash_table_iter_init(&iter, obj->properties); 650 while (g_hash_table_iter_next(&iter, &key, &value)) { 651 prop = value; 652 if (object_property_is_child(prop) && prop->opaque == child) { 653 if (prop->release) { 654 prop->release(obj, prop->name, prop->opaque); 655 prop->release = NULL; 656 } 657 break; 658 } 659 } 660 g_hash_table_iter_init(&iter, obj->properties); 661 while (g_hash_table_iter_next(&iter, &key, &value)) { 662 prop = value; 663 if (object_property_is_child(prop) && prop->opaque == child) { 664 g_hash_table_iter_remove(&iter); 665 break; 666 } 667 } 668 } 669 670 void object_unparent(Object *obj) 671 { 672 if (obj->parent) { 673 object_property_del_child(obj->parent, obj); 674 } 675 } 676 677 static void object_deinit(Object *obj, TypeImpl *type) 678 { 679 if (type->instance_finalize) { 680 type->instance_finalize(obj); 681 } 682 683 if (type_has_parent(type)) { 684 object_deinit(obj, type_get_parent(type)); 685 } 686 } 687 688 static void object_finalize(void *data) 689 { 690 Object *obj = data; 691 TypeImpl *ti = obj->class->type; 692 693 object_property_del_all(obj); 694 object_deinit(obj, ti); 695 696 g_assert(obj->ref == 0); 697 g_assert(obj->parent == NULL); 698 if (obj->free) { 699 obj->free(obj); 700 } 701 } 702 703 /* Find the minimum alignment guaranteed by the system malloc. */ 704 #if __STDC_VERSION__ >= 201112L 705 typedef max_align_t qemu_max_align_t; 706 #else 707 typedef union { 708 long l; 709 void *p; 710 double d; 711 long double ld; 712 } qemu_max_align_t; 713 #endif 714 715 static Object *object_new_with_type(Type type) 716 { 717 Object *obj; 718 size_t size, align; 719 void (*obj_free)(void *); 720 721 g_assert(type != NULL); 722 type_initialize(type); 723 724 size = type->instance_size; 725 align = type->instance_align; 726 727 /* 728 * Do not use qemu_memalign unless required. Depending on the 729 * implementation, extra alignment implies extra overhead. 730 */ 731 if (likely(align <= __alignof__(qemu_max_align_t))) { 732 obj = g_malloc(size); 733 obj_free = g_free; 734 } else { 735 obj = qemu_memalign(align, size); 736 obj_free = qemu_vfree; 737 } 738 739 object_initialize_with_type(obj, size, type); 740 obj->free = obj_free; 741 742 return obj; 743 } 744 745 Object *object_new_with_class(ObjectClass *klass) 746 { 747 return object_new_with_type(klass->type); 748 } 749 750 Object *object_new(const char *typename) 751 { 752 TypeImpl *ti = type_get_by_name(typename); 753 754 return object_new_with_type(ti); 755 } 756 757 758 Object *object_new_with_props(const char *typename, 759 Object *parent, 760 const char *id, 761 Error **errp, 762 ...) 763 { 764 va_list vargs; 765 Object *obj; 766 767 va_start(vargs, errp); 768 obj = object_new_with_propv(typename, parent, id, errp, vargs); 769 va_end(vargs); 770 771 return obj; 772 } 773 774 775 Object *object_new_with_propv(const char *typename, 776 Object *parent, 777 const char *id, 778 Error **errp, 779 va_list vargs) 780 { 781 Object *obj; 782 ObjectClass *klass; 783 UserCreatable *uc; 784 785 klass = object_class_by_name(typename); 786 if (!klass) { 787 error_setg(errp, "invalid object type: %s", typename); 788 return NULL; 789 } 790 791 if (object_class_is_abstract(klass)) { 792 error_setg(errp, "object type '%s' is abstract", typename); 793 return NULL; 794 } 795 obj = object_new_with_type(klass->type); 796 797 if (!object_set_propv(obj, errp, vargs)) { 798 goto error; 799 } 800 801 if (id != NULL) { 802 object_property_add_child(parent, id, obj); 803 } 804 805 uc = (UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE); 806 if (uc) { 807 if (!user_creatable_complete(uc, errp)) { 808 if (id != NULL) { 809 object_unparent(obj); 810 } 811 goto error; 812 } 813 } 814 815 object_unref(obj); 816 return obj; 817 818 error: 819 object_unref(obj); 820 return NULL; 821 } 822 823 824 bool object_set_props(Object *obj, 825 Error **errp, 826 ...) 827 { 828 va_list vargs; 829 bool ret; 830 831 va_start(vargs, errp); 832 ret = object_set_propv(obj, errp, vargs); 833 va_end(vargs); 834 835 return ret; 836 } 837 838 839 bool object_set_propv(Object *obj, 840 Error **errp, 841 va_list vargs) 842 { 843 const char *propname; 844 845 propname = va_arg(vargs, char *); 846 while (propname != NULL) { 847 const char *value = va_arg(vargs, char *); 848 849 g_assert(value != NULL); 850 if (!object_property_parse(obj, propname, value, errp)) { 851 return false; 852 } 853 propname = va_arg(vargs, char *); 854 } 855 856 return true; 857 } 858 859 860 Object *object_dynamic_cast(Object *obj, const char *typename) 861 { 862 if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { 863 return obj; 864 } 865 866 return NULL; 867 } 868 869 Object *object_dynamic_cast_assert(Object *obj, const char *typename, 870 const char *file, int line, const char *func) 871 { 872 trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)", 873 typename, file, line, func); 874 875 #ifdef CONFIG_QOM_CAST_DEBUG 876 int i; 877 Object *inst; 878 879 for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { 880 if (qatomic_read(&obj->class->object_cast_cache[i]) == typename) { 881 goto out; 882 } 883 } 884 885 inst = object_dynamic_cast(obj, typename); 886 887 if (!inst && obj) { 888 fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 889 file, line, func, obj, typename); 890 abort(); 891 } 892 893 assert(obj == inst); 894 895 if (obj && obj == inst) { 896 for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 897 qatomic_set(&obj->class->object_cast_cache[i - 1], 898 qatomic_read(&obj->class->object_cast_cache[i])); 899 } 900 qatomic_set(&obj->class->object_cast_cache[i - 1], typename); 901 } 902 903 out: 904 #endif 905 return obj; 906 } 907 908 ObjectClass *object_class_dynamic_cast(ObjectClass *class, 909 const char *typename) 910 { 911 ObjectClass *ret = NULL; 912 TypeImpl *target_type; 913 TypeImpl *type; 914 915 if (!class) { 916 return NULL; 917 } 918 919 /* A simple fast path that can trigger a lot for leaf classes. */ 920 type = class->type; 921 if (type->name == typename) { 922 return class; 923 } 924 925 target_type = type_get_by_name(typename); 926 if (!target_type) { 927 /* target class type unknown, so fail the cast */ 928 return NULL; 929 } 930 931 if (type->class->interfaces && 932 type_is_ancestor(target_type, type_interface)) { 933 int found = 0; 934 GSList *i; 935 936 for (i = class->interfaces; i; i = i->next) { 937 ObjectClass *target_class = i->data; 938 939 if (type_is_ancestor(target_class->type, target_type)) { 940 ret = target_class; 941 found++; 942 } 943 } 944 945 /* The match was ambiguous, don't allow a cast */ 946 if (found > 1) { 947 ret = NULL; 948 } 949 } else if (type_is_ancestor(type, target_type)) { 950 ret = class; 951 } 952 953 return ret; 954 } 955 956 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, 957 const char *typename, 958 const char *file, int line, 959 const char *func) 960 { 961 ObjectClass *ret; 962 963 trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)", 964 typename, file, line, func); 965 966 #ifdef CONFIG_QOM_CAST_DEBUG 967 int i; 968 969 for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { 970 if (qatomic_read(&class->class_cast_cache[i]) == typename) { 971 ret = class; 972 goto out; 973 } 974 } 975 #else 976 if (!class || !class->interfaces) { 977 return class; 978 } 979 #endif 980 981 ret = object_class_dynamic_cast(class, typename); 982 if (!ret && class) { 983 fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 984 file, line, func, class, typename); 985 abort(); 986 } 987 988 #ifdef CONFIG_QOM_CAST_DEBUG 989 if (class && ret == class) { 990 for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 991 qatomic_set(&class->class_cast_cache[i - 1], 992 qatomic_read(&class->class_cast_cache[i])); 993 } 994 qatomic_set(&class->class_cast_cache[i - 1], typename); 995 } 996 out: 997 #endif 998 return ret; 999 } 1000 1001 const char *object_get_typename(const Object *obj) 1002 { 1003 return obj->class->type->name; 1004 } 1005 1006 ObjectClass *object_get_class(Object *obj) 1007 { 1008 return obj->class; 1009 } 1010 1011 bool object_class_is_abstract(ObjectClass *klass) 1012 { 1013 return klass->type->abstract; 1014 } 1015 1016 const char *object_class_get_name(ObjectClass *klass) 1017 { 1018 return klass->type->name; 1019 } 1020 1021 ObjectClass *object_class_by_name(const char *typename) 1022 { 1023 TypeImpl *type = type_get_by_name(typename); 1024 1025 if (!type) { 1026 return NULL; 1027 } 1028 1029 type_initialize(type); 1030 1031 return type->class; 1032 } 1033 1034 ObjectClass *module_object_class_by_name(const char *typename) 1035 { 1036 ObjectClass *oc; 1037 1038 oc = object_class_by_name(typename); 1039 #ifdef CONFIG_MODULES 1040 if (!oc) { 1041 Error *local_err = NULL; 1042 int rv = module_load_qom(typename, &local_err); 1043 if (rv > 0) { 1044 oc = object_class_by_name(typename); 1045 } else if (rv < 0) { 1046 error_report_err(local_err); 1047 } 1048 } 1049 #endif 1050 return oc; 1051 } 1052 1053 ObjectClass *object_class_get_parent(ObjectClass *class) 1054 { 1055 TypeImpl *type = type_get_parent(class->type); 1056 1057 if (!type) { 1058 return NULL; 1059 } 1060 1061 type_initialize(type); 1062 1063 return type->class; 1064 } 1065 1066 typedef struct OCFData 1067 { 1068 void (*fn)(ObjectClass *klass, void *opaque); 1069 const char *implements_type; 1070 bool include_abstract; 1071 void *opaque; 1072 } OCFData; 1073 1074 static void object_class_foreach_tramp(gpointer key, gpointer value, 1075 gpointer opaque) 1076 { 1077 OCFData *data = opaque; 1078 TypeImpl *type = value; 1079 ObjectClass *k; 1080 1081 type_initialize(type); 1082 k = type->class; 1083 1084 if (!data->include_abstract && type->abstract) { 1085 return; 1086 } 1087 1088 if (data->implements_type && 1089 !object_class_dynamic_cast(k, data->implements_type)) { 1090 return; 1091 } 1092 1093 data->fn(k, data->opaque); 1094 } 1095 1096 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), 1097 const char *implements_type, bool include_abstract, 1098 void *opaque) 1099 { 1100 OCFData data = { fn, implements_type, include_abstract, opaque }; 1101 1102 enumerating_types = true; 1103 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); 1104 enumerating_types = false; 1105 } 1106 1107 static int do_object_child_foreach(Object *obj, 1108 int (*fn)(Object *child, void *opaque), 1109 void *opaque, bool recurse) 1110 { 1111 GHashTableIter iter; 1112 ObjectProperty *prop; 1113 int ret = 0; 1114 1115 g_hash_table_iter_init(&iter, obj->properties); 1116 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) { 1117 if (object_property_is_child(prop)) { 1118 Object *child = prop->opaque; 1119 1120 ret = fn(child, opaque); 1121 if (ret != 0) { 1122 break; 1123 } 1124 if (recurse) { 1125 ret = do_object_child_foreach(child, fn, opaque, true); 1126 if (ret != 0) { 1127 break; 1128 } 1129 } 1130 } 1131 } 1132 return ret; 1133 } 1134 1135 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), 1136 void *opaque) 1137 { 1138 return do_object_child_foreach(obj, fn, opaque, false); 1139 } 1140 1141 int object_child_foreach_recursive(Object *obj, 1142 int (*fn)(Object *child, void *opaque), 1143 void *opaque) 1144 { 1145 return do_object_child_foreach(obj, fn, opaque, true); 1146 } 1147 1148 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque) 1149 { 1150 GSList **list = opaque; 1151 1152 *list = g_slist_prepend(*list, klass); 1153 } 1154 1155 GSList *object_class_get_list(const char *implements_type, 1156 bool include_abstract) 1157 { 1158 GSList *list = NULL; 1159 1160 object_class_foreach(object_class_get_list_tramp, 1161 implements_type, include_abstract, &list); 1162 return list; 1163 } 1164 1165 static gint object_class_cmp(gconstpointer a, gconstpointer b) 1166 { 1167 return strcasecmp(object_class_get_name((ObjectClass *)a), 1168 object_class_get_name((ObjectClass *)b)); 1169 } 1170 1171 GSList *object_class_get_list_sorted(const char *implements_type, 1172 bool include_abstract) 1173 { 1174 return g_slist_sort(object_class_get_list(implements_type, include_abstract), 1175 object_class_cmp); 1176 } 1177 1178 Object *object_ref(void *objptr) 1179 { 1180 Object *obj = OBJECT(objptr); 1181 uint32_t ref; 1182 1183 if (!obj) { 1184 return NULL; 1185 } 1186 ref = qatomic_fetch_inc(&obj->ref); 1187 /* Assert waaay before the integer overflows */ 1188 g_assert(ref < INT_MAX); 1189 return obj; 1190 } 1191 1192 void object_unref(void *objptr) 1193 { 1194 Object *obj = OBJECT(objptr); 1195 if (!obj) { 1196 return; 1197 } 1198 g_assert(obj->ref > 0); 1199 1200 /* parent always holds a reference to its children */ 1201 if (qatomic_fetch_dec(&obj->ref) == 1) { 1202 object_finalize(obj); 1203 } 1204 } 1205 1206 ObjectProperty * 1207 object_property_try_add(Object *obj, const char *name, const char *type, 1208 ObjectPropertyAccessor *get, 1209 ObjectPropertyAccessor *set, 1210 ObjectPropertyRelease *release, 1211 void *opaque, Error **errp) 1212 { 1213 ObjectProperty *prop; 1214 size_t name_len = strlen(name); 1215 1216 if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) { 1217 int i; 1218 ObjectProperty *ret = NULL; 1219 char *name_no_array = g_strdup(name); 1220 1221 name_no_array[name_len - 3] = '\0'; 1222 for (i = 0; i < INT16_MAX; ++i) { 1223 char *full_name = g_strdup_printf("%s[%d]", name_no_array, i); 1224 1225 ret = object_property_try_add(obj, full_name, type, get, set, 1226 release, opaque, NULL); 1227 g_free(full_name); 1228 if (ret) { 1229 break; 1230 } 1231 } 1232 g_free(name_no_array); 1233 assert(ret); 1234 return ret; 1235 } 1236 1237 if (object_property_find(obj, name) != NULL) { 1238 error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')", 1239 name, object_get_typename(obj)); 1240 return NULL; 1241 } 1242 1243 prop = g_malloc0(sizeof(*prop)); 1244 1245 prop->name = g_strdup(name); 1246 prop->type = g_strdup(type); 1247 1248 prop->get = get; 1249 prop->set = set; 1250 prop->release = release; 1251 prop->opaque = opaque; 1252 1253 g_hash_table_insert(obj->properties, prop->name, prop); 1254 return prop; 1255 } 1256 1257 ObjectProperty * 1258 object_property_add(Object *obj, const char *name, const char *type, 1259 ObjectPropertyAccessor *get, 1260 ObjectPropertyAccessor *set, 1261 ObjectPropertyRelease *release, 1262 void *opaque) 1263 { 1264 return object_property_try_add(obj, name, type, get, set, release, 1265 opaque, &error_abort); 1266 } 1267 1268 ObjectProperty * 1269 object_class_property_add(ObjectClass *klass, 1270 const char *name, 1271 const char *type, 1272 ObjectPropertyAccessor *get, 1273 ObjectPropertyAccessor *set, 1274 ObjectPropertyRelease *release, 1275 void *opaque) 1276 { 1277 ObjectProperty *prop; 1278 1279 assert(!object_class_property_find(klass, name)); 1280 1281 prop = g_malloc0(sizeof(*prop)); 1282 1283 prop->name = g_strdup(name); 1284 prop->type = g_strdup(type); 1285 1286 prop->get = get; 1287 prop->set = set; 1288 prop->release = release; 1289 prop->opaque = opaque; 1290 1291 g_hash_table_insert(klass->properties, prop->name, prop); 1292 1293 return prop; 1294 } 1295 1296 ObjectProperty *object_property_find(Object *obj, const char *name) 1297 { 1298 ObjectProperty *prop; 1299 ObjectClass *klass = object_get_class(obj); 1300 1301 prop = object_class_property_find(klass, name); 1302 if (prop) { 1303 return prop; 1304 } 1305 1306 return g_hash_table_lookup(obj->properties, name); 1307 } 1308 1309 ObjectProperty *object_property_find_err(Object *obj, const char *name, 1310 Error **errp) 1311 { 1312 ObjectProperty *prop = object_property_find(obj, name); 1313 if (!prop) { 1314 error_setg(errp, "Property '%s.%s' not found", 1315 object_get_typename(obj), name); 1316 } 1317 return prop; 1318 } 1319 1320 void object_property_iter_init(ObjectPropertyIterator *iter, 1321 Object *obj) 1322 { 1323 g_hash_table_iter_init(&iter->iter, obj->properties); 1324 iter->nextclass = object_get_class(obj); 1325 } 1326 1327 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter) 1328 { 1329 gpointer key, val; 1330 while (!g_hash_table_iter_next(&iter->iter, &key, &val)) { 1331 if (!iter->nextclass) { 1332 return NULL; 1333 } 1334 g_hash_table_iter_init(&iter->iter, iter->nextclass->properties); 1335 iter->nextclass = object_class_get_parent(iter->nextclass); 1336 } 1337 return val; 1338 } 1339 1340 void object_class_property_iter_init(ObjectPropertyIterator *iter, 1341 ObjectClass *klass) 1342 { 1343 g_hash_table_iter_init(&iter->iter, klass->properties); 1344 iter->nextclass = object_class_get_parent(klass); 1345 } 1346 1347 ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name) 1348 { 1349 ObjectClass *parent_klass; 1350 1351 parent_klass = object_class_get_parent(klass); 1352 if (parent_klass) { 1353 ObjectProperty *prop = 1354 object_class_property_find(parent_klass, name); 1355 if (prop) { 1356 return prop; 1357 } 1358 } 1359 1360 return g_hash_table_lookup(klass->properties, name); 1361 } 1362 1363 ObjectProperty *object_class_property_find_err(ObjectClass *klass, 1364 const char *name, 1365 Error **errp) 1366 { 1367 ObjectProperty *prop = object_class_property_find(klass, name); 1368 if (!prop) { 1369 error_setg(errp, "Property '.%s' not found", name); 1370 } 1371 return prop; 1372 } 1373 1374 1375 void object_property_del(Object *obj, const char *name) 1376 { 1377 ObjectProperty *prop = g_hash_table_lookup(obj->properties, name); 1378 1379 if (prop->release) { 1380 prop->release(obj, name, prop->opaque); 1381 } 1382 g_hash_table_remove(obj->properties, name); 1383 } 1384 1385 bool object_property_get(Object *obj, const char *name, Visitor *v, 1386 Error **errp) 1387 { 1388 Error *err = NULL; 1389 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1390 1391 if (prop == NULL) { 1392 return false; 1393 } 1394 1395 if (!prop->get) { 1396 error_setg(errp, "Property '%s.%s' is not readable", 1397 object_get_typename(obj), name); 1398 return false; 1399 } 1400 prop->get(obj, v, name, prop->opaque, &err); 1401 error_propagate(errp, err); 1402 return !err; 1403 } 1404 1405 bool object_property_set(Object *obj, const char *name, Visitor *v, 1406 Error **errp) 1407 { 1408 ERRP_GUARD(); 1409 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1410 1411 if (prop == NULL) { 1412 return false; 1413 } 1414 1415 if (!prop->set) { 1416 error_setg(errp, "Property '%s.%s' is not writable", 1417 object_get_typename(obj), name); 1418 return false; 1419 } 1420 prop->set(obj, v, name, prop->opaque, errp); 1421 return !*errp; 1422 } 1423 1424 bool object_property_set_str(Object *obj, const char *name, 1425 const char *value, Error **errp) 1426 { 1427 QString *qstr = qstring_from_str(value); 1428 bool ok = object_property_set_qobject(obj, name, QOBJECT(qstr), errp); 1429 1430 qobject_unref(qstr); 1431 return ok; 1432 } 1433 1434 char *object_property_get_str(Object *obj, const char *name, 1435 Error **errp) 1436 { 1437 QObject *ret = object_property_get_qobject(obj, name, errp); 1438 QString *qstring; 1439 char *retval; 1440 1441 if (!ret) { 1442 return NULL; 1443 } 1444 qstring = qobject_to(QString, ret); 1445 if (!qstring) { 1446 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 1447 retval = NULL; 1448 } else { 1449 retval = g_strdup(qstring_get_str(qstring)); 1450 } 1451 1452 qobject_unref(ret); 1453 return retval; 1454 } 1455 1456 bool object_property_set_link(Object *obj, const char *name, 1457 Object *value, Error **errp) 1458 { 1459 g_autofree char *path = NULL; 1460 1461 if (value) { 1462 path = object_get_canonical_path(value); 1463 } 1464 return object_property_set_str(obj, name, path ?: "", errp); 1465 } 1466 1467 Object *object_property_get_link(Object *obj, const char *name, 1468 Error **errp) 1469 { 1470 char *str = object_property_get_str(obj, name, errp); 1471 Object *target = NULL; 1472 1473 if (str && *str) { 1474 target = object_resolve_path(str, NULL); 1475 if (!target) { 1476 error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, 1477 "Device '%s' not found", str); 1478 } 1479 } 1480 1481 g_free(str); 1482 return target; 1483 } 1484 1485 bool object_property_set_bool(Object *obj, const char *name, 1486 bool value, Error **errp) 1487 { 1488 QBool *qbool = qbool_from_bool(value); 1489 bool ok = object_property_set_qobject(obj, name, QOBJECT(qbool), errp); 1490 1491 qobject_unref(qbool); 1492 return ok; 1493 } 1494 1495 bool object_property_get_bool(Object *obj, const char *name, 1496 Error **errp) 1497 { 1498 QObject *ret = object_property_get_qobject(obj, name, errp); 1499 QBool *qbool; 1500 bool retval; 1501 1502 if (!ret) { 1503 return false; 1504 } 1505 qbool = qobject_to(QBool, ret); 1506 if (!qbool) { 1507 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 1508 retval = false; 1509 } else { 1510 retval = qbool_get_bool(qbool); 1511 } 1512 1513 qobject_unref(ret); 1514 return retval; 1515 } 1516 1517 bool object_property_set_int(Object *obj, const char *name, 1518 int64_t value, Error **errp) 1519 { 1520 QNum *qnum = qnum_from_int(value); 1521 bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp); 1522 1523 qobject_unref(qnum); 1524 return ok; 1525 } 1526 1527 int64_t object_property_get_int(Object *obj, const char *name, 1528 Error **errp) 1529 { 1530 QObject *ret = object_property_get_qobject(obj, name, errp); 1531 QNum *qnum; 1532 int64_t retval; 1533 1534 if (!ret) { 1535 return -1; 1536 } 1537 1538 qnum = qobject_to(QNum, ret); 1539 if (!qnum || !qnum_get_try_int(qnum, &retval)) { 1540 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 1541 retval = -1; 1542 } 1543 1544 qobject_unref(ret); 1545 return retval; 1546 } 1547 1548 static void object_property_init_defval(Object *obj, ObjectProperty *prop) 1549 { 1550 Visitor *v = qobject_input_visitor_new(prop->defval); 1551 1552 assert(prop->set != NULL); 1553 prop->set(obj, v, prop->name, prop->opaque, &error_abort); 1554 1555 visit_free(v); 1556 } 1557 1558 static void object_property_set_default(ObjectProperty *prop, QObject *defval) 1559 { 1560 assert(!prop->defval); 1561 assert(!prop->init); 1562 1563 prop->defval = defval; 1564 prop->init = object_property_init_defval; 1565 } 1566 1567 void object_property_set_default_bool(ObjectProperty *prop, bool value) 1568 { 1569 object_property_set_default(prop, QOBJECT(qbool_from_bool(value))); 1570 } 1571 1572 void object_property_set_default_str(ObjectProperty *prop, const char *value) 1573 { 1574 object_property_set_default(prop, QOBJECT(qstring_from_str(value))); 1575 } 1576 1577 void object_property_set_default_int(ObjectProperty *prop, int64_t value) 1578 { 1579 object_property_set_default(prop, QOBJECT(qnum_from_int(value))); 1580 } 1581 1582 void object_property_set_default_uint(ObjectProperty *prop, uint64_t value) 1583 { 1584 object_property_set_default(prop, QOBJECT(qnum_from_uint(value))); 1585 } 1586 1587 bool object_property_set_uint(Object *obj, const char *name, 1588 uint64_t value, Error **errp) 1589 { 1590 QNum *qnum = qnum_from_uint(value); 1591 bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp); 1592 1593 qobject_unref(qnum); 1594 return ok; 1595 } 1596 1597 uint64_t object_property_get_uint(Object *obj, const char *name, 1598 Error **errp) 1599 { 1600 QObject *ret = object_property_get_qobject(obj, name, errp); 1601 QNum *qnum; 1602 uint64_t retval; 1603 1604 if (!ret) { 1605 return 0; 1606 } 1607 qnum = qobject_to(QNum, ret); 1608 if (!qnum || !qnum_get_try_uint(qnum, &retval)) { 1609 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint"); 1610 retval = 0; 1611 } 1612 1613 qobject_unref(ret); 1614 return retval; 1615 } 1616 1617 typedef struct EnumProperty { 1618 const QEnumLookup *lookup; 1619 int (*get)(Object *, Error **); 1620 void (*set)(Object *, int, Error **); 1621 } EnumProperty; 1622 1623 int object_property_get_enum(Object *obj, const char *name, 1624 const char *typename, Error **errp) 1625 { 1626 char *str; 1627 int ret; 1628 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1629 EnumProperty *enumprop; 1630 1631 if (prop == NULL) { 1632 return -1; 1633 } 1634 1635 if (!g_str_equal(prop->type, typename)) { 1636 error_setg(errp, "Property %s on %s is not '%s' enum type", 1637 name, object_class_get_name( 1638 object_get_class(obj)), typename); 1639 return -1; 1640 } 1641 1642 enumprop = prop->opaque; 1643 1644 str = object_property_get_str(obj, name, errp); 1645 if (!str) { 1646 return -1; 1647 } 1648 1649 ret = qapi_enum_parse(enumprop->lookup, str, -1, errp); 1650 g_free(str); 1651 1652 return ret; 1653 } 1654 1655 bool object_property_parse(Object *obj, const char *name, 1656 const char *string, Error **errp) 1657 { 1658 Visitor *v = string_input_visitor_new(string); 1659 bool ok = object_property_set(obj, name, v, errp); 1660 1661 visit_free(v); 1662 return ok; 1663 } 1664 1665 char *object_property_print(Object *obj, const char *name, bool human, 1666 Error **errp) 1667 { 1668 Visitor *v; 1669 char *string = NULL; 1670 1671 v = string_output_visitor_new(human, &string); 1672 if (!object_property_get(obj, name, v, errp)) { 1673 goto out; 1674 } 1675 1676 visit_complete(v, &string); 1677 1678 out: 1679 visit_free(v); 1680 return string; 1681 } 1682 1683 const char *object_property_get_type(Object *obj, const char *name, Error **errp) 1684 { 1685 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1686 if (prop == NULL) { 1687 return NULL; 1688 } 1689 1690 return prop->type; 1691 } 1692 1693 Object *object_get_root(void) 1694 { 1695 static Object *root; 1696 1697 if (!root) { 1698 root = object_new("container"); 1699 } 1700 1701 return root; 1702 } 1703 1704 Object *object_get_objects_root(void) 1705 { 1706 return container_get(object_get_root(), "/objects"); 1707 } 1708 1709 Object *object_get_internal_root(void) 1710 { 1711 static Object *internal_root; 1712 1713 if (!internal_root) { 1714 internal_root = object_new("container"); 1715 } 1716 1717 return internal_root; 1718 } 1719 1720 static void object_get_child_property(Object *obj, Visitor *v, 1721 const char *name, void *opaque, 1722 Error **errp) 1723 { 1724 Object *child = opaque; 1725 char *path; 1726 1727 path = object_get_canonical_path(child); 1728 visit_type_str(v, name, &path, errp); 1729 g_free(path); 1730 } 1731 1732 static Object *object_resolve_child_property(Object *parent, void *opaque, 1733 const char *part) 1734 { 1735 return opaque; 1736 } 1737 1738 static void object_finalize_child_property(Object *obj, const char *name, 1739 void *opaque) 1740 { 1741 Object *child = opaque; 1742 1743 if (child->class->unparent) { 1744 (child->class->unparent)(child); 1745 } 1746 child->parent = NULL; 1747 object_unref(child); 1748 } 1749 1750 ObjectProperty * 1751 object_property_try_add_child(Object *obj, const char *name, 1752 Object *child, Error **errp) 1753 { 1754 g_autofree char *type = NULL; 1755 ObjectProperty *op; 1756 1757 assert(!child->parent); 1758 1759 type = g_strdup_printf("child<%s>", object_get_typename(child)); 1760 1761 op = object_property_try_add(obj, name, type, object_get_child_property, 1762 NULL, object_finalize_child_property, 1763 child, errp); 1764 if (!op) { 1765 return NULL; 1766 } 1767 op->resolve = object_resolve_child_property; 1768 object_ref(child); 1769 child->parent = obj; 1770 return op; 1771 } 1772 1773 ObjectProperty * 1774 object_property_add_child(Object *obj, const char *name, 1775 Object *child) 1776 { 1777 return object_property_try_add_child(obj, name, child, &error_abort); 1778 } 1779 1780 void object_property_allow_set_link(const Object *obj, const char *name, 1781 Object *val, Error **errp) 1782 { 1783 /* Allow the link to be set, always */ 1784 } 1785 1786 typedef struct { 1787 union { 1788 Object **targetp; 1789 Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer */ 1790 ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */ 1791 }; 1792 void (*check)(const Object *, const char *, Object *, Error **); 1793 ObjectPropertyLinkFlags flags; 1794 } LinkProperty; 1795 1796 static Object ** 1797 object_link_get_targetp(Object *obj, LinkProperty *lprop) 1798 { 1799 if (lprop->flags & OBJ_PROP_LINK_DIRECT) { 1800 return &lprop->target; 1801 } else if (lprop->flags & OBJ_PROP_LINK_CLASS) { 1802 return (void *)obj + lprop->offset; 1803 } else { 1804 return lprop->targetp; 1805 } 1806 } 1807 1808 static void object_get_link_property(Object *obj, Visitor *v, 1809 const char *name, void *opaque, 1810 Error **errp) 1811 { 1812 LinkProperty *lprop = opaque; 1813 Object **targetp = object_link_get_targetp(obj, lprop); 1814 char *path; 1815 1816 if (*targetp) { 1817 path = object_get_canonical_path(*targetp); 1818 visit_type_str(v, name, &path, errp); 1819 g_free(path); 1820 } else { 1821 path = (char *)""; 1822 visit_type_str(v, name, &path, errp); 1823 } 1824 } 1825 1826 /* 1827 * object_resolve_link: 1828 * 1829 * Lookup an object and ensure its type matches the link property type. This 1830 * is similar to object_resolve_path() except type verification against the 1831 * link property is performed. 1832 * 1833 * Returns: The matched object or NULL on path lookup failures. 1834 */ 1835 static Object *object_resolve_link(Object *obj, const char *name, 1836 const char *path, Error **errp) 1837 { 1838 const char *type; 1839 char *target_type; 1840 bool ambiguous = false; 1841 Object *target; 1842 1843 /* Go from link<FOO> to FOO. */ 1844 type = object_property_get_type(obj, name, NULL); 1845 target_type = g_strndup(&type[5], strlen(type) - 6); 1846 target = object_resolve_path_type(path, target_type, &ambiguous); 1847 1848 if (ambiguous) { 1849 error_setg(errp, "Path '%s' does not uniquely identify an object", 1850 path); 1851 } else if (!target) { 1852 target = object_resolve_path(path, &ambiguous); 1853 if (target || ambiguous) { 1854 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 1855 } else { 1856 error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, 1857 "Device '%s' not found", path); 1858 } 1859 target = NULL; 1860 } 1861 g_free(target_type); 1862 1863 return target; 1864 } 1865 1866 static void object_set_link_property(Object *obj, Visitor *v, 1867 const char *name, void *opaque, 1868 Error **errp) 1869 { 1870 Error *local_err = NULL; 1871 LinkProperty *prop = opaque; 1872 Object **targetp = object_link_get_targetp(obj, prop); 1873 Object *old_target = *targetp; 1874 Object *new_target; 1875 char *path = NULL; 1876 1877 if (!visit_type_str(v, name, &path, errp)) { 1878 return; 1879 } 1880 1881 if (*path) { 1882 new_target = object_resolve_link(obj, name, path, errp); 1883 if (!new_target) { 1884 g_free(path); 1885 return; 1886 } 1887 } else { 1888 new_target = NULL; 1889 } 1890 1891 g_free(path); 1892 1893 prop->check(obj, name, new_target, &local_err); 1894 if (local_err) { 1895 error_propagate(errp, local_err); 1896 return; 1897 } 1898 1899 *targetp = new_target; 1900 if (prop->flags & OBJ_PROP_LINK_STRONG) { 1901 object_ref(new_target); 1902 object_unref(old_target); 1903 } 1904 } 1905 1906 static Object *object_resolve_link_property(Object *parent, void *opaque, 1907 const char *part) 1908 { 1909 LinkProperty *lprop = opaque; 1910 1911 return *object_link_get_targetp(parent, lprop); 1912 } 1913 1914 static void object_release_link_property(Object *obj, const char *name, 1915 void *opaque) 1916 { 1917 LinkProperty *prop = opaque; 1918 Object **targetp = object_link_get_targetp(obj, prop); 1919 1920 if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) { 1921 object_unref(*targetp); 1922 } 1923 if (!(prop->flags & OBJ_PROP_LINK_CLASS)) { 1924 g_free(prop); 1925 } 1926 } 1927 1928 static ObjectProperty * 1929 object_add_link_prop(Object *obj, const char *name, 1930 const char *type, void *ptr, 1931 void (*check)(const Object *, const char *, 1932 Object *, Error **), 1933 ObjectPropertyLinkFlags flags) 1934 { 1935 LinkProperty *prop = g_malloc(sizeof(*prop)); 1936 g_autofree char *full_type = NULL; 1937 ObjectProperty *op; 1938 1939 if (flags & OBJ_PROP_LINK_DIRECT) { 1940 prop->target = ptr; 1941 } else { 1942 prop->targetp = ptr; 1943 } 1944 prop->check = check; 1945 prop->flags = flags; 1946 1947 full_type = g_strdup_printf("link<%s>", type); 1948 1949 op = object_property_add(obj, name, full_type, 1950 object_get_link_property, 1951 check ? object_set_link_property : NULL, 1952 object_release_link_property, 1953 prop); 1954 op->resolve = object_resolve_link_property; 1955 return op; 1956 } 1957 1958 ObjectProperty * 1959 object_property_add_link(Object *obj, const char *name, 1960 const char *type, Object **targetp, 1961 void (*check)(const Object *, const char *, 1962 Object *, Error **), 1963 ObjectPropertyLinkFlags flags) 1964 { 1965 return object_add_link_prop(obj, name, type, targetp, check, flags); 1966 } 1967 1968 ObjectProperty * 1969 object_class_property_add_link(ObjectClass *oc, 1970 const char *name, 1971 const char *type, ptrdiff_t offset, 1972 void (*check)(const Object *obj, const char *name, 1973 Object *val, Error **errp), 1974 ObjectPropertyLinkFlags flags) 1975 { 1976 LinkProperty *prop = g_new0(LinkProperty, 1); 1977 char *full_type; 1978 ObjectProperty *op; 1979 1980 prop->offset = offset; 1981 prop->check = check; 1982 prop->flags = flags | OBJ_PROP_LINK_CLASS; 1983 1984 full_type = g_strdup_printf("link<%s>", type); 1985 1986 op = object_class_property_add(oc, name, full_type, 1987 object_get_link_property, 1988 check ? object_set_link_property : NULL, 1989 object_release_link_property, 1990 prop); 1991 1992 op->resolve = object_resolve_link_property; 1993 1994 g_free(full_type); 1995 return op; 1996 } 1997 1998 ObjectProperty * 1999 object_property_add_const_link(Object *obj, const char *name, 2000 Object *target) 2001 { 2002 return object_add_link_prop(obj, name, 2003 object_get_typename(target), target, 2004 NULL, OBJ_PROP_LINK_DIRECT); 2005 } 2006 2007 const char *object_get_canonical_path_component(const Object *obj) 2008 { 2009 ObjectProperty *prop = NULL; 2010 GHashTableIter iter; 2011 2012 if (obj->parent == NULL) { 2013 return NULL; 2014 } 2015 2016 g_hash_table_iter_init(&iter, obj->parent->properties); 2017 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) { 2018 if (!object_property_is_child(prop)) { 2019 continue; 2020 } 2021 2022 if (prop->opaque == obj) { 2023 return prop->name; 2024 } 2025 } 2026 2027 /* obj had a parent but was not a child, should never happen */ 2028 g_assert_not_reached(); 2029 return NULL; 2030 } 2031 2032 char *object_get_canonical_path(const Object *obj) 2033 { 2034 Object *root = object_get_root(); 2035 char *newpath, *path = NULL; 2036 2037 if (obj == root) { 2038 return g_strdup("/"); 2039 } 2040 2041 do { 2042 const char *component = object_get_canonical_path_component(obj); 2043 2044 if (!component) { 2045 /* A canonical path must be complete, so discard what was 2046 * collected so far. 2047 */ 2048 g_free(path); 2049 return NULL; 2050 } 2051 2052 newpath = g_strdup_printf("/%s%s", component, path ? path : ""); 2053 g_free(path); 2054 path = newpath; 2055 obj = obj->parent; 2056 } while (obj != root); 2057 2058 return path; 2059 } 2060 2061 Object *object_resolve_path_component(Object *parent, const char *part) 2062 { 2063 ObjectProperty *prop = object_property_find(parent, part); 2064 if (prop == NULL) { 2065 return NULL; 2066 } 2067 2068 if (prop->resolve) { 2069 return prop->resolve(parent, prop->opaque, part); 2070 } else { 2071 return NULL; 2072 } 2073 } 2074 2075 static Object *object_resolve_abs_path(Object *parent, 2076 char **parts, 2077 const char *typename) 2078 { 2079 Object *child; 2080 2081 if (*parts == NULL) { 2082 return object_dynamic_cast(parent, typename); 2083 } 2084 2085 if (strcmp(*parts, "") == 0) { 2086 return object_resolve_abs_path(parent, parts + 1, typename); 2087 } 2088 2089 child = object_resolve_path_component(parent, *parts); 2090 if (!child) { 2091 return NULL; 2092 } 2093 2094 return object_resolve_abs_path(child, parts + 1, typename); 2095 } 2096 2097 static Object *object_resolve_partial_path(Object *parent, 2098 char **parts, 2099 const char *typename, 2100 bool *ambiguous) 2101 { 2102 Object *obj; 2103 GHashTableIter iter; 2104 ObjectProperty *prop; 2105 2106 obj = object_resolve_abs_path(parent, parts, typename); 2107 2108 g_hash_table_iter_init(&iter, parent->properties); 2109 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) { 2110 Object *found; 2111 2112 if (!object_property_is_child(prop)) { 2113 continue; 2114 } 2115 2116 found = object_resolve_partial_path(prop->opaque, parts, 2117 typename, ambiguous); 2118 if (found) { 2119 if (obj) { 2120 *ambiguous = true; 2121 return NULL; 2122 } 2123 obj = found; 2124 } 2125 2126 if (*ambiguous) { 2127 return NULL; 2128 } 2129 } 2130 2131 return obj; 2132 } 2133 2134 Object *object_resolve_path_type(const char *path, const char *typename, 2135 bool *ambiguousp) 2136 { 2137 Object *obj; 2138 char **parts; 2139 2140 parts = g_strsplit(path, "/", 0); 2141 assert(parts); 2142 2143 if (parts[0] == NULL || strcmp(parts[0], "") != 0) { 2144 bool ambiguous = false; 2145 obj = object_resolve_partial_path(object_get_root(), parts, 2146 typename, &ambiguous); 2147 if (ambiguousp) { 2148 *ambiguousp = ambiguous; 2149 } 2150 } else { 2151 obj = object_resolve_abs_path(object_get_root(), parts + 1, typename); 2152 } 2153 2154 g_strfreev(parts); 2155 2156 return obj; 2157 } 2158 2159 Object *object_resolve_path(const char *path, bool *ambiguous) 2160 { 2161 return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 2162 } 2163 2164 Object *object_resolve_path_at(Object *parent, const char *path) 2165 { 2166 g_auto(GStrv) parts = g_strsplit(path, "/", 0); 2167 2168 if (*path == '/') { 2169 return object_resolve_abs_path(object_get_root(), parts + 1, 2170 TYPE_OBJECT); 2171 } 2172 return object_resolve_abs_path(parent, parts, TYPE_OBJECT); 2173 } 2174 2175 typedef struct StringProperty 2176 { 2177 char *(*get)(Object *, Error **); 2178 void (*set)(Object *, const char *, Error **); 2179 } StringProperty; 2180 2181 static void property_get_str(Object *obj, Visitor *v, const char *name, 2182 void *opaque, Error **errp) 2183 { 2184 StringProperty *prop = opaque; 2185 char *value; 2186 Error *err = NULL; 2187 2188 value = prop->get(obj, &err); 2189 if (err) { 2190 error_propagate(errp, err); 2191 return; 2192 } 2193 2194 visit_type_str(v, name, &value, errp); 2195 g_free(value); 2196 } 2197 2198 static void property_set_str(Object *obj, Visitor *v, const char *name, 2199 void *opaque, Error **errp) 2200 { 2201 StringProperty *prop = opaque; 2202 char *value; 2203 2204 if (!visit_type_str(v, name, &value, errp)) { 2205 return; 2206 } 2207 2208 prop->set(obj, value, errp); 2209 g_free(value); 2210 } 2211 2212 static void property_release_data(Object *obj, const char *name, 2213 void *opaque) 2214 { 2215 g_free(opaque); 2216 } 2217 2218 ObjectProperty * 2219 object_property_add_str(Object *obj, const char *name, 2220 char *(*get)(Object *, Error **), 2221 void (*set)(Object *, const char *, Error **)) 2222 { 2223 StringProperty *prop = g_malloc0(sizeof(*prop)); 2224 2225 prop->get = get; 2226 prop->set = set; 2227 2228 return object_property_add(obj, name, "string", 2229 get ? property_get_str : NULL, 2230 set ? property_set_str : NULL, 2231 property_release_data, 2232 prop); 2233 } 2234 2235 ObjectProperty * 2236 object_class_property_add_str(ObjectClass *klass, const char *name, 2237 char *(*get)(Object *, Error **), 2238 void (*set)(Object *, const char *, 2239 Error **)) 2240 { 2241 StringProperty *prop = g_malloc0(sizeof(*prop)); 2242 2243 prop->get = get; 2244 prop->set = set; 2245 2246 return object_class_property_add(klass, name, "string", 2247 get ? property_get_str : NULL, 2248 set ? property_set_str : NULL, 2249 NULL, 2250 prop); 2251 } 2252 2253 typedef struct BoolProperty 2254 { 2255 bool (*get)(Object *, Error **); 2256 void (*set)(Object *, bool, Error **); 2257 } BoolProperty; 2258 2259 static void property_get_bool(Object *obj, Visitor *v, const char *name, 2260 void *opaque, Error **errp) 2261 { 2262 BoolProperty *prop = opaque; 2263 bool value; 2264 Error *err = NULL; 2265 2266 value = prop->get(obj, &err); 2267 if (err) { 2268 error_propagate(errp, err); 2269 return; 2270 } 2271 2272 visit_type_bool(v, name, &value, errp); 2273 } 2274 2275 static void property_set_bool(Object *obj, Visitor *v, const char *name, 2276 void *opaque, Error **errp) 2277 { 2278 BoolProperty *prop = opaque; 2279 bool value; 2280 2281 if (!visit_type_bool(v, name, &value, errp)) { 2282 return; 2283 } 2284 2285 prop->set(obj, value, errp); 2286 } 2287 2288 ObjectProperty * 2289 object_property_add_bool(Object *obj, const char *name, 2290 bool (*get)(Object *, Error **), 2291 void (*set)(Object *, bool, Error **)) 2292 { 2293 BoolProperty *prop = g_malloc0(sizeof(*prop)); 2294 2295 prop->get = get; 2296 prop->set = set; 2297 2298 return object_property_add(obj, name, "bool", 2299 get ? property_get_bool : NULL, 2300 set ? property_set_bool : NULL, 2301 property_release_data, 2302 prop); 2303 } 2304 2305 ObjectProperty * 2306 object_class_property_add_bool(ObjectClass *klass, const char *name, 2307 bool (*get)(Object *, Error **), 2308 void (*set)(Object *, bool, Error **)) 2309 { 2310 BoolProperty *prop = g_malloc0(sizeof(*prop)); 2311 2312 prop->get = get; 2313 prop->set = set; 2314 2315 return object_class_property_add(klass, name, "bool", 2316 get ? property_get_bool : NULL, 2317 set ? property_set_bool : NULL, 2318 NULL, 2319 prop); 2320 } 2321 2322 static void property_get_enum(Object *obj, Visitor *v, const char *name, 2323 void *opaque, Error **errp) 2324 { 2325 EnumProperty *prop = opaque; 2326 int value; 2327 Error *err = NULL; 2328 2329 value = prop->get(obj, &err); 2330 if (err) { 2331 error_propagate(errp, err); 2332 return; 2333 } 2334 2335 visit_type_enum(v, name, &value, prop->lookup, errp); 2336 } 2337 2338 static void property_set_enum(Object *obj, Visitor *v, const char *name, 2339 void *opaque, Error **errp) 2340 { 2341 EnumProperty *prop = opaque; 2342 int value; 2343 2344 if (!visit_type_enum(v, name, &value, prop->lookup, errp)) { 2345 return; 2346 } 2347 prop->set(obj, value, errp); 2348 } 2349 2350 ObjectProperty * 2351 object_property_add_enum(Object *obj, const char *name, 2352 const char *typename, 2353 const QEnumLookup *lookup, 2354 int (*get)(Object *, Error **), 2355 void (*set)(Object *, int, Error **)) 2356 { 2357 EnumProperty *prop = g_malloc(sizeof(*prop)); 2358 2359 prop->lookup = lookup; 2360 prop->get = get; 2361 prop->set = set; 2362 2363 return object_property_add(obj, name, typename, 2364 get ? property_get_enum : NULL, 2365 set ? property_set_enum : NULL, 2366 property_release_data, 2367 prop); 2368 } 2369 2370 ObjectProperty * 2371 object_class_property_add_enum(ObjectClass *klass, const char *name, 2372 const char *typename, 2373 const QEnumLookup *lookup, 2374 int (*get)(Object *, Error **), 2375 void (*set)(Object *, int, Error **)) 2376 { 2377 EnumProperty *prop = g_malloc(sizeof(*prop)); 2378 2379 prop->lookup = lookup; 2380 prop->get = get; 2381 prop->set = set; 2382 2383 return object_class_property_add(klass, name, typename, 2384 get ? property_get_enum : NULL, 2385 set ? property_set_enum : NULL, 2386 NULL, 2387 prop); 2388 } 2389 2390 typedef struct TMProperty { 2391 void (*get)(Object *, struct tm *, Error **); 2392 } TMProperty; 2393 2394 static void property_get_tm(Object *obj, Visitor *v, const char *name, 2395 void *opaque, Error **errp) 2396 { 2397 TMProperty *prop = opaque; 2398 Error *err = NULL; 2399 struct tm value; 2400 2401 prop->get(obj, &value, &err); 2402 if (err) { 2403 error_propagate(errp, err); 2404 return; 2405 } 2406 2407 if (!visit_start_struct(v, name, NULL, 0, errp)) { 2408 return; 2409 } 2410 if (!visit_type_int32(v, "tm_year", &value.tm_year, errp)) { 2411 goto out_end; 2412 } 2413 if (!visit_type_int32(v, "tm_mon", &value.tm_mon, errp)) { 2414 goto out_end; 2415 } 2416 if (!visit_type_int32(v, "tm_mday", &value.tm_mday, errp)) { 2417 goto out_end; 2418 } 2419 if (!visit_type_int32(v, "tm_hour", &value.tm_hour, errp)) { 2420 goto out_end; 2421 } 2422 if (!visit_type_int32(v, "tm_min", &value.tm_min, errp)) { 2423 goto out_end; 2424 } 2425 if (!visit_type_int32(v, "tm_sec", &value.tm_sec, errp)) { 2426 goto out_end; 2427 } 2428 visit_check_struct(v, errp); 2429 out_end: 2430 visit_end_struct(v, NULL); 2431 } 2432 2433 ObjectProperty * 2434 object_property_add_tm(Object *obj, const char *name, 2435 void (*get)(Object *, struct tm *, Error **)) 2436 { 2437 TMProperty *prop = g_malloc0(sizeof(*prop)); 2438 2439 prop->get = get; 2440 2441 return object_property_add(obj, name, "struct tm", 2442 get ? property_get_tm : NULL, NULL, 2443 property_release_data, 2444 prop); 2445 } 2446 2447 ObjectProperty * 2448 object_class_property_add_tm(ObjectClass *klass, const char *name, 2449 void (*get)(Object *, struct tm *, Error **)) 2450 { 2451 TMProperty *prop = g_malloc0(sizeof(*prop)); 2452 2453 prop->get = get; 2454 2455 return object_class_property_add(klass, name, "struct tm", 2456 get ? property_get_tm : NULL, 2457 NULL, NULL, prop); 2458 } 2459 2460 static char *object_get_type(Object *obj, Error **errp) 2461 { 2462 return g_strdup(object_get_typename(obj)); 2463 } 2464 2465 static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name, 2466 void *opaque, Error **errp) 2467 { 2468 uint8_t value = *(uint8_t *)opaque; 2469 visit_type_uint8(v, name, &value, errp); 2470 } 2471 2472 static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name, 2473 void *opaque, Error **errp) 2474 { 2475 uint8_t *field = opaque; 2476 uint8_t value; 2477 2478 if (!visit_type_uint8(v, name, &value, errp)) { 2479 return; 2480 } 2481 2482 *field = value; 2483 } 2484 2485 static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name, 2486 void *opaque, Error **errp) 2487 { 2488 uint16_t value = *(uint16_t *)opaque; 2489 visit_type_uint16(v, name, &value, errp); 2490 } 2491 2492 static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name, 2493 void *opaque, Error **errp) 2494 { 2495 uint16_t *field = opaque; 2496 uint16_t value; 2497 2498 if (!visit_type_uint16(v, name, &value, errp)) { 2499 return; 2500 } 2501 2502 *field = value; 2503 } 2504 2505 static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name, 2506 void *opaque, Error **errp) 2507 { 2508 uint32_t value = *(uint32_t *)opaque; 2509 visit_type_uint32(v, name, &value, errp); 2510 } 2511 2512 static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name, 2513 void *opaque, Error **errp) 2514 { 2515 uint32_t *field = opaque; 2516 uint32_t value; 2517 2518 if (!visit_type_uint32(v, name, &value, errp)) { 2519 return; 2520 } 2521 2522 *field = value; 2523 } 2524 2525 static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name, 2526 void *opaque, Error **errp) 2527 { 2528 uint64_t value = *(uint64_t *)opaque; 2529 visit_type_uint64(v, name, &value, errp); 2530 } 2531 2532 static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name, 2533 void *opaque, Error **errp) 2534 { 2535 uint64_t *field = opaque; 2536 uint64_t value; 2537 2538 if (!visit_type_uint64(v, name, &value, errp)) { 2539 return; 2540 } 2541 2542 *field = value; 2543 } 2544 2545 ObjectProperty * 2546 object_property_add_uint8_ptr(Object *obj, const char *name, 2547 const uint8_t *v, 2548 ObjectPropertyFlags flags) 2549 { 2550 ObjectPropertyAccessor *getter = NULL; 2551 ObjectPropertyAccessor *setter = NULL; 2552 2553 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2554 getter = property_get_uint8_ptr; 2555 } 2556 2557 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2558 setter = property_set_uint8_ptr; 2559 } 2560 2561 return object_property_add(obj, name, "uint8", 2562 getter, setter, NULL, (void *)v); 2563 } 2564 2565 ObjectProperty * 2566 object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name, 2567 const uint8_t *v, 2568 ObjectPropertyFlags flags) 2569 { 2570 ObjectPropertyAccessor *getter = NULL; 2571 ObjectPropertyAccessor *setter = NULL; 2572 2573 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2574 getter = property_get_uint8_ptr; 2575 } 2576 2577 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2578 setter = property_set_uint8_ptr; 2579 } 2580 2581 return object_class_property_add(klass, name, "uint8", 2582 getter, setter, NULL, (void *)v); 2583 } 2584 2585 ObjectProperty * 2586 object_property_add_uint16_ptr(Object *obj, const char *name, 2587 const uint16_t *v, 2588 ObjectPropertyFlags flags) 2589 { 2590 ObjectPropertyAccessor *getter = NULL; 2591 ObjectPropertyAccessor *setter = NULL; 2592 2593 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2594 getter = property_get_uint16_ptr; 2595 } 2596 2597 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2598 setter = property_set_uint16_ptr; 2599 } 2600 2601 return object_property_add(obj, name, "uint16", 2602 getter, setter, NULL, (void *)v); 2603 } 2604 2605 ObjectProperty * 2606 object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name, 2607 const uint16_t *v, 2608 ObjectPropertyFlags flags) 2609 { 2610 ObjectPropertyAccessor *getter = NULL; 2611 ObjectPropertyAccessor *setter = NULL; 2612 2613 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2614 getter = property_get_uint16_ptr; 2615 } 2616 2617 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2618 setter = property_set_uint16_ptr; 2619 } 2620 2621 return object_class_property_add(klass, name, "uint16", 2622 getter, setter, NULL, (void *)v); 2623 } 2624 2625 ObjectProperty * 2626 object_property_add_uint32_ptr(Object *obj, const char *name, 2627 const uint32_t *v, 2628 ObjectPropertyFlags flags) 2629 { 2630 ObjectPropertyAccessor *getter = NULL; 2631 ObjectPropertyAccessor *setter = NULL; 2632 2633 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2634 getter = property_get_uint32_ptr; 2635 } 2636 2637 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2638 setter = property_set_uint32_ptr; 2639 } 2640 2641 return object_property_add(obj, name, "uint32", 2642 getter, setter, NULL, (void *)v); 2643 } 2644 2645 ObjectProperty * 2646 object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name, 2647 const uint32_t *v, 2648 ObjectPropertyFlags flags) 2649 { 2650 ObjectPropertyAccessor *getter = NULL; 2651 ObjectPropertyAccessor *setter = NULL; 2652 2653 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2654 getter = property_get_uint32_ptr; 2655 } 2656 2657 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2658 setter = property_set_uint32_ptr; 2659 } 2660 2661 return object_class_property_add(klass, name, "uint32", 2662 getter, setter, NULL, (void *)v); 2663 } 2664 2665 ObjectProperty * 2666 object_property_add_uint64_ptr(Object *obj, const char *name, 2667 const uint64_t *v, 2668 ObjectPropertyFlags flags) 2669 { 2670 ObjectPropertyAccessor *getter = NULL; 2671 ObjectPropertyAccessor *setter = NULL; 2672 2673 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2674 getter = property_get_uint64_ptr; 2675 } 2676 2677 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2678 setter = property_set_uint64_ptr; 2679 } 2680 2681 return object_property_add(obj, name, "uint64", 2682 getter, setter, NULL, (void *)v); 2683 } 2684 2685 ObjectProperty * 2686 object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name, 2687 const uint64_t *v, 2688 ObjectPropertyFlags flags) 2689 { 2690 ObjectPropertyAccessor *getter = NULL; 2691 ObjectPropertyAccessor *setter = NULL; 2692 2693 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2694 getter = property_get_uint64_ptr; 2695 } 2696 2697 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2698 setter = property_set_uint64_ptr; 2699 } 2700 2701 return object_class_property_add(klass, name, "uint64", 2702 getter, setter, NULL, (void *)v); 2703 } 2704 2705 typedef struct { 2706 Object *target_obj; 2707 char *target_name; 2708 } AliasProperty; 2709 2710 static void property_get_alias(Object *obj, Visitor *v, const char *name, 2711 void *opaque, Error **errp) 2712 { 2713 AliasProperty *prop = opaque; 2714 Visitor *alias_v = visitor_forward_field(v, prop->target_name, name); 2715 2716 object_property_get(prop->target_obj, prop->target_name, alias_v, errp); 2717 visit_free(alias_v); 2718 } 2719 2720 static void property_set_alias(Object *obj, Visitor *v, const char *name, 2721 void *opaque, Error **errp) 2722 { 2723 AliasProperty *prop = opaque; 2724 Visitor *alias_v = visitor_forward_field(v, prop->target_name, name); 2725 2726 object_property_set(prop->target_obj, prop->target_name, alias_v, errp); 2727 visit_free(alias_v); 2728 } 2729 2730 static Object *property_resolve_alias(Object *obj, void *opaque, 2731 const char *part) 2732 { 2733 AliasProperty *prop = opaque; 2734 2735 return object_resolve_path_component(prop->target_obj, prop->target_name); 2736 } 2737 2738 static void property_release_alias(Object *obj, const char *name, void *opaque) 2739 { 2740 AliasProperty *prop = opaque; 2741 2742 g_free(prop->target_name); 2743 g_free(prop); 2744 } 2745 2746 ObjectProperty * 2747 object_property_add_alias(Object *obj, const char *name, 2748 Object *target_obj, const char *target_name) 2749 { 2750 AliasProperty *prop; 2751 ObjectProperty *op; 2752 ObjectProperty *target_prop; 2753 g_autofree char *prop_type = NULL; 2754 2755 target_prop = object_property_find_err(target_obj, target_name, 2756 &error_abort); 2757 2758 if (object_property_is_child(target_prop)) { 2759 prop_type = g_strdup_printf("link%s", 2760 target_prop->type + strlen("child")); 2761 } else { 2762 prop_type = g_strdup(target_prop->type); 2763 } 2764 2765 prop = g_malloc(sizeof(*prop)); 2766 prop->target_obj = target_obj; 2767 prop->target_name = g_strdup(target_name); 2768 2769 op = object_property_add(obj, name, prop_type, 2770 property_get_alias, 2771 property_set_alias, 2772 property_release_alias, 2773 prop); 2774 op->resolve = property_resolve_alias; 2775 if (target_prop->defval) { 2776 op->defval = qobject_ref(target_prop->defval); 2777 } 2778 2779 object_property_set_description(obj, op->name, 2780 target_prop->description); 2781 return op; 2782 } 2783 2784 void object_property_set_description(Object *obj, const char *name, 2785 const char *description) 2786 { 2787 ObjectProperty *op; 2788 2789 op = object_property_find_err(obj, name, &error_abort); 2790 g_free(op->description); 2791 op->description = g_strdup(description); 2792 } 2793 2794 void object_class_property_set_description(ObjectClass *klass, 2795 const char *name, 2796 const char *description) 2797 { 2798 ObjectProperty *op; 2799 2800 op = g_hash_table_lookup(klass->properties, name); 2801 g_free(op->description); 2802 op->description = g_strdup(description); 2803 } 2804 2805 static void object_class_init(ObjectClass *klass, void *data) 2806 { 2807 object_class_property_add_str(klass, "type", object_get_type, 2808 NULL); 2809 } 2810 2811 static void register_types(void) 2812 { 2813 static const TypeInfo interface_info = { 2814 .name = TYPE_INTERFACE, 2815 .class_size = sizeof(InterfaceClass), 2816 .abstract = true, 2817 }; 2818 2819 static const TypeInfo object_info = { 2820 .name = TYPE_OBJECT, 2821 .instance_size = sizeof(Object), 2822 .class_init = object_class_init, 2823 .abstract = true, 2824 }; 2825 2826 type_interface = type_register_internal(&interface_info); 2827 type_register_internal(&object_info); 2828 } 2829 2830 type_init(register_types) 2831