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_one(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_one(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 if (!obj) { 1172 return NULL; 1173 } 1174 qatomic_inc(&obj->ref); 1175 return obj; 1176 } 1177 1178 void object_unref(void *objptr) 1179 { 1180 Object *obj = OBJECT(objptr); 1181 if (!obj) { 1182 return; 1183 } 1184 g_assert(obj->ref > 0); 1185 1186 /* parent always holds a reference to its children */ 1187 if (qatomic_fetch_dec(&obj->ref) == 1) { 1188 object_finalize(obj); 1189 } 1190 } 1191 1192 ObjectProperty * 1193 object_property_try_add(Object *obj, const char *name, const char *type, 1194 ObjectPropertyAccessor *get, 1195 ObjectPropertyAccessor *set, 1196 ObjectPropertyRelease *release, 1197 void *opaque, Error **errp) 1198 { 1199 ObjectProperty *prop; 1200 size_t name_len = strlen(name); 1201 1202 if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) { 1203 int i; 1204 ObjectProperty *ret = NULL; 1205 char *name_no_array = g_strdup(name); 1206 1207 name_no_array[name_len - 3] = '\0'; 1208 for (i = 0; i < INT16_MAX; ++i) { 1209 char *full_name = g_strdup_printf("%s[%d]", name_no_array, i); 1210 1211 ret = object_property_try_add(obj, full_name, type, get, set, 1212 release, opaque, NULL); 1213 g_free(full_name); 1214 if (ret) { 1215 break; 1216 } 1217 } 1218 g_free(name_no_array); 1219 assert(ret); 1220 return ret; 1221 } 1222 1223 if (object_property_find(obj, name) != NULL) { 1224 error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')", 1225 name, object_get_typename(obj)); 1226 return NULL; 1227 } 1228 1229 prop = g_malloc0(sizeof(*prop)); 1230 1231 prop->name = g_strdup(name); 1232 prop->type = g_strdup(type); 1233 1234 prop->get = get; 1235 prop->set = set; 1236 prop->release = release; 1237 prop->opaque = opaque; 1238 1239 g_hash_table_insert(obj->properties, prop->name, prop); 1240 return prop; 1241 } 1242 1243 ObjectProperty * 1244 object_property_add(Object *obj, const char *name, const char *type, 1245 ObjectPropertyAccessor *get, 1246 ObjectPropertyAccessor *set, 1247 ObjectPropertyRelease *release, 1248 void *opaque) 1249 { 1250 return object_property_try_add(obj, name, type, get, set, release, 1251 opaque, &error_abort); 1252 } 1253 1254 ObjectProperty * 1255 object_class_property_add(ObjectClass *klass, 1256 const char *name, 1257 const char *type, 1258 ObjectPropertyAccessor *get, 1259 ObjectPropertyAccessor *set, 1260 ObjectPropertyRelease *release, 1261 void *opaque) 1262 { 1263 ObjectProperty *prop; 1264 1265 assert(!object_class_property_find(klass, name)); 1266 1267 prop = g_malloc0(sizeof(*prop)); 1268 1269 prop->name = g_strdup(name); 1270 prop->type = g_strdup(type); 1271 1272 prop->get = get; 1273 prop->set = set; 1274 prop->release = release; 1275 prop->opaque = opaque; 1276 1277 g_hash_table_insert(klass->properties, prop->name, prop); 1278 1279 return prop; 1280 } 1281 1282 ObjectProperty *object_property_find(Object *obj, const char *name) 1283 { 1284 ObjectProperty *prop; 1285 ObjectClass *klass = object_get_class(obj); 1286 1287 prop = object_class_property_find(klass, name); 1288 if (prop) { 1289 return prop; 1290 } 1291 1292 return g_hash_table_lookup(obj->properties, name); 1293 } 1294 1295 ObjectProperty *object_property_find_err(Object *obj, const char *name, 1296 Error **errp) 1297 { 1298 ObjectProperty *prop = object_property_find(obj, name); 1299 if (!prop) { 1300 error_setg(errp, "Property '%s.%s' not found", 1301 object_get_typename(obj), name); 1302 } 1303 return prop; 1304 } 1305 1306 void object_property_iter_init(ObjectPropertyIterator *iter, 1307 Object *obj) 1308 { 1309 g_hash_table_iter_init(&iter->iter, obj->properties); 1310 iter->nextclass = object_get_class(obj); 1311 } 1312 1313 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter) 1314 { 1315 gpointer key, val; 1316 while (!g_hash_table_iter_next(&iter->iter, &key, &val)) { 1317 if (!iter->nextclass) { 1318 return NULL; 1319 } 1320 g_hash_table_iter_init(&iter->iter, iter->nextclass->properties); 1321 iter->nextclass = object_class_get_parent(iter->nextclass); 1322 } 1323 return val; 1324 } 1325 1326 void object_class_property_iter_init(ObjectPropertyIterator *iter, 1327 ObjectClass *klass) 1328 { 1329 g_hash_table_iter_init(&iter->iter, klass->properties); 1330 iter->nextclass = object_class_get_parent(klass); 1331 } 1332 1333 ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name) 1334 { 1335 ObjectClass *parent_klass; 1336 1337 parent_klass = object_class_get_parent(klass); 1338 if (parent_klass) { 1339 ObjectProperty *prop = 1340 object_class_property_find(parent_klass, name); 1341 if (prop) { 1342 return prop; 1343 } 1344 } 1345 1346 return g_hash_table_lookup(klass->properties, name); 1347 } 1348 1349 ObjectProperty *object_class_property_find_err(ObjectClass *klass, 1350 const char *name, 1351 Error **errp) 1352 { 1353 ObjectProperty *prop = object_class_property_find(klass, name); 1354 if (!prop) { 1355 error_setg(errp, "Property '.%s' not found", name); 1356 } 1357 return prop; 1358 } 1359 1360 1361 void object_property_del(Object *obj, const char *name) 1362 { 1363 ObjectProperty *prop = g_hash_table_lookup(obj->properties, name); 1364 1365 if (prop->release) { 1366 prop->release(obj, name, prop->opaque); 1367 } 1368 g_hash_table_remove(obj->properties, name); 1369 } 1370 1371 bool object_property_get(Object *obj, const char *name, Visitor *v, 1372 Error **errp) 1373 { 1374 Error *err = NULL; 1375 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1376 1377 if (prop == NULL) { 1378 return false; 1379 } 1380 1381 if (!prop->get) { 1382 error_setg(errp, QERR_PERMISSION_DENIED); 1383 return false; 1384 } 1385 prop->get(obj, v, name, prop->opaque, &err); 1386 error_propagate(errp, err); 1387 return !err; 1388 } 1389 1390 bool object_property_set(Object *obj, const char *name, Visitor *v, 1391 Error **errp) 1392 { 1393 ERRP_GUARD(); 1394 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1395 1396 if (prop == NULL) { 1397 return false; 1398 } 1399 1400 if (!prop->set) { 1401 error_setg(errp, QERR_PERMISSION_DENIED); 1402 return false; 1403 } 1404 prop->set(obj, v, name, prop->opaque, errp); 1405 return !*errp; 1406 } 1407 1408 bool object_property_set_str(Object *obj, const char *name, 1409 const char *value, Error **errp) 1410 { 1411 QString *qstr = qstring_from_str(value); 1412 bool ok = object_property_set_qobject(obj, name, QOBJECT(qstr), errp); 1413 1414 qobject_unref(qstr); 1415 return ok; 1416 } 1417 1418 char *object_property_get_str(Object *obj, const char *name, 1419 Error **errp) 1420 { 1421 QObject *ret = object_property_get_qobject(obj, name, errp); 1422 QString *qstring; 1423 char *retval; 1424 1425 if (!ret) { 1426 return NULL; 1427 } 1428 qstring = qobject_to(QString, ret); 1429 if (!qstring) { 1430 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 1431 retval = NULL; 1432 } else { 1433 retval = g_strdup(qstring_get_str(qstring)); 1434 } 1435 1436 qobject_unref(ret); 1437 return retval; 1438 } 1439 1440 bool object_property_set_link(Object *obj, const char *name, 1441 Object *value, Error **errp) 1442 { 1443 g_autofree char *path = NULL; 1444 1445 if (value) { 1446 path = object_get_canonical_path(value); 1447 } 1448 return object_property_set_str(obj, name, path ?: "", errp); 1449 } 1450 1451 Object *object_property_get_link(Object *obj, const char *name, 1452 Error **errp) 1453 { 1454 char *str = object_property_get_str(obj, name, errp); 1455 Object *target = NULL; 1456 1457 if (str && *str) { 1458 target = object_resolve_path(str, NULL); 1459 if (!target) { 1460 error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, 1461 "Device '%s' not found", str); 1462 } 1463 } 1464 1465 g_free(str); 1466 return target; 1467 } 1468 1469 bool object_property_set_bool(Object *obj, const char *name, 1470 bool value, Error **errp) 1471 { 1472 QBool *qbool = qbool_from_bool(value); 1473 bool ok = object_property_set_qobject(obj, name, QOBJECT(qbool), errp); 1474 1475 qobject_unref(qbool); 1476 return ok; 1477 } 1478 1479 bool object_property_get_bool(Object *obj, const char *name, 1480 Error **errp) 1481 { 1482 QObject *ret = object_property_get_qobject(obj, name, errp); 1483 QBool *qbool; 1484 bool retval; 1485 1486 if (!ret) { 1487 return false; 1488 } 1489 qbool = qobject_to(QBool, ret); 1490 if (!qbool) { 1491 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 1492 retval = false; 1493 } else { 1494 retval = qbool_get_bool(qbool); 1495 } 1496 1497 qobject_unref(ret); 1498 return retval; 1499 } 1500 1501 bool object_property_set_int(Object *obj, const char *name, 1502 int64_t value, Error **errp) 1503 { 1504 QNum *qnum = qnum_from_int(value); 1505 bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp); 1506 1507 qobject_unref(qnum); 1508 return ok; 1509 } 1510 1511 int64_t object_property_get_int(Object *obj, const char *name, 1512 Error **errp) 1513 { 1514 QObject *ret = object_property_get_qobject(obj, name, errp); 1515 QNum *qnum; 1516 int64_t retval; 1517 1518 if (!ret) { 1519 return -1; 1520 } 1521 1522 qnum = qobject_to(QNum, ret); 1523 if (!qnum || !qnum_get_try_int(qnum, &retval)) { 1524 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 1525 retval = -1; 1526 } 1527 1528 qobject_unref(ret); 1529 return retval; 1530 } 1531 1532 static void object_property_init_defval(Object *obj, ObjectProperty *prop) 1533 { 1534 Visitor *v = qobject_input_visitor_new(prop->defval); 1535 1536 assert(prop->set != NULL); 1537 prop->set(obj, v, prop->name, prop->opaque, &error_abort); 1538 1539 visit_free(v); 1540 } 1541 1542 static void object_property_set_default(ObjectProperty *prop, QObject *defval) 1543 { 1544 assert(!prop->defval); 1545 assert(!prop->init); 1546 1547 prop->defval = defval; 1548 prop->init = object_property_init_defval; 1549 } 1550 1551 void object_property_set_default_bool(ObjectProperty *prop, bool value) 1552 { 1553 object_property_set_default(prop, QOBJECT(qbool_from_bool(value))); 1554 } 1555 1556 void object_property_set_default_str(ObjectProperty *prop, const char *value) 1557 { 1558 object_property_set_default(prop, QOBJECT(qstring_from_str(value))); 1559 } 1560 1561 void object_property_set_default_int(ObjectProperty *prop, int64_t value) 1562 { 1563 object_property_set_default(prop, QOBJECT(qnum_from_int(value))); 1564 } 1565 1566 void object_property_set_default_uint(ObjectProperty *prop, uint64_t value) 1567 { 1568 object_property_set_default(prop, QOBJECT(qnum_from_uint(value))); 1569 } 1570 1571 bool object_property_set_uint(Object *obj, const char *name, 1572 uint64_t value, Error **errp) 1573 { 1574 QNum *qnum = qnum_from_uint(value); 1575 bool ok = object_property_set_qobject(obj, name, QOBJECT(qnum), errp); 1576 1577 qobject_unref(qnum); 1578 return ok; 1579 } 1580 1581 uint64_t object_property_get_uint(Object *obj, const char *name, 1582 Error **errp) 1583 { 1584 QObject *ret = object_property_get_qobject(obj, name, errp); 1585 QNum *qnum; 1586 uint64_t retval; 1587 1588 if (!ret) { 1589 return 0; 1590 } 1591 qnum = qobject_to(QNum, ret); 1592 if (!qnum || !qnum_get_try_uint(qnum, &retval)) { 1593 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint"); 1594 retval = 0; 1595 } 1596 1597 qobject_unref(ret); 1598 return retval; 1599 } 1600 1601 typedef struct EnumProperty { 1602 const QEnumLookup *lookup; 1603 int (*get)(Object *, Error **); 1604 void (*set)(Object *, int, Error **); 1605 } EnumProperty; 1606 1607 int object_property_get_enum(Object *obj, const char *name, 1608 const char *typename, Error **errp) 1609 { 1610 char *str; 1611 int ret; 1612 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1613 EnumProperty *enumprop; 1614 1615 if (prop == NULL) { 1616 return -1; 1617 } 1618 1619 if (!g_str_equal(prop->type, typename)) { 1620 error_setg(errp, "Property %s on %s is not '%s' enum type", 1621 name, object_class_get_name( 1622 object_get_class(obj)), typename); 1623 return -1; 1624 } 1625 1626 enumprop = prop->opaque; 1627 1628 str = object_property_get_str(obj, name, errp); 1629 if (!str) { 1630 return -1; 1631 } 1632 1633 ret = qapi_enum_parse(enumprop->lookup, str, -1, errp); 1634 g_free(str); 1635 1636 return ret; 1637 } 1638 1639 bool object_property_parse(Object *obj, const char *name, 1640 const char *string, Error **errp) 1641 { 1642 Visitor *v = string_input_visitor_new(string); 1643 bool ok = object_property_set(obj, name, v, errp); 1644 1645 visit_free(v); 1646 return ok; 1647 } 1648 1649 char *object_property_print(Object *obj, const char *name, bool human, 1650 Error **errp) 1651 { 1652 Visitor *v; 1653 char *string = NULL; 1654 1655 v = string_output_visitor_new(human, &string); 1656 if (!object_property_get(obj, name, v, errp)) { 1657 goto out; 1658 } 1659 1660 visit_complete(v, &string); 1661 1662 out: 1663 visit_free(v); 1664 return string; 1665 } 1666 1667 const char *object_property_get_type(Object *obj, const char *name, Error **errp) 1668 { 1669 ObjectProperty *prop = object_property_find_err(obj, name, errp); 1670 if (prop == NULL) { 1671 return NULL; 1672 } 1673 1674 return prop->type; 1675 } 1676 1677 Object *object_get_root(void) 1678 { 1679 static Object *root; 1680 1681 if (!root) { 1682 root = object_new("container"); 1683 } 1684 1685 return root; 1686 } 1687 1688 Object *object_get_objects_root(void) 1689 { 1690 return container_get(object_get_root(), "/objects"); 1691 } 1692 1693 Object *object_get_internal_root(void) 1694 { 1695 static Object *internal_root; 1696 1697 if (!internal_root) { 1698 internal_root = object_new("container"); 1699 } 1700 1701 return internal_root; 1702 } 1703 1704 static void object_get_child_property(Object *obj, Visitor *v, 1705 const char *name, void *opaque, 1706 Error **errp) 1707 { 1708 Object *child = opaque; 1709 char *path; 1710 1711 path = object_get_canonical_path(child); 1712 visit_type_str(v, name, &path, errp); 1713 g_free(path); 1714 } 1715 1716 static Object *object_resolve_child_property(Object *parent, void *opaque, 1717 const char *part) 1718 { 1719 return opaque; 1720 } 1721 1722 static void object_finalize_child_property(Object *obj, const char *name, 1723 void *opaque) 1724 { 1725 Object *child = opaque; 1726 1727 if (child->class->unparent) { 1728 (child->class->unparent)(child); 1729 } 1730 child->parent = NULL; 1731 object_unref(child); 1732 } 1733 1734 ObjectProperty * 1735 object_property_try_add_child(Object *obj, const char *name, 1736 Object *child, Error **errp) 1737 { 1738 g_autofree char *type = NULL; 1739 ObjectProperty *op; 1740 1741 assert(!child->parent); 1742 1743 type = g_strdup_printf("child<%s>", object_get_typename(child)); 1744 1745 op = object_property_try_add(obj, name, type, object_get_child_property, 1746 NULL, object_finalize_child_property, 1747 child, errp); 1748 if (!op) { 1749 return NULL; 1750 } 1751 op->resolve = object_resolve_child_property; 1752 object_ref(child); 1753 child->parent = obj; 1754 return op; 1755 } 1756 1757 ObjectProperty * 1758 object_property_add_child(Object *obj, const char *name, 1759 Object *child) 1760 { 1761 return object_property_try_add_child(obj, name, child, &error_abort); 1762 } 1763 1764 void object_property_allow_set_link(const Object *obj, const char *name, 1765 Object *val, Error **errp) 1766 { 1767 /* Allow the link to be set, always */ 1768 } 1769 1770 typedef struct { 1771 union { 1772 Object **targetp; 1773 Object *target; /* if OBJ_PROP_LINK_DIRECT, when holding the pointer */ 1774 ptrdiff_t offset; /* if OBJ_PROP_LINK_CLASS */ 1775 }; 1776 void (*check)(const Object *, const char *, Object *, Error **); 1777 ObjectPropertyLinkFlags flags; 1778 } LinkProperty; 1779 1780 static Object ** 1781 object_link_get_targetp(Object *obj, LinkProperty *lprop) 1782 { 1783 if (lprop->flags & OBJ_PROP_LINK_DIRECT) { 1784 return &lprop->target; 1785 } else if (lprop->flags & OBJ_PROP_LINK_CLASS) { 1786 return (void *)obj + lprop->offset; 1787 } else { 1788 return lprop->targetp; 1789 } 1790 } 1791 1792 static void object_get_link_property(Object *obj, Visitor *v, 1793 const char *name, void *opaque, 1794 Error **errp) 1795 { 1796 LinkProperty *lprop = opaque; 1797 Object **targetp = object_link_get_targetp(obj, lprop); 1798 char *path; 1799 1800 if (*targetp) { 1801 path = object_get_canonical_path(*targetp); 1802 visit_type_str(v, name, &path, errp); 1803 g_free(path); 1804 } else { 1805 path = (char *)""; 1806 visit_type_str(v, name, &path, errp); 1807 } 1808 } 1809 1810 /* 1811 * object_resolve_link: 1812 * 1813 * Lookup an object and ensure its type matches the link property type. This 1814 * is similar to object_resolve_path() except type verification against the 1815 * link property is performed. 1816 * 1817 * Returns: The matched object or NULL on path lookup failures. 1818 */ 1819 static Object *object_resolve_link(Object *obj, const char *name, 1820 const char *path, Error **errp) 1821 { 1822 const char *type; 1823 char *target_type; 1824 bool ambiguous = false; 1825 Object *target; 1826 1827 /* Go from link<FOO> to FOO. */ 1828 type = object_property_get_type(obj, name, NULL); 1829 target_type = g_strndup(&type[5], strlen(type) - 6); 1830 target = object_resolve_path_type(path, target_type, &ambiguous); 1831 1832 if (ambiguous) { 1833 error_setg(errp, "Path '%s' does not uniquely identify an object", 1834 path); 1835 } else if (!target) { 1836 target = object_resolve_path(path, &ambiguous); 1837 if (target || ambiguous) { 1838 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 1839 } else { 1840 error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, 1841 "Device '%s' not found", path); 1842 } 1843 target = NULL; 1844 } 1845 g_free(target_type); 1846 1847 return target; 1848 } 1849 1850 static void object_set_link_property(Object *obj, Visitor *v, 1851 const char *name, void *opaque, 1852 Error **errp) 1853 { 1854 Error *local_err = NULL; 1855 LinkProperty *prop = opaque; 1856 Object **targetp = object_link_get_targetp(obj, prop); 1857 Object *old_target = *targetp; 1858 Object *new_target; 1859 char *path = NULL; 1860 1861 if (!visit_type_str(v, name, &path, errp)) { 1862 return; 1863 } 1864 1865 if (*path) { 1866 new_target = object_resolve_link(obj, name, path, errp); 1867 if (!new_target) { 1868 g_free(path); 1869 return; 1870 } 1871 } else { 1872 new_target = NULL; 1873 } 1874 1875 g_free(path); 1876 1877 prop->check(obj, name, new_target, &local_err); 1878 if (local_err) { 1879 error_propagate(errp, local_err); 1880 return; 1881 } 1882 1883 *targetp = new_target; 1884 if (prop->flags & OBJ_PROP_LINK_STRONG) { 1885 object_ref(new_target); 1886 object_unref(old_target); 1887 } 1888 } 1889 1890 static Object *object_resolve_link_property(Object *parent, void *opaque, 1891 const char *part) 1892 { 1893 LinkProperty *lprop = opaque; 1894 1895 return *object_link_get_targetp(parent, lprop); 1896 } 1897 1898 static void object_release_link_property(Object *obj, const char *name, 1899 void *opaque) 1900 { 1901 LinkProperty *prop = opaque; 1902 Object **targetp = object_link_get_targetp(obj, prop); 1903 1904 if ((prop->flags & OBJ_PROP_LINK_STRONG) && *targetp) { 1905 object_unref(*targetp); 1906 } 1907 if (!(prop->flags & OBJ_PROP_LINK_CLASS)) { 1908 g_free(prop); 1909 } 1910 } 1911 1912 static ObjectProperty * 1913 object_add_link_prop(Object *obj, const char *name, 1914 const char *type, void *ptr, 1915 void (*check)(const Object *, const char *, 1916 Object *, Error **), 1917 ObjectPropertyLinkFlags flags) 1918 { 1919 LinkProperty *prop = g_malloc(sizeof(*prop)); 1920 g_autofree char *full_type = NULL; 1921 ObjectProperty *op; 1922 1923 if (flags & OBJ_PROP_LINK_DIRECT) { 1924 prop->target = ptr; 1925 } else { 1926 prop->targetp = ptr; 1927 } 1928 prop->check = check; 1929 prop->flags = flags; 1930 1931 full_type = g_strdup_printf("link<%s>", type); 1932 1933 op = object_property_add(obj, name, full_type, 1934 object_get_link_property, 1935 check ? object_set_link_property : NULL, 1936 object_release_link_property, 1937 prop); 1938 op->resolve = object_resolve_link_property; 1939 return op; 1940 } 1941 1942 ObjectProperty * 1943 object_property_add_link(Object *obj, const char *name, 1944 const char *type, Object **targetp, 1945 void (*check)(const Object *, const char *, 1946 Object *, Error **), 1947 ObjectPropertyLinkFlags flags) 1948 { 1949 return object_add_link_prop(obj, name, type, targetp, check, flags); 1950 } 1951 1952 ObjectProperty * 1953 object_class_property_add_link(ObjectClass *oc, 1954 const char *name, 1955 const char *type, ptrdiff_t offset, 1956 void (*check)(const Object *obj, const char *name, 1957 Object *val, Error **errp), 1958 ObjectPropertyLinkFlags flags) 1959 { 1960 LinkProperty *prop = g_new0(LinkProperty, 1); 1961 char *full_type; 1962 ObjectProperty *op; 1963 1964 prop->offset = offset; 1965 prop->check = check; 1966 prop->flags = flags | OBJ_PROP_LINK_CLASS; 1967 1968 full_type = g_strdup_printf("link<%s>", type); 1969 1970 op = object_class_property_add(oc, name, full_type, 1971 object_get_link_property, 1972 check ? object_set_link_property : NULL, 1973 object_release_link_property, 1974 prop); 1975 1976 op->resolve = object_resolve_link_property; 1977 1978 g_free(full_type); 1979 return op; 1980 } 1981 1982 ObjectProperty * 1983 object_property_add_const_link(Object *obj, const char *name, 1984 Object *target) 1985 { 1986 return object_add_link_prop(obj, name, 1987 object_get_typename(target), target, 1988 NULL, OBJ_PROP_LINK_DIRECT); 1989 } 1990 1991 const char *object_get_canonical_path_component(const Object *obj) 1992 { 1993 ObjectProperty *prop = NULL; 1994 GHashTableIter iter; 1995 1996 if (obj->parent == NULL) { 1997 return NULL; 1998 } 1999 2000 g_hash_table_iter_init(&iter, obj->parent->properties); 2001 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) { 2002 if (!object_property_is_child(prop)) { 2003 continue; 2004 } 2005 2006 if (prop->opaque == obj) { 2007 return prop->name; 2008 } 2009 } 2010 2011 /* obj had a parent but was not a child, should never happen */ 2012 g_assert_not_reached(); 2013 return NULL; 2014 } 2015 2016 char *object_get_canonical_path(const Object *obj) 2017 { 2018 Object *root = object_get_root(); 2019 char *newpath, *path = NULL; 2020 2021 if (obj == root) { 2022 return g_strdup("/"); 2023 } 2024 2025 do { 2026 const char *component = object_get_canonical_path_component(obj); 2027 2028 if (!component) { 2029 /* A canonical path must be complete, so discard what was 2030 * collected so far. 2031 */ 2032 g_free(path); 2033 return NULL; 2034 } 2035 2036 newpath = g_strdup_printf("/%s%s", component, path ? path : ""); 2037 g_free(path); 2038 path = newpath; 2039 obj = obj->parent; 2040 } while (obj != root); 2041 2042 return path; 2043 } 2044 2045 Object *object_resolve_path_component(Object *parent, const char *part) 2046 { 2047 ObjectProperty *prop = object_property_find(parent, part); 2048 if (prop == NULL) { 2049 return NULL; 2050 } 2051 2052 if (prop->resolve) { 2053 return prop->resolve(parent, prop->opaque, part); 2054 } else { 2055 return NULL; 2056 } 2057 } 2058 2059 static Object *object_resolve_abs_path(Object *parent, 2060 char **parts, 2061 const char *typename) 2062 { 2063 Object *child; 2064 2065 if (*parts == NULL) { 2066 return object_dynamic_cast(parent, typename); 2067 } 2068 2069 if (strcmp(*parts, "") == 0) { 2070 return object_resolve_abs_path(parent, parts + 1, typename); 2071 } 2072 2073 child = object_resolve_path_component(parent, *parts); 2074 if (!child) { 2075 return NULL; 2076 } 2077 2078 return object_resolve_abs_path(child, parts + 1, typename); 2079 } 2080 2081 static Object *object_resolve_partial_path(Object *parent, 2082 char **parts, 2083 const char *typename, 2084 bool *ambiguous) 2085 { 2086 Object *obj; 2087 GHashTableIter iter; 2088 ObjectProperty *prop; 2089 2090 obj = object_resolve_abs_path(parent, parts, typename); 2091 2092 g_hash_table_iter_init(&iter, parent->properties); 2093 while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) { 2094 Object *found; 2095 2096 if (!object_property_is_child(prop)) { 2097 continue; 2098 } 2099 2100 found = object_resolve_partial_path(prop->opaque, parts, 2101 typename, ambiguous); 2102 if (found) { 2103 if (obj) { 2104 *ambiguous = true; 2105 return NULL; 2106 } 2107 obj = found; 2108 } 2109 2110 if (*ambiguous) { 2111 return NULL; 2112 } 2113 } 2114 2115 return obj; 2116 } 2117 2118 Object *object_resolve_path_type(const char *path, const char *typename, 2119 bool *ambiguousp) 2120 { 2121 Object *obj; 2122 char **parts; 2123 2124 parts = g_strsplit(path, "/", 0); 2125 assert(parts); 2126 2127 if (parts[0] == NULL || strcmp(parts[0], "") != 0) { 2128 bool ambiguous = false; 2129 obj = object_resolve_partial_path(object_get_root(), parts, 2130 typename, &ambiguous); 2131 if (ambiguousp) { 2132 *ambiguousp = ambiguous; 2133 } 2134 } else { 2135 obj = object_resolve_abs_path(object_get_root(), parts + 1, typename); 2136 } 2137 2138 g_strfreev(parts); 2139 2140 return obj; 2141 } 2142 2143 Object *object_resolve_path(const char *path, bool *ambiguous) 2144 { 2145 return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 2146 } 2147 2148 Object *object_resolve_path_at(Object *parent, const char *path) 2149 { 2150 g_auto(GStrv) parts = g_strsplit(path, "/", 0); 2151 2152 if (*path == '/') { 2153 return object_resolve_abs_path(object_get_root(), parts + 1, 2154 TYPE_OBJECT); 2155 } 2156 return object_resolve_abs_path(parent, parts, TYPE_OBJECT); 2157 } 2158 2159 typedef struct StringProperty 2160 { 2161 char *(*get)(Object *, Error **); 2162 void (*set)(Object *, const char *, Error **); 2163 } StringProperty; 2164 2165 static void property_get_str(Object *obj, Visitor *v, const char *name, 2166 void *opaque, Error **errp) 2167 { 2168 StringProperty *prop = opaque; 2169 char *value; 2170 Error *err = NULL; 2171 2172 value = prop->get(obj, &err); 2173 if (err) { 2174 error_propagate(errp, err); 2175 return; 2176 } 2177 2178 visit_type_str(v, name, &value, errp); 2179 g_free(value); 2180 } 2181 2182 static void property_set_str(Object *obj, Visitor *v, const char *name, 2183 void *opaque, Error **errp) 2184 { 2185 StringProperty *prop = opaque; 2186 char *value; 2187 2188 if (!visit_type_str(v, name, &value, errp)) { 2189 return; 2190 } 2191 2192 prop->set(obj, value, errp); 2193 g_free(value); 2194 } 2195 2196 static void property_release_data(Object *obj, const char *name, 2197 void *opaque) 2198 { 2199 g_free(opaque); 2200 } 2201 2202 ObjectProperty * 2203 object_property_add_str(Object *obj, const char *name, 2204 char *(*get)(Object *, Error **), 2205 void (*set)(Object *, const char *, Error **)) 2206 { 2207 StringProperty *prop = g_malloc0(sizeof(*prop)); 2208 2209 prop->get = get; 2210 prop->set = set; 2211 2212 return object_property_add(obj, name, "string", 2213 get ? property_get_str : NULL, 2214 set ? property_set_str : NULL, 2215 property_release_data, 2216 prop); 2217 } 2218 2219 ObjectProperty * 2220 object_class_property_add_str(ObjectClass *klass, const char *name, 2221 char *(*get)(Object *, Error **), 2222 void (*set)(Object *, const char *, 2223 Error **)) 2224 { 2225 StringProperty *prop = g_malloc0(sizeof(*prop)); 2226 2227 prop->get = get; 2228 prop->set = set; 2229 2230 return object_class_property_add(klass, name, "string", 2231 get ? property_get_str : NULL, 2232 set ? property_set_str : NULL, 2233 NULL, 2234 prop); 2235 } 2236 2237 typedef struct BoolProperty 2238 { 2239 bool (*get)(Object *, Error **); 2240 void (*set)(Object *, bool, Error **); 2241 } BoolProperty; 2242 2243 static void property_get_bool(Object *obj, Visitor *v, const char *name, 2244 void *opaque, Error **errp) 2245 { 2246 BoolProperty *prop = opaque; 2247 bool value; 2248 Error *err = NULL; 2249 2250 value = prop->get(obj, &err); 2251 if (err) { 2252 error_propagate(errp, err); 2253 return; 2254 } 2255 2256 visit_type_bool(v, name, &value, errp); 2257 } 2258 2259 static void property_set_bool(Object *obj, Visitor *v, const char *name, 2260 void *opaque, Error **errp) 2261 { 2262 BoolProperty *prop = opaque; 2263 bool value; 2264 2265 if (!visit_type_bool(v, name, &value, errp)) { 2266 return; 2267 } 2268 2269 prop->set(obj, value, errp); 2270 } 2271 2272 ObjectProperty * 2273 object_property_add_bool(Object *obj, const char *name, 2274 bool (*get)(Object *, Error **), 2275 void (*set)(Object *, bool, Error **)) 2276 { 2277 BoolProperty *prop = g_malloc0(sizeof(*prop)); 2278 2279 prop->get = get; 2280 prop->set = set; 2281 2282 return object_property_add(obj, name, "bool", 2283 get ? property_get_bool : NULL, 2284 set ? property_set_bool : NULL, 2285 property_release_data, 2286 prop); 2287 } 2288 2289 ObjectProperty * 2290 object_class_property_add_bool(ObjectClass *klass, const char *name, 2291 bool (*get)(Object *, Error **), 2292 void (*set)(Object *, bool, Error **)) 2293 { 2294 BoolProperty *prop = g_malloc0(sizeof(*prop)); 2295 2296 prop->get = get; 2297 prop->set = set; 2298 2299 return object_class_property_add(klass, name, "bool", 2300 get ? property_get_bool : NULL, 2301 set ? property_set_bool : NULL, 2302 NULL, 2303 prop); 2304 } 2305 2306 static void property_get_enum(Object *obj, Visitor *v, const char *name, 2307 void *opaque, Error **errp) 2308 { 2309 EnumProperty *prop = opaque; 2310 int value; 2311 Error *err = NULL; 2312 2313 value = prop->get(obj, &err); 2314 if (err) { 2315 error_propagate(errp, err); 2316 return; 2317 } 2318 2319 visit_type_enum(v, name, &value, prop->lookup, errp); 2320 } 2321 2322 static void property_set_enum(Object *obj, Visitor *v, const char *name, 2323 void *opaque, Error **errp) 2324 { 2325 EnumProperty *prop = opaque; 2326 int value; 2327 2328 if (!visit_type_enum(v, name, &value, prop->lookup, errp)) { 2329 return; 2330 } 2331 prop->set(obj, value, errp); 2332 } 2333 2334 ObjectProperty * 2335 object_property_add_enum(Object *obj, const char *name, 2336 const char *typename, 2337 const QEnumLookup *lookup, 2338 int (*get)(Object *, Error **), 2339 void (*set)(Object *, int, Error **)) 2340 { 2341 EnumProperty *prop = g_malloc(sizeof(*prop)); 2342 2343 prop->lookup = lookup; 2344 prop->get = get; 2345 prop->set = set; 2346 2347 return object_property_add(obj, name, typename, 2348 get ? property_get_enum : NULL, 2349 set ? property_set_enum : NULL, 2350 property_release_data, 2351 prop); 2352 } 2353 2354 ObjectProperty * 2355 object_class_property_add_enum(ObjectClass *klass, const char *name, 2356 const char *typename, 2357 const QEnumLookup *lookup, 2358 int (*get)(Object *, Error **), 2359 void (*set)(Object *, int, Error **)) 2360 { 2361 EnumProperty *prop = g_malloc(sizeof(*prop)); 2362 2363 prop->lookup = lookup; 2364 prop->get = get; 2365 prop->set = set; 2366 2367 return object_class_property_add(klass, name, typename, 2368 get ? property_get_enum : NULL, 2369 set ? property_set_enum : NULL, 2370 NULL, 2371 prop); 2372 } 2373 2374 typedef struct TMProperty { 2375 void (*get)(Object *, struct tm *, Error **); 2376 } TMProperty; 2377 2378 static void property_get_tm(Object *obj, Visitor *v, const char *name, 2379 void *opaque, Error **errp) 2380 { 2381 TMProperty *prop = opaque; 2382 Error *err = NULL; 2383 struct tm value; 2384 2385 prop->get(obj, &value, &err); 2386 if (err) { 2387 error_propagate(errp, err); 2388 return; 2389 } 2390 2391 if (!visit_start_struct(v, name, NULL, 0, errp)) { 2392 return; 2393 } 2394 if (!visit_type_int32(v, "tm_year", &value.tm_year, errp)) { 2395 goto out_end; 2396 } 2397 if (!visit_type_int32(v, "tm_mon", &value.tm_mon, errp)) { 2398 goto out_end; 2399 } 2400 if (!visit_type_int32(v, "tm_mday", &value.tm_mday, errp)) { 2401 goto out_end; 2402 } 2403 if (!visit_type_int32(v, "tm_hour", &value.tm_hour, errp)) { 2404 goto out_end; 2405 } 2406 if (!visit_type_int32(v, "tm_min", &value.tm_min, errp)) { 2407 goto out_end; 2408 } 2409 if (!visit_type_int32(v, "tm_sec", &value.tm_sec, errp)) { 2410 goto out_end; 2411 } 2412 visit_check_struct(v, errp); 2413 out_end: 2414 visit_end_struct(v, NULL); 2415 } 2416 2417 ObjectProperty * 2418 object_property_add_tm(Object *obj, const char *name, 2419 void (*get)(Object *, struct tm *, Error **)) 2420 { 2421 TMProperty *prop = g_malloc0(sizeof(*prop)); 2422 2423 prop->get = get; 2424 2425 return object_property_add(obj, name, "struct tm", 2426 get ? property_get_tm : NULL, NULL, 2427 property_release_data, 2428 prop); 2429 } 2430 2431 ObjectProperty * 2432 object_class_property_add_tm(ObjectClass *klass, const char *name, 2433 void (*get)(Object *, struct tm *, Error **)) 2434 { 2435 TMProperty *prop = g_malloc0(sizeof(*prop)); 2436 2437 prop->get = get; 2438 2439 return object_class_property_add(klass, name, "struct tm", 2440 get ? property_get_tm : NULL, 2441 NULL, NULL, prop); 2442 } 2443 2444 static char *object_get_type(Object *obj, Error **errp) 2445 { 2446 return g_strdup(object_get_typename(obj)); 2447 } 2448 2449 static void property_get_uint8_ptr(Object *obj, Visitor *v, const char *name, 2450 void *opaque, Error **errp) 2451 { 2452 uint8_t value = *(uint8_t *)opaque; 2453 visit_type_uint8(v, name, &value, errp); 2454 } 2455 2456 static void property_set_uint8_ptr(Object *obj, Visitor *v, const char *name, 2457 void *opaque, Error **errp) 2458 { 2459 uint8_t *field = opaque; 2460 uint8_t value; 2461 2462 if (!visit_type_uint8(v, name, &value, errp)) { 2463 return; 2464 } 2465 2466 *field = value; 2467 } 2468 2469 static void property_get_uint16_ptr(Object *obj, Visitor *v, const char *name, 2470 void *opaque, Error **errp) 2471 { 2472 uint16_t value = *(uint16_t *)opaque; 2473 visit_type_uint16(v, name, &value, errp); 2474 } 2475 2476 static void property_set_uint16_ptr(Object *obj, Visitor *v, const char *name, 2477 void *opaque, Error **errp) 2478 { 2479 uint16_t *field = opaque; 2480 uint16_t value; 2481 2482 if (!visit_type_uint16(v, name, &value, errp)) { 2483 return; 2484 } 2485 2486 *field = value; 2487 } 2488 2489 static void property_get_uint32_ptr(Object *obj, Visitor *v, const char *name, 2490 void *opaque, Error **errp) 2491 { 2492 uint32_t value = *(uint32_t *)opaque; 2493 visit_type_uint32(v, name, &value, errp); 2494 } 2495 2496 static void property_set_uint32_ptr(Object *obj, Visitor *v, const char *name, 2497 void *opaque, Error **errp) 2498 { 2499 uint32_t *field = opaque; 2500 uint32_t value; 2501 2502 if (!visit_type_uint32(v, name, &value, errp)) { 2503 return; 2504 } 2505 2506 *field = value; 2507 } 2508 2509 static void property_get_uint64_ptr(Object *obj, Visitor *v, const char *name, 2510 void *opaque, Error **errp) 2511 { 2512 uint64_t value = *(uint64_t *)opaque; 2513 visit_type_uint64(v, name, &value, errp); 2514 } 2515 2516 static void property_set_uint64_ptr(Object *obj, Visitor *v, const char *name, 2517 void *opaque, Error **errp) 2518 { 2519 uint64_t *field = opaque; 2520 uint64_t value; 2521 2522 if (!visit_type_uint64(v, name, &value, errp)) { 2523 return; 2524 } 2525 2526 *field = value; 2527 } 2528 2529 ObjectProperty * 2530 object_property_add_uint8_ptr(Object *obj, const char *name, 2531 const uint8_t *v, 2532 ObjectPropertyFlags flags) 2533 { 2534 ObjectPropertyAccessor *getter = NULL; 2535 ObjectPropertyAccessor *setter = NULL; 2536 2537 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2538 getter = property_get_uint8_ptr; 2539 } 2540 2541 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2542 setter = property_set_uint8_ptr; 2543 } 2544 2545 return object_property_add(obj, name, "uint8", 2546 getter, setter, NULL, (void *)v); 2547 } 2548 2549 ObjectProperty * 2550 object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name, 2551 const uint8_t *v, 2552 ObjectPropertyFlags flags) 2553 { 2554 ObjectPropertyAccessor *getter = NULL; 2555 ObjectPropertyAccessor *setter = NULL; 2556 2557 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2558 getter = property_get_uint8_ptr; 2559 } 2560 2561 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2562 setter = property_set_uint8_ptr; 2563 } 2564 2565 return object_class_property_add(klass, name, "uint8", 2566 getter, setter, NULL, (void *)v); 2567 } 2568 2569 ObjectProperty * 2570 object_property_add_uint16_ptr(Object *obj, const char *name, 2571 const uint16_t *v, 2572 ObjectPropertyFlags flags) 2573 { 2574 ObjectPropertyAccessor *getter = NULL; 2575 ObjectPropertyAccessor *setter = NULL; 2576 2577 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2578 getter = property_get_uint16_ptr; 2579 } 2580 2581 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2582 setter = property_set_uint16_ptr; 2583 } 2584 2585 return object_property_add(obj, name, "uint16", 2586 getter, setter, NULL, (void *)v); 2587 } 2588 2589 ObjectProperty * 2590 object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name, 2591 const uint16_t *v, 2592 ObjectPropertyFlags flags) 2593 { 2594 ObjectPropertyAccessor *getter = NULL; 2595 ObjectPropertyAccessor *setter = NULL; 2596 2597 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2598 getter = property_get_uint16_ptr; 2599 } 2600 2601 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2602 setter = property_set_uint16_ptr; 2603 } 2604 2605 return object_class_property_add(klass, name, "uint16", 2606 getter, setter, NULL, (void *)v); 2607 } 2608 2609 ObjectProperty * 2610 object_property_add_uint32_ptr(Object *obj, const char *name, 2611 const uint32_t *v, 2612 ObjectPropertyFlags flags) 2613 { 2614 ObjectPropertyAccessor *getter = NULL; 2615 ObjectPropertyAccessor *setter = NULL; 2616 2617 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2618 getter = property_get_uint32_ptr; 2619 } 2620 2621 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2622 setter = property_set_uint32_ptr; 2623 } 2624 2625 return object_property_add(obj, name, "uint32", 2626 getter, setter, NULL, (void *)v); 2627 } 2628 2629 ObjectProperty * 2630 object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name, 2631 const uint32_t *v, 2632 ObjectPropertyFlags flags) 2633 { 2634 ObjectPropertyAccessor *getter = NULL; 2635 ObjectPropertyAccessor *setter = NULL; 2636 2637 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2638 getter = property_get_uint32_ptr; 2639 } 2640 2641 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2642 setter = property_set_uint32_ptr; 2643 } 2644 2645 return object_class_property_add(klass, name, "uint32", 2646 getter, setter, NULL, (void *)v); 2647 } 2648 2649 ObjectProperty * 2650 object_property_add_uint64_ptr(Object *obj, const char *name, 2651 const uint64_t *v, 2652 ObjectPropertyFlags flags) 2653 { 2654 ObjectPropertyAccessor *getter = NULL; 2655 ObjectPropertyAccessor *setter = NULL; 2656 2657 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2658 getter = property_get_uint64_ptr; 2659 } 2660 2661 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2662 setter = property_set_uint64_ptr; 2663 } 2664 2665 return object_property_add(obj, name, "uint64", 2666 getter, setter, NULL, (void *)v); 2667 } 2668 2669 ObjectProperty * 2670 object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name, 2671 const uint64_t *v, 2672 ObjectPropertyFlags flags) 2673 { 2674 ObjectPropertyAccessor *getter = NULL; 2675 ObjectPropertyAccessor *setter = NULL; 2676 2677 if ((flags & OBJ_PROP_FLAG_READ) == OBJ_PROP_FLAG_READ) { 2678 getter = property_get_uint64_ptr; 2679 } 2680 2681 if ((flags & OBJ_PROP_FLAG_WRITE) == OBJ_PROP_FLAG_WRITE) { 2682 setter = property_set_uint64_ptr; 2683 } 2684 2685 return object_class_property_add(klass, name, "uint64", 2686 getter, setter, NULL, (void *)v); 2687 } 2688 2689 typedef struct { 2690 Object *target_obj; 2691 char *target_name; 2692 } AliasProperty; 2693 2694 static void property_get_alias(Object *obj, Visitor *v, const char *name, 2695 void *opaque, Error **errp) 2696 { 2697 AliasProperty *prop = opaque; 2698 Visitor *alias_v = visitor_forward_field(v, prop->target_name, name); 2699 2700 object_property_get(prop->target_obj, prop->target_name, alias_v, errp); 2701 visit_free(alias_v); 2702 } 2703 2704 static void property_set_alias(Object *obj, Visitor *v, const char *name, 2705 void *opaque, Error **errp) 2706 { 2707 AliasProperty *prop = opaque; 2708 Visitor *alias_v = visitor_forward_field(v, prop->target_name, name); 2709 2710 object_property_set(prop->target_obj, prop->target_name, alias_v, errp); 2711 visit_free(alias_v); 2712 } 2713 2714 static Object *property_resolve_alias(Object *obj, void *opaque, 2715 const char *part) 2716 { 2717 AliasProperty *prop = opaque; 2718 2719 return object_resolve_path_component(prop->target_obj, prop->target_name); 2720 } 2721 2722 static void property_release_alias(Object *obj, const char *name, void *opaque) 2723 { 2724 AliasProperty *prop = opaque; 2725 2726 g_free(prop->target_name); 2727 g_free(prop); 2728 } 2729 2730 ObjectProperty * 2731 object_property_add_alias(Object *obj, const char *name, 2732 Object *target_obj, const char *target_name) 2733 { 2734 AliasProperty *prop; 2735 ObjectProperty *op; 2736 ObjectProperty *target_prop; 2737 g_autofree char *prop_type = NULL; 2738 2739 target_prop = object_property_find_err(target_obj, target_name, 2740 &error_abort); 2741 2742 if (object_property_is_child(target_prop)) { 2743 prop_type = g_strdup_printf("link%s", 2744 target_prop->type + strlen("child")); 2745 } else { 2746 prop_type = g_strdup(target_prop->type); 2747 } 2748 2749 prop = g_malloc(sizeof(*prop)); 2750 prop->target_obj = target_obj; 2751 prop->target_name = g_strdup(target_name); 2752 2753 op = object_property_add(obj, name, prop_type, 2754 property_get_alias, 2755 property_set_alias, 2756 property_release_alias, 2757 prop); 2758 op->resolve = property_resolve_alias; 2759 if (target_prop->defval) { 2760 op->defval = qobject_ref(target_prop->defval); 2761 } 2762 2763 object_property_set_description(obj, op->name, 2764 target_prop->description); 2765 return op; 2766 } 2767 2768 void object_property_set_description(Object *obj, const char *name, 2769 const char *description) 2770 { 2771 ObjectProperty *op; 2772 2773 op = object_property_find_err(obj, name, &error_abort); 2774 g_free(op->description); 2775 op->description = g_strdup(description); 2776 } 2777 2778 void object_class_property_set_description(ObjectClass *klass, 2779 const char *name, 2780 const char *description) 2781 { 2782 ObjectProperty *op; 2783 2784 op = g_hash_table_lookup(klass->properties, name); 2785 g_free(op->description); 2786 op->description = g_strdup(description); 2787 } 2788 2789 static void object_class_init(ObjectClass *klass, void *data) 2790 { 2791 object_class_property_add_str(klass, "type", object_get_type, 2792 NULL); 2793 } 2794 2795 static void register_types(void) 2796 { 2797 static const TypeInfo interface_info = { 2798 .name = TYPE_INTERFACE, 2799 .class_size = sizeof(InterfaceClass), 2800 .abstract = true, 2801 }; 2802 2803 static const TypeInfo object_info = { 2804 .name = TYPE_OBJECT, 2805 .instance_size = sizeof(Object), 2806 .class_init = object_class_init, 2807 .abstract = true, 2808 }; 2809 2810 type_interface = type_register_internal(&interface_info); 2811 type_register_internal(&object_info); 2812 } 2813 2814 type_init(register_types) 2815