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