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 "qom/object.h" 14 #include "qom/object_interfaces.h" 15 #include "qemu-common.h" 16 #include "qapi/visitor.h" 17 #include "qapi-visit.h" 18 #include "qapi/string-input-visitor.h" 19 #include "qapi/string-output-visitor.h" 20 #include "qapi/qmp/qerror.h" 21 #include "trace.h" 22 23 /* TODO: replace QObject with a simpler visitor to avoid a dependency 24 * of the QOM core on QObject? */ 25 #include "qom/qom-qobject.h" 26 #include "qapi/qmp/qobject.h" 27 #include "qapi/qmp/qbool.h" 28 #include "qapi/qmp/qint.h" 29 #include "qapi/qmp/qstring.h" 30 31 #define MAX_INTERFACES 32 32 33 typedef struct InterfaceImpl InterfaceImpl; 34 typedef struct TypeImpl TypeImpl; 35 36 struct InterfaceImpl 37 { 38 const char *typename; 39 }; 40 41 struct TypeImpl 42 { 43 const char *name; 44 45 size_t class_size; 46 47 size_t instance_size; 48 49 void (*class_init)(ObjectClass *klass, void *data); 50 void (*class_base_init)(ObjectClass *klass, void *data); 51 void (*class_finalize)(ObjectClass *klass, void *data); 52 53 void *class_data; 54 55 void (*instance_init)(Object *obj); 56 void (*instance_post_init)(Object *obj); 57 void (*instance_finalize)(Object *obj); 58 59 bool abstract; 60 61 const char *parent; 62 TypeImpl *parent_type; 63 64 ObjectClass *class; 65 66 int num_interfaces; 67 InterfaceImpl interfaces[MAX_INTERFACES]; 68 }; 69 70 static Type type_interface; 71 72 static GHashTable *type_table_get(void) 73 { 74 static GHashTable *type_table; 75 76 if (type_table == NULL) { 77 type_table = g_hash_table_new(g_str_hash, g_str_equal); 78 } 79 80 return type_table; 81 } 82 83 static bool enumerating_types; 84 85 static void type_table_add(TypeImpl *ti) 86 { 87 assert(!enumerating_types); 88 g_hash_table_insert(type_table_get(), (void *)ti->name, ti); 89 } 90 91 static TypeImpl *type_table_lookup(const char *name) 92 { 93 return g_hash_table_lookup(type_table_get(), name); 94 } 95 96 static TypeImpl *type_new(const TypeInfo *info) 97 { 98 TypeImpl *ti = g_malloc0(sizeof(*ti)); 99 int i; 100 101 g_assert(info->name != NULL); 102 103 if (type_table_lookup(info->name) != NULL) { 104 fprintf(stderr, "Registering `%s' which already exists\n", info->name); 105 abort(); 106 } 107 108 ti->name = g_strdup(info->name); 109 ti->parent = g_strdup(info->parent); 110 111 ti->class_size = info->class_size; 112 ti->instance_size = info->instance_size; 113 114 ti->class_init = info->class_init; 115 ti->class_base_init = info->class_base_init; 116 ti->class_finalize = info->class_finalize; 117 ti->class_data = info->class_data; 118 119 ti->instance_init = info->instance_init; 120 ti->instance_post_init = info->instance_post_init; 121 ti->instance_finalize = info->instance_finalize; 122 123 ti->abstract = info->abstract; 124 125 for (i = 0; info->interfaces && info->interfaces[i].type; i++) { 126 ti->interfaces[i].typename = g_strdup(info->interfaces[i].type); 127 } 128 ti->num_interfaces = i; 129 130 return ti; 131 } 132 133 static TypeImpl *type_register_internal(const TypeInfo *info) 134 { 135 TypeImpl *ti; 136 ti = type_new(info); 137 138 type_table_add(ti); 139 return ti; 140 } 141 142 TypeImpl *type_register(const TypeInfo *info) 143 { 144 assert(info->parent); 145 return type_register_internal(info); 146 } 147 148 TypeImpl *type_register_static(const TypeInfo *info) 149 { 150 return type_register(info); 151 } 152 153 static TypeImpl *type_get_by_name(const char *name) 154 { 155 if (name == NULL) { 156 return NULL; 157 } 158 159 return type_table_lookup(name); 160 } 161 162 static TypeImpl *type_get_parent(TypeImpl *type) 163 { 164 if (!type->parent_type && type->parent) { 165 type->parent_type = type_get_by_name(type->parent); 166 g_assert(type->parent_type != NULL); 167 } 168 169 return type->parent_type; 170 } 171 172 static bool type_has_parent(TypeImpl *type) 173 { 174 return (type->parent != NULL); 175 } 176 177 static size_t type_class_get_size(TypeImpl *ti) 178 { 179 if (ti->class_size) { 180 return ti->class_size; 181 } 182 183 if (type_has_parent(ti)) { 184 return type_class_get_size(type_get_parent(ti)); 185 } 186 187 return sizeof(ObjectClass); 188 } 189 190 static size_t type_object_get_size(TypeImpl *ti) 191 { 192 if (ti->instance_size) { 193 return ti->instance_size; 194 } 195 196 if (type_has_parent(ti)) { 197 return type_object_get_size(type_get_parent(ti)); 198 } 199 200 return 0; 201 } 202 203 static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) 204 { 205 assert(target_type); 206 207 /* Check if typename is a direct ancestor of type */ 208 while (type) { 209 if (type == target_type) { 210 return true; 211 } 212 213 type = type_get_parent(type); 214 } 215 216 return false; 217 } 218 219 static void type_initialize(TypeImpl *ti); 220 221 static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, 222 TypeImpl *parent_type) 223 { 224 InterfaceClass *new_iface; 225 TypeInfo info = { }; 226 TypeImpl *iface_impl; 227 228 info.parent = parent_type->name; 229 info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name); 230 info.abstract = true; 231 232 iface_impl = type_new(&info); 233 iface_impl->parent_type = parent_type; 234 type_initialize(iface_impl); 235 g_free((char *)info.name); 236 237 new_iface = (InterfaceClass *)iface_impl->class; 238 new_iface->concrete_class = ti->class; 239 new_iface->interface_type = interface_type; 240 241 ti->class->interfaces = g_slist_append(ti->class->interfaces, 242 iface_impl->class); 243 } 244 245 static void type_initialize(TypeImpl *ti) 246 { 247 TypeImpl *parent; 248 249 if (ti->class) { 250 return; 251 } 252 253 ti->class_size = type_class_get_size(ti); 254 ti->instance_size = type_object_get_size(ti); 255 256 ti->class = g_malloc0(ti->class_size); 257 258 parent = type_get_parent(ti); 259 if (parent) { 260 type_initialize(parent); 261 GSList *e; 262 int i; 263 264 g_assert(parent->class_size <= ti->class_size); 265 memcpy(ti->class, parent->class, parent->class_size); 266 ti->class->interfaces = NULL; 267 268 for (e = parent->class->interfaces; e; e = e->next) { 269 InterfaceClass *iface = e->data; 270 ObjectClass *klass = OBJECT_CLASS(iface); 271 272 type_initialize_interface(ti, iface->interface_type, klass->type); 273 } 274 275 for (i = 0; i < ti->num_interfaces; i++) { 276 TypeImpl *t = type_get_by_name(ti->interfaces[i].typename); 277 for (e = ti->class->interfaces; e; e = e->next) { 278 TypeImpl *target_type = OBJECT_CLASS(e->data)->type; 279 280 if (type_is_ancestor(target_type, t)) { 281 break; 282 } 283 } 284 285 if (e) { 286 continue; 287 } 288 289 type_initialize_interface(ti, t, t); 290 } 291 } 292 293 ti->class->type = ti; 294 295 while (parent) { 296 if (parent->class_base_init) { 297 parent->class_base_init(ti->class, ti->class_data); 298 } 299 parent = type_get_parent(parent); 300 } 301 302 if (ti->class_init) { 303 ti->class_init(ti->class, ti->class_data); 304 } 305 } 306 307 static void object_init_with_type(Object *obj, TypeImpl *ti) 308 { 309 if (type_has_parent(ti)) { 310 object_init_with_type(obj, type_get_parent(ti)); 311 } 312 313 if (ti->instance_init) { 314 ti->instance_init(obj); 315 } 316 } 317 318 static void object_post_init_with_type(Object *obj, TypeImpl *ti) 319 { 320 if (ti->instance_post_init) { 321 ti->instance_post_init(obj); 322 } 323 324 if (type_has_parent(ti)) { 325 object_post_init_with_type(obj, type_get_parent(ti)); 326 } 327 } 328 329 void object_initialize_with_type(void *data, size_t size, TypeImpl *type) 330 { 331 Object *obj = data; 332 333 g_assert(type != NULL); 334 type_initialize(type); 335 336 g_assert(type->instance_size >= sizeof(Object)); 337 g_assert(type->abstract == false); 338 g_assert(size >= type->instance_size); 339 340 memset(obj, 0, type->instance_size); 341 obj->class = type->class; 342 object_ref(obj); 343 QTAILQ_INIT(&obj->properties); 344 object_init_with_type(obj, type); 345 object_post_init_with_type(obj, type); 346 } 347 348 void object_initialize(void *data, size_t size, const char *typename) 349 { 350 TypeImpl *type = type_get_by_name(typename); 351 352 object_initialize_with_type(data, size, type); 353 } 354 355 static inline bool object_property_is_child(ObjectProperty *prop) 356 { 357 return strstart(prop->type, "child<", NULL); 358 } 359 360 static void object_property_del_all(Object *obj) 361 { 362 while (!QTAILQ_EMPTY(&obj->properties)) { 363 ObjectProperty *prop = QTAILQ_FIRST(&obj->properties); 364 365 QTAILQ_REMOVE(&obj->properties, prop, node); 366 367 if (prop->release) { 368 prop->release(obj, prop->name, prop->opaque); 369 } 370 371 g_free(prop->name); 372 g_free(prop->type); 373 g_free(prop->description); 374 g_free(prop); 375 } 376 } 377 378 static void object_property_del_child(Object *obj, Object *child, Error **errp) 379 { 380 ObjectProperty *prop; 381 382 QTAILQ_FOREACH(prop, &obj->properties, node) { 383 if (object_property_is_child(prop) && prop->opaque == child) { 384 object_property_del(obj, prop->name, errp); 385 break; 386 } 387 } 388 } 389 390 void object_unparent(Object *obj) 391 { 392 if (obj->parent) { 393 object_property_del_child(obj->parent, obj, NULL); 394 } 395 } 396 397 static void object_deinit(Object *obj, TypeImpl *type) 398 { 399 if (type->instance_finalize) { 400 type->instance_finalize(obj); 401 } 402 403 if (type_has_parent(type)) { 404 object_deinit(obj, type_get_parent(type)); 405 } 406 } 407 408 static void object_finalize(void *data) 409 { 410 Object *obj = data; 411 TypeImpl *ti = obj->class->type; 412 413 object_property_del_all(obj); 414 object_deinit(obj, ti); 415 416 g_assert(obj->ref == 0); 417 if (obj->free) { 418 obj->free(obj); 419 } 420 } 421 422 Object *object_new_with_type(Type type) 423 { 424 Object *obj; 425 426 g_assert(type != NULL); 427 type_initialize(type); 428 429 obj = g_malloc(type->instance_size); 430 object_initialize_with_type(obj, type->instance_size, type); 431 obj->free = g_free; 432 433 return obj; 434 } 435 436 Object *object_new(const char *typename) 437 { 438 TypeImpl *ti = type_get_by_name(typename); 439 440 return object_new_with_type(ti); 441 } 442 443 444 Object *object_new_with_props(const char *typename, 445 Object *parent, 446 const char *id, 447 Error **errp, 448 ...) 449 { 450 va_list vargs; 451 Object *obj; 452 453 va_start(vargs, errp); 454 obj = object_new_with_propv(typename, parent, id, errp, vargs); 455 va_end(vargs); 456 457 return obj; 458 } 459 460 461 Object *object_new_with_propv(const char *typename, 462 Object *parent, 463 const char *id, 464 Error **errp, 465 va_list vargs) 466 { 467 Object *obj; 468 ObjectClass *klass; 469 Error *local_err = NULL; 470 471 klass = object_class_by_name(typename); 472 if (!klass) { 473 error_setg(errp, "invalid object type: %s", typename); 474 return NULL; 475 } 476 477 if (object_class_is_abstract(klass)) { 478 error_setg(errp, "object type '%s' is abstract", typename); 479 return NULL; 480 } 481 obj = object_new(typename); 482 483 if (object_set_propv(obj, &local_err, vargs) < 0) { 484 goto error; 485 } 486 487 object_property_add_child(parent, id, obj, &local_err); 488 if (local_err) { 489 goto error; 490 } 491 492 if (object_dynamic_cast(obj, TYPE_USER_CREATABLE)) { 493 user_creatable_complete(obj, &local_err); 494 if (local_err) { 495 object_unparent(obj); 496 goto error; 497 } 498 } 499 500 object_unref(OBJECT(obj)); 501 return obj; 502 503 error: 504 if (local_err) { 505 error_propagate(errp, local_err); 506 } 507 object_unref(obj); 508 return NULL; 509 } 510 511 512 int object_set_props(Object *obj, 513 Error **errp, 514 ...) 515 { 516 va_list vargs; 517 int ret; 518 519 va_start(vargs, errp); 520 ret = object_set_propv(obj, errp, vargs); 521 va_end(vargs); 522 523 return ret; 524 } 525 526 527 int object_set_propv(Object *obj, 528 Error **errp, 529 va_list vargs) 530 { 531 const char *propname; 532 Error *local_err = NULL; 533 534 propname = va_arg(vargs, char *); 535 while (propname != NULL) { 536 const char *value = va_arg(vargs, char *); 537 538 g_assert(value != NULL); 539 object_property_parse(obj, value, propname, &local_err); 540 if (local_err) { 541 error_propagate(errp, local_err); 542 return -1; 543 } 544 propname = va_arg(vargs, char *); 545 } 546 547 return 0; 548 } 549 550 551 Object *object_dynamic_cast(Object *obj, const char *typename) 552 { 553 if (obj && object_class_dynamic_cast(object_get_class(obj), typename)) { 554 return obj; 555 } 556 557 return NULL; 558 } 559 560 Object *object_dynamic_cast_assert(Object *obj, const char *typename, 561 const char *file, int line, const char *func) 562 { 563 trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)", 564 typename, file, line, func); 565 566 #ifdef CONFIG_QOM_CAST_DEBUG 567 int i; 568 Object *inst; 569 570 for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { 571 if (obj->class->object_cast_cache[i] == typename) { 572 goto out; 573 } 574 } 575 576 inst = object_dynamic_cast(obj, typename); 577 578 if (!inst && obj) { 579 fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 580 file, line, func, obj, typename); 581 abort(); 582 } 583 584 assert(obj == inst); 585 586 if (obj && obj == inst) { 587 for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 588 obj->class->object_cast_cache[i - 1] = 589 obj->class->object_cast_cache[i]; 590 } 591 obj->class->object_cast_cache[i - 1] = typename; 592 } 593 594 out: 595 #endif 596 return obj; 597 } 598 599 ObjectClass *object_class_dynamic_cast(ObjectClass *class, 600 const char *typename) 601 { 602 ObjectClass *ret = NULL; 603 TypeImpl *target_type; 604 TypeImpl *type; 605 606 if (!class) { 607 return NULL; 608 } 609 610 /* A simple fast path that can trigger a lot for leaf classes. */ 611 type = class->type; 612 if (type->name == typename) { 613 return class; 614 } 615 616 target_type = type_get_by_name(typename); 617 if (!target_type) { 618 /* target class type unknown, so fail the cast */ 619 return NULL; 620 } 621 622 if (type->class->interfaces && 623 type_is_ancestor(target_type, type_interface)) { 624 int found = 0; 625 GSList *i; 626 627 for (i = class->interfaces; i; i = i->next) { 628 ObjectClass *target_class = i->data; 629 630 if (type_is_ancestor(target_class->type, target_type)) { 631 ret = target_class; 632 found++; 633 } 634 } 635 636 /* The match was ambiguous, don't allow a cast */ 637 if (found > 1) { 638 ret = NULL; 639 } 640 } else if (type_is_ancestor(type, target_type)) { 641 ret = class; 642 } 643 644 return ret; 645 } 646 647 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, 648 const char *typename, 649 const char *file, int line, 650 const char *func) 651 { 652 ObjectClass *ret; 653 654 trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)", 655 typename, file, line, func); 656 657 #ifdef CONFIG_QOM_CAST_DEBUG 658 int i; 659 660 for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { 661 if (class->class_cast_cache[i] == typename) { 662 ret = class; 663 goto out; 664 } 665 } 666 #else 667 if (!class || !class->interfaces) { 668 return class; 669 } 670 #endif 671 672 ret = object_class_dynamic_cast(class, typename); 673 if (!ret && class) { 674 fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", 675 file, line, func, class, typename); 676 abort(); 677 } 678 679 #ifdef CONFIG_QOM_CAST_DEBUG 680 if (class && ret == class) { 681 for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { 682 class->class_cast_cache[i - 1] = class->class_cast_cache[i]; 683 } 684 class->class_cast_cache[i - 1] = typename; 685 } 686 out: 687 #endif 688 return ret; 689 } 690 691 const char *object_get_typename(Object *obj) 692 { 693 return obj->class->type->name; 694 } 695 696 ObjectClass *object_get_class(Object *obj) 697 { 698 return obj->class; 699 } 700 701 bool object_class_is_abstract(ObjectClass *klass) 702 { 703 return klass->type->abstract; 704 } 705 706 const char *object_class_get_name(ObjectClass *klass) 707 { 708 return klass->type->name; 709 } 710 711 ObjectClass *object_class_by_name(const char *typename) 712 { 713 TypeImpl *type = type_get_by_name(typename); 714 715 if (!type) { 716 return NULL; 717 } 718 719 type_initialize(type); 720 721 return type->class; 722 } 723 724 ObjectClass *object_class_get_parent(ObjectClass *class) 725 { 726 TypeImpl *type = type_get_parent(class->type); 727 728 if (!type) { 729 return NULL; 730 } 731 732 type_initialize(type); 733 734 return type->class; 735 } 736 737 typedef struct OCFData 738 { 739 void (*fn)(ObjectClass *klass, void *opaque); 740 const char *implements_type; 741 bool include_abstract; 742 void *opaque; 743 } OCFData; 744 745 static void object_class_foreach_tramp(gpointer key, gpointer value, 746 gpointer opaque) 747 { 748 OCFData *data = opaque; 749 TypeImpl *type = value; 750 ObjectClass *k; 751 752 type_initialize(type); 753 k = type->class; 754 755 if (!data->include_abstract && type->abstract) { 756 return; 757 } 758 759 if (data->implements_type && 760 !object_class_dynamic_cast(k, data->implements_type)) { 761 return; 762 } 763 764 data->fn(k, data->opaque); 765 } 766 767 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), 768 const char *implements_type, bool include_abstract, 769 void *opaque) 770 { 771 OCFData data = { fn, implements_type, include_abstract, opaque }; 772 773 enumerating_types = true; 774 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); 775 enumerating_types = false; 776 } 777 778 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), 779 void *opaque) 780 { 781 ObjectProperty *prop, *next; 782 int ret = 0; 783 784 QTAILQ_FOREACH_SAFE(prop, &obj->properties, node, next) { 785 if (object_property_is_child(prop)) { 786 ret = fn(prop->opaque, opaque); 787 if (ret != 0) { 788 break; 789 } 790 } 791 } 792 return ret; 793 } 794 795 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque) 796 { 797 GSList **list = opaque; 798 799 *list = g_slist_prepend(*list, klass); 800 } 801 802 GSList *object_class_get_list(const char *implements_type, 803 bool include_abstract) 804 { 805 GSList *list = NULL; 806 807 object_class_foreach(object_class_get_list_tramp, 808 implements_type, include_abstract, &list); 809 return list; 810 } 811 812 void object_ref(Object *obj) 813 { 814 if (!obj) { 815 return; 816 } 817 atomic_inc(&obj->ref); 818 } 819 820 void object_unref(Object *obj) 821 { 822 if (!obj) { 823 return; 824 } 825 g_assert(obj->ref > 0); 826 827 /* parent always holds a reference to its children */ 828 if (atomic_fetch_dec(&obj->ref) == 1) { 829 object_finalize(obj); 830 } 831 } 832 833 ObjectProperty * 834 object_property_add(Object *obj, const char *name, const char *type, 835 ObjectPropertyAccessor *get, 836 ObjectPropertyAccessor *set, 837 ObjectPropertyRelease *release, 838 void *opaque, Error **errp) 839 { 840 ObjectProperty *prop; 841 size_t name_len = strlen(name); 842 843 if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) { 844 int i; 845 ObjectProperty *ret; 846 char *name_no_array = g_strdup(name); 847 848 name_no_array[name_len - 3] = '\0'; 849 for (i = 0; ; ++i) { 850 char *full_name = g_strdup_printf("%s[%d]", name_no_array, i); 851 852 ret = object_property_add(obj, full_name, type, get, set, 853 release, opaque, NULL); 854 g_free(full_name); 855 if (ret) { 856 break; 857 } 858 } 859 g_free(name_no_array); 860 return ret; 861 } 862 863 QTAILQ_FOREACH(prop, &obj->properties, node) { 864 if (strcmp(prop->name, name) == 0) { 865 error_setg(errp, "attempt to add duplicate property '%s'" 866 " to object (type '%s')", name, 867 object_get_typename(obj)); 868 return NULL; 869 } 870 } 871 872 prop = g_malloc0(sizeof(*prop)); 873 874 prop->name = g_strdup(name); 875 prop->type = g_strdup(type); 876 877 prop->get = get; 878 prop->set = set; 879 prop->release = release; 880 prop->opaque = opaque; 881 882 QTAILQ_INSERT_TAIL(&obj->properties, prop, node); 883 return prop; 884 } 885 886 ObjectProperty *object_property_find(Object *obj, const char *name, 887 Error **errp) 888 { 889 ObjectProperty *prop; 890 891 QTAILQ_FOREACH(prop, &obj->properties, node) { 892 if (strcmp(prop->name, name) == 0) { 893 return prop; 894 } 895 } 896 897 error_setg(errp, "Property '.%s' not found", name); 898 return NULL; 899 } 900 901 void object_property_del(Object *obj, const char *name, Error **errp) 902 { 903 ObjectProperty *prop = object_property_find(obj, name, errp); 904 if (prop == NULL) { 905 return; 906 } 907 908 if (prop->release) { 909 prop->release(obj, name, prop->opaque); 910 } 911 912 QTAILQ_REMOVE(&obj->properties, prop, node); 913 914 g_free(prop->name); 915 g_free(prop->type); 916 g_free(prop->description); 917 g_free(prop); 918 } 919 920 void object_property_get(Object *obj, Visitor *v, const char *name, 921 Error **errp) 922 { 923 ObjectProperty *prop = object_property_find(obj, name, errp); 924 if (prop == NULL) { 925 return; 926 } 927 928 if (!prop->get) { 929 error_set(errp, QERR_PERMISSION_DENIED); 930 } else { 931 prop->get(obj, v, prop->opaque, name, errp); 932 } 933 } 934 935 void object_property_set(Object *obj, Visitor *v, const char *name, 936 Error **errp) 937 { 938 ObjectProperty *prop = object_property_find(obj, name, errp); 939 if (prop == NULL) { 940 return; 941 } 942 943 if (!prop->set) { 944 error_set(errp, QERR_PERMISSION_DENIED); 945 } else { 946 prop->set(obj, v, prop->opaque, name, errp); 947 } 948 } 949 950 void object_property_set_str(Object *obj, const char *value, 951 const char *name, Error **errp) 952 { 953 QString *qstr = qstring_from_str(value); 954 object_property_set_qobject(obj, QOBJECT(qstr), name, errp); 955 956 QDECREF(qstr); 957 } 958 959 char *object_property_get_str(Object *obj, const char *name, 960 Error **errp) 961 { 962 QObject *ret = object_property_get_qobject(obj, name, errp); 963 QString *qstring; 964 char *retval; 965 966 if (!ret) { 967 return NULL; 968 } 969 qstring = qobject_to_qstring(ret); 970 if (!qstring) { 971 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 972 retval = NULL; 973 } else { 974 retval = g_strdup(qstring_get_str(qstring)); 975 } 976 977 QDECREF(qstring); 978 return retval; 979 } 980 981 void object_property_set_link(Object *obj, Object *value, 982 const char *name, Error **errp) 983 { 984 if (value) { 985 gchar *path = object_get_canonical_path(value); 986 object_property_set_str(obj, path, name, errp); 987 g_free(path); 988 } else { 989 object_property_set_str(obj, "", name, errp); 990 } 991 } 992 993 Object *object_property_get_link(Object *obj, const char *name, 994 Error **errp) 995 { 996 char *str = object_property_get_str(obj, name, errp); 997 Object *target = NULL; 998 999 if (str && *str) { 1000 target = object_resolve_path(str, NULL); 1001 if (!target) { 1002 error_set(errp, QERR_DEVICE_NOT_FOUND, str); 1003 } 1004 } 1005 1006 g_free(str); 1007 return target; 1008 } 1009 1010 void object_property_set_bool(Object *obj, bool value, 1011 const char *name, Error **errp) 1012 { 1013 QBool *qbool = qbool_from_bool(value); 1014 object_property_set_qobject(obj, QOBJECT(qbool), name, errp); 1015 1016 QDECREF(qbool); 1017 } 1018 1019 bool object_property_get_bool(Object *obj, const char *name, 1020 Error **errp) 1021 { 1022 QObject *ret = object_property_get_qobject(obj, name, errp); 1023 QBool *qbool; 1024 bool retval; 1025 1026 if (!ret) { 1027 return false; 1028 } 1029 qbool = qobject_to_qbool(ret); 1030 if (!qbool) { 1031 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 1032 retval = false; 1033 } else { 1034 retval = qbool_get_bool(qbool); 1035 } 1036 1037 QDECREF(qbool); 1038 return retval; 1039 } 1040 1041 void object_property_set_int(Object *obj, int64_t value, 1042 const char *name, Error **errp) 1043 { 1044 QInt *qint = qint_from_int(value); 1045 object_property_set_qobject(obj, QOBJECT(qint), name, errp); 1046 1047 QDECREF(qint); 1048 } 1049 1050 int64_t object_property_get_int(Object *obj, const char *name, 1051 Error **errp) 1052 { 1053 QObject *ret = object_property_get_qobject(obj, name, errp); 1054 QInt *qint; 1055 int64_t retval; 1056 1057 if (!ret) { 1058 return -1; 1059 } 1060 qint = qobject_to_qint(ret); 1061 if (!qint) { 1062 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 1063 retval = -1; 1064 } else { 1065 retval = qint_get_int(qint); 1066 } 1067 1068 QDECREF(qint); 1069 return retval; 1070 } 1071 1072 typedef struct EnumProperty { 1073 const char * const *strings; 1074 int (*get)(Object *, Error **); 1075 void (*set)(Object *, int, Error **); 1076 } EnumProperty; 1077 1078 int object_property_get_enum(Object *obj, const char *name, 1079 const char *typename, Error **errp) 1080 { 1081 StringOutputVisitor *sov; 1082 StringInputVisitor *siv; 1083 char *str; 1084 int ret; 1085 ObjectProperty *prop = object_property_find(obj, name, errp); 1086 EnumProperty *enumprop; 1087 1088 if (prop == NULL) { 1089 return 0; 1090 } 1091 1092 if (!g_str_equal(prop->type, typename)) { 1093 error_setg(errp, "Property %s on %s is not '%s' enum type", 1094 name, object_class_get_name( 1095 object_get_class(obj)), typename); 1096 return 0; 1097 } 1098 1099 enumprop = prop->opaque; 1100 1101 sov = string_output_visitor_new(false); 1102 object_property_get(obj, string_output_get_visitor(sov), name, errp); 1103 str = string_output_get_string(sov); 1104 siv = string_input_visitor_new(str); 1105 string_output_visitor_cleanup(sov); 1106 visit_type_enum(string_input_get_visitor(siv), 1107 &ret, enumprop->strings, NULL, name, errp); 1108 1109 g_free(str); 1110 string_input_visitor_cleanup(siv); 1111 1112 return ret; 1113 } 1114 1115 void object_property_get_uint16List(Object *obj, const char *name, 1116 uint16List **list, Error **errp) 1117 { 1118 StringOutputVisitor *ov; 1119 StringInputVisitor *iv; 1120 char *str; 1121 1122 ov = string_output_visitor_new(false); 1123 object_property_get(obj, string_output_get_visitor(ov), 1124 name, errp); 1125 str = string_output_get_string(ov); 1126 iv = string_input_visitor_new(str); 1127 visit_type_uint16List(string_input_get_visitor(iv), 1128 list, NULL, errp); 1129 1130 g_free(str); 1131 string_output_visitor_cleanup(ov); 1132 string_input_visitor_cleanup(iv); 1133 } 1134 1135 void object_property_parse(Object *obj, const char *string, 1136 const char *name, Error **errp) 1137 { 1138 StringInputVisitor *mi; 1139 mi = string_input_visitor_new(string); 1140 object_property_set(obj, string_input_get_visitor(mi), name, errp); 1141 1142 string_input_visitor_cleanup(mi); 1143 } 1144 1145 char *object_property_print(Object *obj, const char *name, bool human, 1146 Error **errp) 1147 { 1148 StringOutputVisitor *mo; 1149 char *string = NULL; 1150 Error *local_err = NULL; 1151 1152 mo = string_output_visitor_new(human); 1153 object_property_get(obj, string_output_get_visitor(mo), name, &local_err); 1154 if (local_err) { 1155 error_propagate(errp, local_err); 1156 goto out; 1157 } 1158 1159 string = string_output_get_string(mo); 1160 1161 out: 1162 string_output_visitor_cleanup(mo); 1163 return string; 1164 } 1165 1166 const char *object_property_get_type(Object *obj, const char *name, Error **errp) 1167 { 1168 ObjectProperty *prop = object_property_find(obj, name, errp); 1169 if (prop == NULL) { 1170 return NULL; 1171 } 1172 1173 return prop->type; 1174 } 1175 1176 Object *object_get_root(void) 1177 { 1178 static Object *root; 1179 1180 if (!root) { 1181 root = object_new("container"); 1182 } 1183 1184 return root; 1185 } 1186 1187 Object *object_get_objects_root(void) 1188 { 1189 return container_get(object_get_root(), "/objects"); 1190 } 1191 1192 static void object_get_child_property(Object *obj, Visitor *v, void *opaque, 1193 const char *name, Error **errp) 1194 { 1195 Object *child = opaque; 1196 gchar *path; 1197 1198 path = object_get_canonical_path(child); 1199 visit_type_str(v, &path, name, errp); 1200 g_free(path); 1201 } 1202 1203 static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part) 1204 { 1205 return opaque; 1206 } 1207 1208 static void object_finalize_child_property(Object *obj, const char *name, 1209 void *opaque) 1210 { 1211 Object *child = opaque; 1212 1213 if (child->class->unparent) { 1214 (child->class->unparent)(child); 1215 } 1216 child->parent = NULL; 1217 object_unref(child); 1218 } 1219 1220 void object_property_add_child(Object *obj, const char *name, 1221 Object *child, Error **errp) 1222 { 1223 Error *local_err = NULL; 1224 gchar *type; 1225 ObjectProperty *op; 1226 1227 if (child->parent != NULL) { 1228 error_setg(errp, "child object is already parented"); 1229 return; 1230 } 1231 1232 type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); 1233 1234 op = object_property_add(obj, name, type, object_get_child_property, NULL, 1235 object_finalize_child_property, child, &local_err); 1236 if (local_err) { 1237 error_propagate(errp, local_err); 1238 goto out; 1239 } 1240 1241 op->resolve = object_resolve_child_property; 1242 object_ref(child); 1243 child->parent = obj; 1244 1245 out: 1246 g_free(type); 1247 } 1248 1249 void object_property_allow_set_link(Object *obj, const char *name, 1250 Object *val, Error **errp) 1251 { 1252 /* Allow the link to be set, always */ 1253 } 1254 1255 typedef struct { 1256 Object **child; 1257 void (*check)(Object *, const char *, Object *, Error **); 1258 ObjectPropertyLinkFlags flags; 1259 } LinkProperty; 1260 1261 static void object_get_link_property(Object *obj, Visitor *v, void *opaque, 1262 const char *name, Error **errp) 1263 { 1264 LinkProperty *lprop = opaque; 1265 Object **child = lprop->child; 1266 gchar *path; 1267 1268 if (*child) { 1269 path = object_get_canonical_path(*child); 1270 visit_type_str(v, &path, name, errp); 1271 g_free(path); 1272 } else { 1273 path = (gchar *)""; 1274 visit_type_str(v, &path, name, errp); 1275 } 1276 } 1277 1278 /* 1279 * object_resolve_link: 1280 * 1281 * Lookup an object and ensure its type matches the link property type. This 1282 * is similar to object_resolve_path() except type verification against the 1283 * link property is performed. 1284 * 1285 * Returns: The matched object or NULL on path lookup failures. 1286 */ 1287 static Object *object_resolve_link(Object *obj, const char *name, 1288 const char *path, Error **errp) 1289 { 1290 const char *type; 1291 gchar *target_type; 1292 bool ambiguous = false; 1293 Object *target; 1294 1295 /* Go from link<FOO> to FOO. */ 1296 type = object_property_get_type(obj, name, NULL); 1297 target_type = g_strndup(&type[5], strlen(type) - 6); 1298 target = object_resolve_path_type(path, target_type, &ambiguous); 1299 1300 if (ambiguous) { 1301 error_set(errp, ERROR_CLASS_GENERIC_ERROR, 1302 "Path '%s' does not uniquely identify an object", path); 1303 } else if (!target) { 1304 target = object_resolve_path(path, &ambiguous); 1305 if (target || ambiguous) { 1306 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 1307 } else { 1308 error_set(errp, QERR_DEVICE_NOT_FOUND, path); 1309 } 1310 target = NULL; 1311 } 1312 g_free(target_type); 1313 1314 return target; 1315 } 1316 1317 static void object_set_link_property(Object *obj, Visitor *v, void *opaque, 1318 const char *name, Error **errp) 1319 { 1320 Error *local_err = NULL; 1321 LinkProperty *prop = opaque; 1322 Object **child = prop->child; 1323 Object *old_target = *child; 1324 Object *new_target = NULL; 1325 char *path = NULL; 1326 1327 visit_type_str(v, &path, name, &local_err); 1328 1329 if (!local_err && strcmp(path, "") != 0) { 1330 new_target = object_resolve_link(obj, name, path, &local_err); 1331 } 1332 1333 g_free(path); 1334 if (local_err) { 1335 error_propagate(errp, local_err); 1336 return; 1337 } 1338 1339 prop->check(obj, name, new_target, &local_err); 1340 if (local_err) { 1341 error_propagate(errp, local_err); 1342 return; 1343 } 1344 1345 object_ref(new_target); 1346 *child = new_target; 1347 object_unref(old_target); 1348 } 1349 1350 static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part) 1351 { 1352 LinkProperty *lprop = opaque; 1353 1354 return *lprop->child; 1355 } 1356 1357 static void object_release_link_property(Object *obj, const char *name, 1358 void *opaque) 1359 { 1360 LinkProperty *prop = opaque; 1361 1362 if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) { 1363 object_unref(*prop->child); 1364 } 1365 g_free(prop); 1366 } 1367 1368 void object_property_add_link(Object *obj, const char *name, 1369 const char *type, Object **child, 1370 void (*check)(Object *, const char *, 1371 Object *, Error **), 1372 ObjectPropertyLinkFlags flags, 1373 Error **errp) 1374 { 1375 Error *local_err = NULL; 1376 LinkProperty *prop = g_malloc(sizeof(*prop)); 1377 gchar *full_type; 1378 ObjectProperty *op; 1379 1380 prop->child = child; 1381 prop->check = check; 1382 prop->flags = flags; 1383 1384 full_type = g_strdup_printf("link<%s>", type); 1385 1386 op = object_property_add(obj, name, full_type, 1387 object_get_link_property, 1388 check ? object_set_link_property : NULL, 1389 object_release_link_property, 1390 prop, 1391 &local_err); 1392 if (local_err) { 1393 error_propagate(errp, local_err); 1394 g_free(prop); 1395 goto out; 1396 } 1397 1398 op->resolve = object_resolve_link_property; 1399 1400 out: 1401 g_free(full_type); 1402 } 1403 1404 void object_property_add_const_link(Object *obj, const char *name, 1405 Object *target, Error **errp) 1406 { 1407 char *link_type; 1408 ObjectProperty *op; 1409 1410 link_type = g_strdup_printf("link<%s>", object_get_typename(target)); 1411 op = object_property_add(obj, name, link_type, 1412 object_get_child_property, NULL, 1413 NULL, target, errp); 1414 if (op != NULL) { 1415 op->resolve = object_resolve_child_property; 1416 } 1417 g_free(link_type); 1418 } 1419 1420 gchar *object_get_canonical_path_component(Object *obj) 1421 { 1422 ObjectProperty *prop = NULL; 1423 1424 g_assert(obj); 1425 g_assert(obj->parent != NULL); 1426 1427 QTAILQ_FOREACH(prop, &obj->parent->properties, node) { 1428 if (!object_property_is_child(prop)) { 1429 continue; 1430 } 1431 1432 if (prop->opaque == obj) { 1433 return g_strdup(prop->name); 1434 } 1435 } 1436 1437 /* obj had a parent but was not a child, should never happen */ 1438 g_assert_not_reached(); 1439 return NULL; 1440 } 1441 1442 gchar *object_get_canonical_path(Object *obj) 1443 { 1444 Object *root = object_get_root(); 1445 char *newpath, *path = NULL; 1446 1447 while (obj != root) { 1448 char *component = object_get_canonical_path_component(obj); 1449 1450 if (path) { 1451 newpath = g_strdup_printf("%s/%s", component, path); 1452 g_free(component); 1453 g_free(path); 1454 path = newpath; 1455 } else { 1456 path = component; 1457 } 1458 1459 obj = obj->parent; 1460 } 1461 1462 newpath = g_strdup_printf("/%s", path ? path : ""); 1463 g_free(path); 1464 1465 return newpath; 1466 } 1467 1468 Object *object_resolve_path_component(Object *parent, const gchar *part) 1469 { 1470 ObjectProperty *prop = object_property_find(parent, part, NULL); 1471 if (prop == NULL) { 1472 return NULL; 1473 } 1474 1475 if (prop->resolve) { 1476 return prop->resolve(parent, prop->opaque, part); 1477 } else { 1478 return NULL; 1479 } 1480 } 1481 1482 static Object *object_resolve_abs_path(Object *parent, 1483 gchar **parts, 1484 const char *typename, 1485 int index) 1486 { 1487 Object *child; 1488 1489 if (parts[index] == NULL) { 1490 return object_dynamic_cast(parent, typename); 1491 } 1492 1493 if (strcmp(parts[index], "") == 0) { 1494 return object_resolve_abs_path(parent, parts, typename, index + 1); 1495 } 1496 1497 child = object_resolve_path_component(parent, parts[index]); 1498 if (!child) { 1499 return NULL; 1500 } 1501 1502 return object_resolve_abs_path(child, parts, typename, index + 1); 1503 } 1504 1505 static Object *object_resolve_partial_path(Object *parent, 1506 gchar **parts, 1507 const char *typename, 1508 bool *ambiguous) 1509 { 1510 Object *obj; 1511 ObjectProperty *prop; 1512 1513 obj = object_resolve_abs_path(parent, parts, typename, 0); 1514 1515 QTAILQ_FOREACH(prop, &parent->properties, node) { 1516 Object *found; 1517 1518 if (!object_property_is_child(prop)) { 1519 continue; 1520 } 1521 1522 found = object_resolve_partial_path(prop->opaque, parts, 1523 typename, ambiguous); 1524 if (found) { 1525 if (obj) { 1526 if (ambiguous) { 1527 *ambiguous = true; 1528 } 1529 return NULL; 1530 } 1531 obj = found; 1532 } 1533 1534 if (ambiguous && *ambiguous) { 1535 return NULL; 1536 } 1537 } 1538 1539 return obj; 1540 } 1541 1542 Object *object_resolve_path_type(const char *path, const char *typename, 1543 bool *ambiguous) 1544 { 1545 Object *obj; 1546 gchar **parts; 1547 1548 parts = g_strsplit(path, "/", 0); 1549 assert(parts); 1550 1551 if (parts[0] == NULL || strcmp(parts[0], "") != 0) { 1552 if (ambiguous) { 1553 *ambiguous = false; 1554 } 1555 obj = object_resolve_partial_path(object_get_root(), parts, 1556 typename, ambiguous); 1557 } else { 1558 obj = object_resolve_abs_path(object_get_root(), parts, typename, 1); 1559 } 1560 1561 g_strfreev(parts); 1562 1563 return obj; 1564 } 1565 1566 Object *object_resolve_path(const char *path, bool *ambiguous) 1567 { 1568 return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 1569 } 1570 1571 typedef struct StringProperty 1572 { 1573 char *(*get)(Object *, Error **); 1574 void (*set)(Object *, const char *, Error **); 1575 } StringProperty; 1576 1577 static void property_get_str(Object *obj, Visitor *v, void *opaque, 1578 const char *name, Error **errp) 1579 { 1580 StringProperty *prop = opaque; 1581 char *value; 1582 1583 value = prop->get(obj, errp); 1584 if (value) { 1585 visit_type_str(v, &value, name, errp); 1586 g_free(value); 1587 } 1588 } 1589 1590 static void property_set_str(Object *obj, Visitor *v, void *opaque, 1591 const char *name, Error **errp) 1592 { 1593 StringProperty *prop = opaque; 1594 char *value; 1595 Error *local_err = NULL; 1596 1597 visit_type_str(v, &value, name, &local_err); 1598 if (local_err) { 1599 error_propagate(errp, local_err); 1600 return; 1601 } 1602 1603 prop->set(obj, value, errp); 1604 g_free(value); 1605 } 1606 1607 static void property_release_str(Object *obj, const char *name, 1608 void *opaque) 1609 { 1610 StringProperty *prop = opaque; 1611 g_free(prop); 1612 } 1613 1614 void object_property_add_str(Object *obj, const char *name, 1615 char *(*get)(Object *, Error **), 1616 void (*set)(Object *, const char *, Error **), 1617 Error **errp) 1618 { 1619 Error *local_err = NULL; 1620 StringProperty *prop = g_malloc0(sizeof(*prop)); 1621 1622 prop->get = get; 1623 prop->set = set; 1624 1625 object_property_add(obj, name, "string", 1626 get ? property_get_str : NULL, 1627 set ? property_set_str : NULL, 1628 property_release_str, 1629 prop, &local_err); 1630 if (local_err) { 1631 error_propagate(errp, local_err); 1632 g_free(prop); 1633 } 1634 } 1635 1636 typedef struct BoolProperty 1637 { 1638 bool (*get)(Object *, Error **); 1639 void (*set)(Object *, bool, Error **); 1640 } BoolProperty; 1641 1642 static void property_get_bool(Object *obj, Visitor *v, void *opaque, 1643 const char *name, Error **errp) 1644 { 1645 BoolProperty *prop = opaque; 1646 bool value; 1647 1648 value = prop->get(obj, errp); 1649 visit_type_bool(v, &value, name, errp); 1650 } 1651 1652 static void property_set_bool(Object *obj, Visitor *v, void *opaque, 1653 const char *name, Error **errp) 1654 { 1655 BoolProperty *prop = opaque; 1656 bool value; 1657 Error *local_err = NULL; 1658 1659 visit_type_bool(v, &value, name, &local_err); 1660 if (local_err) { 1661 error_propagate(errp, local_err); 1662 return; 1663 } 1664 1665 prop->set(obj, value, errp); 1666 } 1667 1668 static void property_release_bool(Object *obj, const char *name, 1669 void *opaque) 1670 { 1671 BoolProperty *prop = opaque; 1672 g_free(prop); 1673 } 1674 1675 void object_property_add_bool(Object *obj, const char *name, 1676 bool (*get)(Object *, Error **), 1677 void (*set)(Object *, bool, Error **), 1678 Error **errp) 1679 { 1680 Error *local_err = NULL; 1681 BoolProperty *prop = g_malloc0(sizeof(*prop)); 1682 1683 prop->get = get; 1684 prop->set = set; 1685 1686 object_property_add(obj, name, "bool", 1687 get ? property_get_bool : NULL, 1688 set ? property_set_bool : NULL, 1689 property_release_bool, 1690 prop, &local_err); 1691 if (local_err) { 1692 error_propagate(errp, local_err); 1693 g_free(prop); 1694 } 1695 } 1696 1697 static void property_get_enum(Object *obj, Visitor *v, void *opaque, 1698 const char *name, Error **errp) 1699 { 1700 EnumProperty *prop = opaque; 1701 int value; 1702 1703 value = prop->get(obj, errp); 1704 visit_type_enum(v, &value, prop->strings, NULL, name, errp); 1705 } 1706 1707 static void property_set_enum(Object *obj, Visitor *v, void *opaque, 1708 const char *name, Error **errp) 1709 { 1710 EnumProperty *prop = opaque; 1711 int value; 1712 1713 visit_type_enum(v, &value, prop->strings, NULL, name, errp); 1714 prop->set(obj, value, errp); 1715 } 1716 1717 static void property_release_enum(Object *obj, const char *name, 1718 void *opaque) 1719 { 1720 EnumProperty *prop = opaque; 1721 g_free(prop); 1722 } 1723 1724 void object_property_add_enum(Object *obj, const char *name, 1725 const char *typename, 1726 const char * const *strings, 1727 int (*get)(Object *, Error **), 1728 void (*set)(Object *, int, Error **), 1729 Error **errp) 1730 { 1731 Error *local_err = NULL; 1732 EnumProperty *prop = g_malloc(sizeof(*prop)); 1733 1734 prop->strings = strings; 1735 prop->get = get; 1736 prop->set = set; 1737 1738 object_property_add(obj, name, typename, 1739 get ? property_get_enum : NULL, 1740 set ? property_set_enum : NULL, 1741 property_release_enum, 1742 prop, &local_err); 1743 if (local_err) { 1744 error_propagate(errp, local_err); 1745 g_free(prop); 1746 } 1747 } 1748 1749 typedef struct TMProperty { 1750 void (*get)(Object *, struct tm *, Error **); 1751 } TMProperty; 1752 1753 static void property_get_tm(Object *obj, Visitor *v, void *opaque, 1754 const char *name, Error **errp) 1755 { 1756 TMProperty *prop = opaque; 1757 Error *err = NULL; 1758 struct tm value; 1759 1760 prop->get(obj, &value, &err); 1761 if (err) { 1762 goto out; 1763 } 1764 1765 visit_start_struct(v, NULL, "struct tm", name, 0, &err); 1766 if (err) { 1767 goto out; 1768 } 1769 visit_type_int32(v, &value.tm_year, "tm_year", &err); 1770 if (err) { 1771 goto out_end; 1772 } 1773 visit_type_int32(v, &value.tm_mon, "tm_mon", &err); 1774 if (err) { 1775 goto out_end; 1776 } 1777 visit_type_int32(v, &value.tm_mday, "tm_mday", &err); 1778 if (err) { 1779 goto out_end; 1780 } 1781 visit_type_int32(v, &value.tm_hour, "tm_hour", &err); 1782 if (err) { 1783 goto out_end; 1784 } 1785 visit_type_int32(v, &value.tm_min, "tm_min", &err); 1786 if (err) { 1787 goto out_end; 1788 } 1789 visit_type_int32(v, &value.tm_sec, "tm_sec", &err); 1790 if (err) { 1791 goto out_end; 1792 } 1793 out_end: 1794 error_propagate(errp, err); 1795 err = NULL; 1796 visit_end_struct(v, errp); 1797 out: 1798 error_propagate(errp, err); 1799 1800 } 1801 1802 static void property_release_tm(Object *obj, const char *name, 1803 void *opaque) 1804 { 1805 TMProperty *prop = opaque; 1806 g_free(prop); 1807 } 1808 1809 void object_property_add_tm(Object *obj, const char *name, 1810 void (*get)(Object *, struct tm *, Error **), 1811 Error **errp) 1812 { 1813 Error *local_err = NULL; 1814 TMProperty *prop = g_malloc0(sizeof(*prop)); 1815 1816 prop->get = get; 1817 1818 object_property_add(obj, name, "struct tm", 1819 get ? property_get_tm : NULL, NULL, 1820 property_release_tm, 1821 prop, &local_err); 1822 if (local_err) { 1823 error_propagate(errp, local_err); 1824 g_free(prop); 1825 } 1826 } 1827 1828 static char *qdev_get_type(Object *obj, Error **errp) 1829 { 1830 return g_strdup(object_get_typename(obj)); 1831 } 1832 1833 static void property_get_uint8_ptr(Object *obj, Visitor *v, 1834 void *opaque, const char *name, 1835 Error **errp) 1836 { 1837 uint8_t value = *(uint8_t *)opaque; 1838 visit_type_uint8(v, &value, name, errp); 1839 } 1840 1841 static void property_get_uint16_ptr(Object *obj, Visitor *v, 1842 void *opaque, const char *name, 1843 Error **errp) 1844 { 1845 uint16_t value = *(uint16_t *)opaque; 1846 visit_type_uint16(v, &value, name, errp); 1847 } 1848 1849 static void property_get_uint32_ptr(Object *obj, Visitor *v, 1850 void *opaque, const char *name, 1851 Error **errp) 1852 { 1853 uint32_t value = *(uint32_t *)opaque; 1854 visit_type_uint32(v, &value, name, errp); 1855 } 1856 1857 static void property_get_uint64_ptr(Object *obj, Visitor *v, 1858 void *opaque, const char *name, 1859 Error **errp) 1860 { 1861 uint64_t value = *(uint64_t *)opaque; 1862 visit_type_uint64(v, &value, name, errp); 1863 } 1864 1865 void object_property_add_uint8_ptr(Object *obj, const char *name, 1866 const uint8_t *v, Error **errp) 1867 { 1868 object_property_add(obj, name, "uint8", property_get_uint8_ptr, 1869 NULL, NULL, (void *)v, errp); 1870 } 1871 1872 void object_property_add_uint16_ptr(Object *obj, const char *name, 1873 const uint16_t *v, Error **errp) 1874 { 1875 object_property_add(obj, name, "uint16", property_get_uint16_ptr, 1876 NULL, NULL, (void *)v, errp); 1877 } 1878 1879 void object_property_add_uint32_ptr(Object *obj, const char *name, 1880 const uint32_t *v, Error **errp) 1881 { 1882 object_property_add(obj, name, "uint32", property_get_uint32_ptr, 1883 NULL, NULL, (void *)v, errp); 1884 } 1885 1886 void object_property_add_uint64_ptr(Object *obj, const char *name, 1887 const uint64_t *v, Error **errp) 1888 { 1889 object_property_add(obj, name, "uint64", property_get_uint64_ptr, 1890 NULL, NULL, (void *)v, errp); 1891 } 1892 1893 typedef struct { 1894 Object *target_obj; 1895 char *target_name; 1896 } AliasProperty; 1897 1898 static void property_get_alias(Object *obj, struct Visitor *v, void *opaque, 1899 const char *name, Error **errp) 1900 { 1901 AliasProperty *prop = opaque; 1902 1903 object_property_get(prop->target_obj, v, prop->target_name, errp); 1904 } 1905 1906 static void property_set_alias(Object *obj, struct Visitor *v, void *opaque, 1907 const char *name, Error **errp) 1908 { 1909 AliasProperty *prop = opaque; 1910 1911 object_property_set(prop->target_obj, v, prop->target_name, errp); 1912 } 1913 1914 static Object *property_resolve_alias(Object *obj, void *opaque, 1915 const gchar *part) 1916 { 1917 AliasProperty *prop = opaque; 1918 1919 return object_resolve_path_component(prop->target_obj, prop->target_name); 1920 } 1921 1922 static void property_release_alias(Object *obj, const char *name, void *opaque) 1923 { 1924 AliasProperty *prop = opaque; 1925 1926 g_free(prop->target_name); 1927 g_free(prop); 1928 } 1929 1930 void object_property_add_alias(Object *obj, const char *name, 1931 Object *target_obj, const char *target_name, 1932 Error **errp) 1933 { 1934 AliasProperty *prop; 1935 ObjectProperty *op; 1936 ObjectProperty *target_prop; 1937 gchar *prop_type; 1938 Error *local_err = NULL; 1939 1940 target_prop = object_property_find(target_obj, target_name, errp); 1941 if (!target_prop) { 1942 return; 1943 } 1944 1945 if (object_property_is_child(target_prop)) { 1946 prop_type = g_strdup_printf("link%s", 1947 target_prop->type + strlen("child")); 1948 } else { 1949 prop_type = g_strdup(target_prop->type); 1950 } 1951 1952 prop = g_malloc(sizeof(*prop)); 1953 prop->target_obj = target_obj; 1954 prop->target_name = g_strdup(target_name); 1955 1956 op = object_property_add(obj, name, prop_type, 1957 property_get_alias, 1958 property_set_alias, 1959 property_release_alias, 1960 prop, &local_err); 1961 if (local_err) { 1962 error_propagate(errp, local_err); 1963 g_free(prop); 1964 goto out; 1965 } 1966 op->resolve = property_resolve_alias; 1967 1968 object_property_set_description(obj, op->name, 1969 target_prop->description, 1970 &error_abort); 1971 1972 out: 1973 g_free(prop_type); 1974 } 1975 1976 void object_property_set_description(Object *obj, const char *name, 1977 const char *description, Error **errp) 1978 { 1979 ObjectProperty *op; 1980 1981 op = object_property_find(obj, name, errp); 1982 if (!op) { 1983 return; 1984 } 1985 1986 g_free(op->description); 1987 op->description = g_strdup(description); 1988 } 1989 1990 static void object_instance_init(Object *obj) 1991 { 1992 object_property_add_str(obj, "type", qdev_get_type, NULL, NULL); 1993 } 1994 1995 static void register_types(void) 1996 { 1997 static TypeInfo interface_info = { 1998 .name = TYPE_INTERFACE, 1999 .class_size = sizeof(InterfaceClass), 2000 .abstract = true, 2001 }; 2002 2003 static TypeInfo object_info = { 2004 .name = TYPE_OBJECT, 2005 .instance_size = sizeof(Object), 2006 .instance_init = object_instance_init, 2007 .abstract = true, 2008 }; 2009 2010 type_interface = type_register_internal(&interface_info); 2011 type_register_internal(&object_info); 2012 } 2013 2014 type_init(register_types) 2015