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 static int do_object_child_foreach(Object *obj, 779 int (*fn)(Object *child, void *opaque), 780 void *opaque, bool recurse) 781 { 782 ObjectProperty *prop, *next; 783 int ret = 0; 784 785 QTAILQ_FOREACH_SAFE(prop, &obj->properties, node, next) { 786 if (object_property_is_child(prop)) { 787 Object *child = prop->opaque; 788 789 ret = fn(child, opaque); 790 if (ret != 0) { 791 break; 792 } 793 if (recurse) { 794 do_object_child_foreach(child, fn, opaque, true); 795 } 796 } 797 } 798 return ret; 799 } 800 801 int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), 802 void *opaque) 803 { 804 return do_object_child_foreach(obj, fn, opaque, false); 805 } 806 807 int object_child_foreach_recursive(Object *obj, 808 int (*fn)(Object *child, void *opaque), 809 void *opaque) 810 { 811 return do_object_child_foreach(obj, fn, opaque, true); 812 } 813 814 static void object_class_get_list_tramp(ObjectClass *klass, void *opaque) 815 { 816 GSList **list = opaque; 817 818 *list = g_slist_prepend(*list, klass); 819 } 820 821 GSList *object_class_get_list(const char *implements_type, 822 bool include_abstract) 823 { 824 GSList *list = NULL; 825 826 object_class_foreach(object_class_get_list_tramp, 827 implements_type, include_abstract, &list); 828 return list; 829 } 830 831 void object_ref(Object *obj) 832 { 833 if (!obj) { 834 return; 835 } 836 atomic_inc(&obj->ref); 837 } 838 839 void object_unref(Object *obj) 840 { 841 if (!obj) { 842 return; 843 } 844 g_assert(obj->ref > 0); 845 846 /* parent always holds a reference to its children */ 847 if (atomic_fetch_dec(&obj->ref) == 1) { 848 object_finalize(obj); 849 } 850 } 851 852 ObjectProperty * 853 object_property_add(Object *obj, const char *name, const char *type, 854 ObjectPropertyAccessor *get, 855 ObjectPropertyAccessor *set, 856 ObjectPropertyRelease *release, 857 void *opaque, Error **errp) 858 { 859 ObjectProperty *prop; 860 size_t name_len = strlen(name); 861 862 if (name_len >= 3 && !memcmp(name + name_len - 3, "[*]", 4)) { 863 int i; 864 ObjectProperty *ret; 865 char *name_no_array = g_strdup(name); 866 867 name_no_array[name_len - 3] = '\0'; 868 for (i = 0; ; ++i) { 869 char *full_name = g_strdup_printf("%s[%d]", name_no_array, i); 870 871 ret = object_property_add(obj, full_name, type, get, set, 872 release, opaque, NULL); 873 g_free(full_name); 874 if (ret) { 875 break; 876 } 877 } 878 g_free(name_no_array); 879 return ret; 880 } 881 882 QTAILQ_FOREACH(prop, &obj->properties, node) { 883 if (strcmp(prop->name, name) == 0) { 884 error_setg(errp, "attempt to add duplicate property '%s'" 885 " to object (type '%s')", name, 886 object_get_typename(obj)); 887 return NULL; 888 } 889 } 890 891 prop = g_malloc0(sizeof(*prop)); 892 893 prop->name = g_strdup(name); 894 prop->type = g_strdup(type); 895 896 prop->get = get; 897 prop->set = set; 898 prop->release = release; 899 prop->opaque = opaque; 900 901 QTAILQ_INSERT_TAIL(&obj->properties, prop, node); 902 return prop; 903 } 904 905 ObjectProperty *object_property_find(Object *obj, const char *name, 906 Error **errp) 907 { 908 ObjectProperty *prop; 909 910 QTAILQ_FOREACH(prop, &obj->properties, node) { 911 if (strcmp(prop->name, name) == 0) { 912 return prop; 913 } 914 } 915 916 error_setg(errp, "Property '.%s' not found", name); 917 return NULL; 918 } 919 920 void object_property_del(Object *obj, const char *name, Error **errp) 921 { 922 ObjectProperty *prop = object_property_find(obj, name, errp); 923 if (prop == NULL) { 924 return; 925 } 926 927 if (prop->release) { 928 prop->release(obj, name, prop->opaque); 929 } 930 931 QTAILQ_REMOVE(&obj->properties, prop, node); 932 933 g_free(prop->name); 934 g_free(prop->type); 935 g_free(prop->description); 936 g_free(prop); 937 } 938 939 void object_property_get(Object *obj, Visitor *v, const char *name, 940 Error **errp) 941 { 942 ObjectProperty *prop = object_property_find(obj, name, errp); 943 if (prop == NULL) { 944 return; 945 } 946 947 if (!prop->get) { 948 error_setg(errp, QERR_PERMISSION_DENIED); 949 } else { 950 prop->get(obj, v, prop->opaque, name, errp); 951 } 952 } 953 954 void object_property_set(Object *obj, Visitor *v, const char *name, 955 Error **errp) 956 { 957 ObjectProperty *prop = object_property_find(obj, name, errp); 958 if (prop == NULL) { 959 return; 960 } 961 962 if (!prop->set) { 963 error_setg(errp, QERR_PERMISSION_DENIED); 964 } else { 965 prop->set(obj, v, prop->opaque, name, errp); 966 } 967 } 968 969 void object_property_set_str(Object *obj, const char *value, 970 const char *name, Error **errp) 971 { 972 QString *qstr = qstring_from_str(value); 973 object_property_set_qobject(obj, QOBJECT(qstr), name, errp); 974 975 QDECREF(qstr); 976 } 977 978 char *object_property_get_str(Object *obj, const char *name, 979 Error **errp) 980 { 981 QObject *ret = object_property_get_qobject(obj, name, errp); 982 QString *qstring; 983 char *retval; 984 985 if (!ret) { 986 return NULL; 987 } 988 qstring = qobject_to_qstring(ret); 989 if (!qstring) { 990 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string"); 991 retval = NULL; 992 } else { 993 retval = g_strdup(qstring_get_str(qstring)); 994 } 995 996 QDECREF(qstring); 997 return retval; 998 } 999 1000 void object_property_set_link(Object *obj, Object *value, 1001 const char *name, Error **errp) 1002 { 1003 if (value) { 1004 gchar *path = object_get_canonical_path(value); 1005 object_property_set_str(obj, path, name, errp); 1006 g_free(path); 1007 } else { 1008 object_property_set_str(obj, "", name, errp); 1009 } 1010 } 1011 1012 Object *object_property_get_link(Object *obj, const char *name, 1013 Error **errp) 1014 { 1015 char *str = object_property_get_str(obj, name, errp); 1016 Object *target = NULL; 1017 1018 if (str && *str) { 1019 target = object_resolve_path(str, NULL); 1020 if (!target) { 1021 error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, 1022 "Device '%s' not found", str); 1023 } 1024 } 1025 1026 g_free(str); 1027 return target; 1028 } 1029 1030 void object_property_set_bool(Object *obj, bool value, 1031 const char *name, Error **errp) 1032 { 1033 QBool *qbool = qbool_from_bool(value); 1034 object_property_set_qobject(obj, QOBJECT(qbool), name, errp); 1035 1036 QDECREF(qbool); 1037 } 1038 1039 bool object_property_get_bool(Object *obj, const char *name, 1040 Error **errp) 1041 { 1042 QObject *ret = object_property_get_qobject(obj, name, errp); 1043 QBool *qbool; 1044 bool retval; 1045 1046 if (!ret) { 1047 return false; 1048 } 1049 qbool = qobject_to_qbool(ret); 1050 if (!qbool) { 1051 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); 1052 retval = false; 1053 } else { 1054 retval = qbool_get_bool(qbool); 1055 } 1056 1057 QDECREF(qbool); 1058 return retval; 1059 } 1060 1061 void object_property_set_int(Object *obj, int64_t value, 1062 const char *name, Error **errp) 1063 { 1064 QInt *qint = qint_from_int(value); 1065 object_property_set_qobject(obj, QOBJECT(qint), name, errp); 1066 1067 QDECREF(qint); 1068 } 1069 1070 int64_t object_property_get_int(Object *obj, const char *name, 1071 Error **errp) 1072 { 1073 QObject *ret = object_property_get_qobject(obj, name, errp); 1074 QInt *qint; 1075 int64_t retval; 1076 1077 if (!ret) { 1078 return -1; 1079 } 1080 qint = qobject_to_qint(ret); 1081 if (!qint) { 1082 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); 1083 retval = -1; 1084 } else { 1085 retval = qint_get_int(qint); 1086 } 1087 1088 QDECREF(qint); 1089 return retval; 1090 } 1091 1092 typedef struct EnumProperty { 1093 const char * const *strings; 1094 int (*get)(Object *, Error **); 1095 void (*set)(Object *, int, Error **); 1096 } EnumProperty; 1097 1098 int object_property_get_enum(Object *obj, const char *name, 1099 const char *typename, Error **errp) 1100 { 1101 StringOutputVisitor *sov; 1102 StringInputVisitor *siv; 1103 char *str; 1104 int ret; 1105 ObjectProperty *prop = object_property_find(obj, name, errp); 1106 EnumProperty *enumprop; 1107 1108 if (prop == NULL) { 1109 return 0; 1110 } 1111 1112 if (!g_str_equal(prop->type, typename)) { 1113 error_setg(errp, "Property %s on %s is not '%s' enum type", 1114 name, object_class_get_name( 1115 object_get_class(obj)), typename); 1116 return 0; 1117 } 1118 1119 enumprop = prop->opaque; 1120 1121 sov = string_output_visitor_new(false); 1122 object_property_get(obj, string_output_get_visitor(sov), name, errp); 1123 str = string_output_get_string(sov); 1124 siv = string_input_visitor_new(str); 1125 string_output_visitor_cleanup(sov); 1126 visit_type_enum(string_input_get_visitor(siv), 1127 &ret, enumprop->strings, NULL, name, errp); 1128 1129 g_free(str); 1130 string_input_visitor_cleanup(siv); 1131 1132 return ret; 1133 } 1134 1135 void object_property_get_uint16List(Object *obj, const char *name, 1136 uint16List **list, Error **errp) 1137 { 1138 StringOutputVisitor *ov; 1139 StringInputVisitor *iv; 1140 char *str; 1141 1142 ov = string_output_visitor_new(false); 1143 object_property_get(obj, string_output_get_visitor(ov), 1144 name, errp); 1145 str = string_output_get_string(ov); 1146 iv = string_input_visitor_new(str); 1147 visit_type_uint16List(string_input_get_visitor(iv), 1148 list, NULL, errp); 1149 1150 g_free(str); 1151 string_output_visitor_cleanup(ov); 1152 string_input_visitor_cleanup(iv); 1153 } 1154 1155 void object_property_parse(Object *obj, const char *string, 1156 const char *name, Error **errp) 1157 { 1158 StringInputVisitor *mi; 1159 mi = string_input_visitor_new(string); 1160 object_property_set(obj, string_input_get_visitor(mi), name, errp); 1161 1162 string_input_visitor_cleanup(mi); 1163 } 1164 1165 char *object_property_print(Object *obj, const char *name, bool human, 1166 Error **errp) 1167 { 1168 StringOutputVisitor *mo; 1169 char *string = NULL; 1170 Error *local_err = NULL; 1171 1172 mo = string_output_visitor_new(human); 1173 object_property_get(obj, string_output_get_visitor(mo), name, &local_err); 1174 if (local_err) { 1175 error_propagate(errp, local_err); 1176 goto out; 1177 } 1178 1179 string = string_output_get_string(mo); 1180 1181 out: 1182 string_output_visitor_cleanup(mo); 1183 return string; 1184 } 1185 1186 const char *object_property_get_type(Object *obj, const char *name, Error **errp) 1187 { 1188 ObjectProperty *prop = object_property_find(obj, name, errp); 1189 if (prop == NULL) { 1190 return NULL; 1191 } 1192 1193 return prop->type; 1194 } 1195 1196 Object *object_get_root(void) 1197 { 1198 static Object *root; 1199 1200 if (!root) { 1201 root = object_new("container"); 1202 } 1203 1204 return root; 1205 } 1206 1207 Object *object_get_objects_root(void) 1208 { 1209 return container_get(object_get_root(), "/objects"); 1210 } 1211 1212 static void object_get_child_property(Object *obj, Visitor *v, void *opaque, 1213 const char *name, Error **errp) 1214 { 1215 Object *child = opaque; 1216 gchar *path; 1217 1218 path = object_get_canonical_path(child); 1219 visit_type_str(v, &path, name, errp); 1220 g_free(path); 1221 } 1222 1223 static Object *object_resolve_child_property(Object *parent, void *opaque, const gchar *part) 1224 { 1225 return opaque; 1226 } 1227 1228 static void object_finalize_child_property(Object *obj, const char *name, 1229 void *opaque) 1230 { 1231 Object *child = opaque; 1232 1233 if (child->class->unparent) { 1234 (child->class->unparent)(child); 1235 } 1236 child->parent = NULL; 1237 object_unref(child); 1238 } 1239 1240 void object_property_add_child(Object *obj, const char *name, 1241 Object *child, Error **errp) 1242 { 1243 Error *local_err = NULL; 1244 gchar *type; 1245 ObjectProperty *op; 1246 1247 if (child->parent != NULL) { 1248 error_setg(errp, "child object is already parented"); 1249 return; 1250 } 1251 1252 type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); 1253 1254 op = object_property_add(obj, name, type, object_get_child_property, NULL, 1255 object_finalize_child_property, child, &local_err); 1256 if (local_err) { 1257 error_propagate(errp, local_err); 1258 goto out; 1259 } 1260 1261 op->resolve = object_resolve_child_property; 1262 object_ref(child); 1263 child->parent = obj; 1264 1265 out: 1266 g_free(type); 1267 } 1268 1269 void object_property_allow_set_link(Object *obj, const char *name, 1270 Object *val, Error **errp) 1271 { 1272 /* Allow the link to be set, always */ 1273 } 1274 1275 typedef struct { 1276 Object **child; 1277 void (*check)(Object *, const char *, Object *, Error **); 1278 ObjectPropertyLinkFlags flags; 1279 } LinkProperty; 1280 1281 static void object_get_link_property(Object *obj, Visitor *v, void *opaque, 1282 const char *name, Error **errp) 1283 { 1284 LinkProperty *lprop = opaque; 1285 Object **child = lprop->child; 1286 gchar *path; 1287 1288 if (*child) { 1289 path = object_get_canonical_path(*child); 1290 visit_type_str(v, &path, name, errp); 1291 g_free(path); 1292 } else { 1293 path = (gchar *)""; 1294 visit_type_str(v, &path, name, errp); 1295 } 1296 } 1297 1298 /* 1299 * object_resolve_link: 1300 * 1301 * Lookup an object and ensure its type matches the link property type. This 1302 * is similar to object_resolve_path() except type verification against the 1303 * link property is performed. 1304 * 1305 * Returns: The matched object or NULL on path lookup failures. 1306 */ 1307 static Object *object_resolve_link(Object *obj, const char *name, 1308 const char *path, Error **errp) 1309 { 1310 const char *type; 1311 gchar *target_type; 1312 bool ambiguous = false; 1313 Object *target; 1314 1315 /* Go from link<FOO> to FOO. */ 1316 type = object_property_get_type(obj, name, NULL); 1317 target_type = g_strndup(&type[5], strlen(type) - 6); 1318 target = object_resolve_path_type(path, target_type, &ambiguous); 1319 1320 if (ambiguous) { 1321 error_set(errp, ERROR_CLASS_GENERIC_ERROR, 1322 "Path '%s' does not uniquely identify an object", path); 1323 } else if (!target) { 1324 target = object_resolve_path(path, &ambiguous); 1325 if (target || ambiguous) { 1326 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type); 1327 } else { 1328 error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, 1329 "Device '%s' not found", path); 1330 } 1331 target = NULL; 1332 } 1333 g_free(target_type); 1334 1335 return target; 1336 } 1337 1338 static void object_set_link_property(Object *obj, Visitor *v, void *opaque, 1339 const char *name, Error **errp) 1340 { 1341 Error *local_err = NULL; 1342 LinkProperty *prop = opaque; 1343 Object **child = prop->child; 1344 Object *old_target = *child; 1345 Object *new_target = NULL; 1346 char *path = NULL; 1347 1348 visit_type_str(v, &path, name, &local_err); 1349 1350 if (!local_err && strcmp(path, "") != 0) { 1351 new_target = object_resolve_link(obj, name, path, &local_err); 1352 } 1353 1354 g_free(path); 1355 if (local_err) { 1356 error_propagate(errp, local_err); 1357 return; 1358 } 1359 1360 prop->check(obj, name, new_target, &local_err); 1361 if (local_err) { 1362 error_propagate(errp, local_err); 1363 return; 1364 } 1365 1366 object_ref(new_target); 1367 *child = new_target; 1368 object_unref(old_target); 1369 } 1370 1371 static Object *object_resolve_link_property(Object *parent, void *opaque, const gchar *part) 1372 { 1373 LinkProperty *lprop = opaque; 1374 1375 return *lprop->child; 1376 } 1377 1378 static void object_release_link_property(Object *obj, const char *name, 1379 void *opaque) 1380 { 1381 LinkProperty *prop = opaque; 1382 1383 if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) { 1384 object_unref(*prop->child); 1385 } 1386 g_free(prop); 1387 } 1388 1389 void object_property_add_link(Object *obj, const char *name, 1390 const char *type, Object **child, 1391 void (*check)(Object *, const char *, 1392 Object *, Error **), 1393 ObjectPropertyLinkFlags flags, 1394 Error **errp) 1395 { 1396 Error *local_err = NULL; 1397 LinkProperty *prop = g_malloc(sizeof(*prop)); 1398 gchar *full_type; 1399 ObjectProperty *op; 1400 1401 prop->child = child; 1402 prop->check = check; 1403 prop->flags = flags; 1404 1405 full_type = g_strdup_printf("link<%s>", type); 1406 1407 op = object_property_add(obj, name, full_type, 1408 object_get_link_property, 1409 check ? object_set_link_property : NULL, 1410 object_release_link_property, 1411 prop, 1412 &local_err); 1413 if (local_err) { 1414 error_propagate(errp, local_err); 1415 g_free(prop); 1416 goto out; 1417 } 1418 1419 op->resolve = object_resolve_link_property; 1420 1421 out: 1422 g_free(full_type); 1423 } 1424 1425 void object_property_add_const_link(Object *obj, const char *name, 1426 Object *target, Error **errp) 1427 { 1428 char *link_type; 1429 ObjectProperty *op; 1430 1431 link_type = g_strdup_printf("link<%s>", object_get_typename(target)); 1432 op = object_property_add(obj, name, link_type, 1433 object_get_child_property, NULL, 1434 NULL, target, errp); 1435 if (op != NULL) { 1436 op->resolve = object_resolve_child_property; 1437 } 1438 g_free(link_type); 1439 } 1440 1441 gchar *object_get_canonical_path_component(Object *obj) 1442 { 1443 ObjectProperty *prop = NULL; 1444 1445 g_assert(obj); 1446 g_assert(obj->parent != NULL); 1447 1448 QTAILQ_FOREACH(prop, &obj->parent->properties, node) { 1449 if (!object_property_is_child(prop)) { 1450 continue; 1451 } 1452 1453 if (prop->opaque == obj) { 1454 return g_strdup(prop->name); 1455 } 1456 } 1457 1458 /* obj had a parent but was not a child, should never happen */ 1459 g_assert_not_reached(); 1460 return NULL; 1461 } 1462 1463 gchar *object_get_canonical_path(Object *obj) 1464 { 1465 Object *root = object_get_root(); 1466 char *newpath, *path = NULL; 1467 1468 while (obj != root) { 1469 char *component = object_get_canonical_path_component(obj); 1470 1471 if (path) { 1472 newpath = g_strdup_printf("%s/%s", component, path); 1473 g_free(component); 1474 g_free(path); 1475 path = newpath; 1476 } else { 1477 path = component; 1478 } 1479 1480 obj = obj->parent; 1481 } 1482 1483 newpath = g_strdup_printf("/%s", path ? path : ""); 1484 g_free(path); 1485 1486 return newpath; 1487 } 1488 1489 Object *object_resolve_path_component(Object *parent, const gchar *part) 1490 { 1491 ObjectProperty *prop = object_property_find(parent, part, NULL); 1492 if (prop == NULL) { 1493 return NULL; 1494 } 1495 1496 if (prop->resolve) { 1497 return prop->resolve(parent, prop->opaque, part); 1498 } else { 1499 return NULL; 1500 } 1501 } 1502 1503 static Object *object_resolve_abs_path(Object *parent, 1504 gchar **parts, 1505 const char *typename, 1506 int index) 1507 { 1508 Object *child; 1509 1510 if (parts[index] == NULL) { 1511 return object_dynamic_cast(parent, typename); 1512 } 1513 1514 if (strcmp(parts[index], "") == 0) { 1515 return object_resolve_abs_path(parent, parts, typename, index + 1); 1516 } 1517 1518 child = object_resolve_path_component(parent, parts[index]); 1519 if (!child) { 1520 return NULL; 1521 } 1522 1523 return object_resolve_abs_path(child, parts, typename, index + 1); 1524 } 1525 1526 static Object *object_resolve_partial_path(Object *parent, 1527 gchar **parts, 1528 const char *typename, 1529 bool *ambiguous) 1530 { 1531 Object *obj; 1532 ObjectProperty *prop; 1533 1534 obj = object_resolve_abs_path(parent, parts, typename, 0); 1535 1536 QTAILQ_FOREACH(prop, &parent->properties, node) { 1537 Object *found; 1538 1539 if (!object_property_is_child(prop)) { 1540 continue; 1541 } 1542 1543 found = object_resolve_partial_path(prop->opaque, parts, 1544 typename, ambiguous); 1545 if (found) { 1546 if (obj) { 1547 if (ambiguous) { 1548 *ambiguous = true; 1549 } 1550 return NULL; 1551 } 1552 obj = found; 1553 } 1554 1555 if (ambiguous && *ambiguous) { 1556 return NULL; 1557 } 1558 } 1559 1560 return obj; 1561 } 1562 1563 Object *object_resolve_path_type(const char *path, const char *typename, 1564 bool *ambiguous) 1565 { 1566 Object *obj; 1567 gchar **parts; 1568 1569 parts = g_strsplit(path, "/", 0); 1570 assert(parts); 1571 1572 if (parts[0] == NULL || strcmp(parts[0], "") != 0) { 1573 if (ambiguous) { 1574 *ambiguous = false; 1575 } 1576 obj = object_resolve_partial_path(object_get_root(), parts, 1577 typename, ambiguous); 1578 } else { 1579 obj = object_resolve_abs_path(object_get_root(), parts, typename, 1); 1580 } 1581 1582 g_strfreev(parts); 1583 1584 return obj; 1585 } 1586 1587 Object *object_resolve_path(const char *path, bool *ambiguous) 1588 { 1589 return object_resolve_path_type(path, TYPE_OBJECT, ambiguous); 1590 } 1591 1592 typedef struct StringProperty 1593 { 1594 char *(*get)(Object *, Error **); 1595 void (*set)(Object *, const char *, Error **); 1596 } StringProperty; 1597 1598 static void property_get_str(Object *obj, Visitor *v, void *opaque, 1599 const char *name, Error **errp) 1600 { 1601 StringProperty *prop = opaque; 1602 char *value; 1603 1604 value = prop->get(obj, errp); 1605 if (value) { 1606 visit_type_str(v, &value, name, errp); 1607 g_free(value); 1608 } 1609 } 1610 1611 static void property_set_str(Object *obj, Visitor *v, void *opaque, 1612 const char *name, Error **errp) 1613 { 1614 StringProperty *prop = opaque; 1615 char *value; 1616 Error *local_err = NULL; 1617 1618 visit_type_str(v, &value, name, &local_err); 1619 if (local_err) { 1620 error_propagate(errp, local_err); 1621 return; 1622 } 1623 1624 prop->set(obj, value, errp); 1625 g_free(value); 1626 } 1627 1628 static void property_release_str(Object *obj, const char *name, 1629 void *opaque) 1630 { 1631 StringProperty *prop = opaque; 1632 g_free(prop); 1633 } 1634 1635 void object_property_add_str(Object *obj, const char *name, 1636 char *(*get)(Object *, Error **), 1637 void (*set)(Object *, const char *, Error **), 1638 Error **errp) 1639 { 1640 Error *local_err = NULL; 1641 StringProperty *prop = g_malloc0(sizeof(*prop)); 1642 1643 prop->get = get; 1644 prop->set = set; 1645 1646 object_property_add(obj, name, "string", 1647 get ? property_get_str : NULL, 1648 set ? property_set_str : NULL, 1649 property_release_str, 1650 prop, &local_err); 1651 if (local_err) { 1652 error_propagate(errp, local_err); 1653 g_free(prop); 1654 } 1655 } 1656 1657 typedef struct BoolProperty 1658 { 1659 bool (*get)(Object *, Error **); 1660 void (*set)(Object *, bool, Error **); 1661 } BoolProperty; 1662 1663 static void property_get_bool(Object *obj, Visitor *v, void *opaque, 1664 const char *name, Error **errp) 1665 { 1666 BoolProperty *prop = opaque; 1667 bool value; 1668 1669 value = prop->get(obj, errp); 1670 visit_type_bool(v, &value, name, errp); 1671 } 1672 1673 static void property_set_bool(Object *obj, Visitor *v, void *opaque, 1674 const char *name, Error **errp) 1675 { 1676 BoolProperty *prop = opaque; 1677 bool value; 1678 Error *local_err = NULL; 1679 1680 visit_type_bool(v, &value, name, &local_err); 1681 if (local_err) { 1682 error_propagate(errp, local_err); 1683 return; 1684 } 1685 1686 prop->set(obj, value, errp); 1687 } 1688 1689 static void property_release_bool(Object *obj, const char *name, 1690 void *opaque) 1691 { 1692 BoolProperty *prop = opaque; 1693 g_free(prop); 1694 } 1695 1696 void object_property_add_bool(Object *obj, const char *name, 1697 bool (*get)(Object *, Error **), 1698 void (*set)(Object *, bool, Error **), 1699 Error **errp) 1700 { 1701 Error *local_err = NULL; 1702 BoolProperty *prop = g_malloc0(sizeof(*prop)); 1703 1704 prop->get = get; 1705 prop->set = set; 1706 1707 object_property_add(obj, name, "bool", 1708 get ? property_get_bool : NULL, 1709 set ? property_set_bool : NULL, 1710 property_release_bool, 1711 prop, &local_err); 1712 if (local_err) { 1713 error_propagate(errp, local_err); 1714 g_free(prop); 1715 } 1716 } 1717 1718 static void property_get_enum(Object *obj, Visitor *v, void *opaque, 1719 const char *name, Error **errp) 1720 { 1721 EnumProperty *prop = opaque; 1722 int value; 1723 1724 value = prop->get(obj, errp); 1725 visit_type_enum(v, &value, prop->strings, NULL, name, errp); 1726 } 1727 1728 static void property_set_enum(Object *obj, Visitor *v, void *opaque, 1729 const char *name, Error **errp) 1730 { 1731 EnumProperty *prop = opaque; 1732 int value; 1733 1734 visit_type_enum(v, &value, prop->strings, NULL, name, errp); 1735 prop->set(obj, value, errp); 1736 } 1737 1738 static void property_release_enum(Object *obj, const char *name, 1739 void *opaque) 1740 { 1741 EnumProperty *prop = opaque; 1742 g_free(prop); 1743 } 1744 1745 void object_property_add_enum(Object *obj, const char *name, 1746 const char *typename, 1747 const char * const *strings, 1748 int (*get)(Object *, Error **), 1749 void (*set)(Object *, int, Error **), 1750 Error **errp) 1751 { 1752 Error *local_err = NULL; 1753 EnumProperty *prop = g_malloc(sizeof(*prop)); 1754 1755 prop->strings = strings; 1756 prop->get = get; 1757 prop->set = set; 1758 1759 object_property_add(obj, name, typename, 1760 get ? property_get_enum : NULL, 1761 set ? property_set_enum : NULL, 1762 property_release_enum, 1763 prop, &local_err); 1764 if (local_err) { 1765 error_propagate(errp, local_err); 1766 g_free(prop); 1767 } 1768 } 1769 1770 typedef struct TMProperty { 1771 void (*get)(Object *, struct tm *, Error **); 1772 } TMProperty; 1773 1774 static void property_get_tm(Object *obj, Visitor *v, void *opaque, 1775 const char *name, Error **errp) 1776 { 1777 TMProperty *prop = opaque; 1778 Error *err = NULL; 1779 struct tm value; 1780 1781 prop->get(obj, &value, &err); 1782 if (err) { 1783 goto out; 1784 } 1785 1786 visit_start_struct(v, NULL, "struct tm", name, 0, &err); 1787 if (err) { 1788 goto out; 1789 } 1790 visit_type_int32(v, &value.tm_year, "tm_year", &err); 1791 if (err) { 1792 goto out_end; 1793 } 1794 visit_type_int32(v, &value.tm_mon, "tm_mon", &err); 1795 if (err) { 1796 goto out_end; 1797 } 1798 visit_type_int32(v, &value.tm_mday, "tm_mday", &err); 1799 if (err) { 1800 goto out_end; 1801 } 1802 visit_type_int32(v, &value.tm_hour, "tm_hour", &err); 1803 if (err) { 1804 goto out_end; 1805 } 1806 visit_type_int32(v, &value.tm_min, "tm_min", &err); 1807 if (err) { 1808 goto out_end; 1809 } 1810 visit_type_int32(v, &value.tm_sec, "tm_sec", &err); 1811 if (err) { 1812 goto out_end; 1813 } 1814 out_end: 1815 error_propagate(errp, err); 1816 err = NULL; 1817 visit_end_struct(v, errp); 1818 out: 1819 error_propagate(errp, err); 1820 1821 } 1822 1823 static void property_release_tm(Object *obj, const char *name, 1824 void *opaque) 1825 { 1826 TMProperty *prop = opaque; 1827 g_free(prop); 1828 } 1829 1830 void object_property_add_tm(Object *obj, const char *name, 1831 void (*get)(Object *, struct tm *, Error **), 1832 Error **errp) 1833 { 1834 Error *local_err = NULL; 1835 TMProperty *prop = g_malloc0(sizeof(*prop)); 1836 1837 prop->get = get; 1838 1839 object_property_add(obj, name, "struct tm", 1840 get ? property_get_tm : NULL, NULL, 1841 property_release_tm, 1842 prop, &local_err); 1843 if (local_err) { 1844 error_propagate(errp, local_err); 1845 g_free(prop); 1846 } 1847 } 1848 1849 static char *qdev_get_type(Object *obj, Error **errp) 1850 { 1851 return g_strdup(object_get_typename(obj)); 1852 } 1853 1854 static void property_get_uint8_ptr(Object *obj, Visitor *v, 1855 void *opaque, const char *name, 1856 Error **errp) 1857 { 1858 uint8_t value = *(uint8_t *)opaque; 1859 visit_type_uint8(v, &value, name, errp); 1860 } 1861 1862 static void property_get_uint16_ptr(Object *obj, Visitor *v, 1863 void *opaque, const char *name, 1864 Error **errp) 1865 { 1866 uint16_t value = *(uint16_t *)opaque; 1867 visit_type_uint16(v, &value, name, errp); 1868 } 1869 1870 static void property_get_uint32_ptr(Object *obj, Visitor *v, 1871 void *opaque, const char *name, 1872 Error **errp) 1873 { 1874 uint32_t value = *(uint32_t *)opaque; 1875 visit_type_uint32(v, &value, name, errp); 1876 } 1877 1878 static void property_get_uint64_ptr(Object *obj, Visitor *v, 1879 void *opaque, const char *name, 1880 Error **errp) 1881 { 1882 uint64_t value = *(uint64_t *)opaque; 1883 visit_type_uint64(v, &value, name, errp); 1884 } 1885 1886 void object_property_add_uint8_ptr(Object *obj, const char *name, 1887 const uint8_t *v, Error **errp) 1888 { 1889 object_property_add(obj, name, "uint8", property_get_uint8_ptr, 1890 NULL, NULL, (void *)v, errp); 1891 } 1892 1893 void object_property_add_uint16_ptr(Object *obj, const char *name, 1894 const uint16_t *v, Error **errp) 1895 { 1896 object_property_add(obj, name, "uint16", property_get_uint16_ptr, 1897 NULL, NULL, (void *)v, errp); 1898 } 1899 1900 void object_property_add_uint32_ptr(Object *obj, const char *name, 1901 const uint32_t *v, Error **errp) 1902 { 1903 object_property_add(obj, name, "uint32", property_get_uint32_ptr, 1904 NULL, NULL, (void *)v, errp); 1905 } 1906 1907 void object_property_add_uint64_ptr(Object *obj, const char *name, 1908 const uint64_t *v, Error **errp) 1909 { 1910 object_property_add(obj, name, "uint64", property_get_uint64_ptr, 1911 NULL, NULL, (void *)v, errp); 1912 } 1913 1914 typedef struct { 1915 Object *target_obj; 1916 char *target_name; 1917 } AliasProperty; 1918 1919 static void property_get_alias(Object *obj, struct Visitor *v, void *opaque, 1920 const char *name, Error **errp) 1921 { 1922 AliasProperty *prop = opaque; 1923 1924 object_property_get(prop->target_obj, v, prop->target_name, errp); 1925 } 1926 1927 static void property_set_alias(Object *obj, struct Visitor *v, void *opaque, 1928 const char *name, Error **errp) 1929 { 1930 AliasProperty *prop = opaque; 1931 1932 object_property_set(prop->target_obj, v, prop->target_name, errp); 1933 } 1934 1935 static Object *property_resolve_alias(Object *obj, void *opaque, 1936 const gchar *part) 1937 { 1938 AliasProperty *prop = opaque; 1939 1940 return object_resolve_path_component(prop->target_obj, prop->target_name); 1941 } 1942 1943 static void property_release_alias(Object *obj, const char *name, void *opaque) 1944 { 1945 AliasProperty *prop = opaque; 1946 1947 g_free(prop->target_name); 1948 g_free(prop); 1949 } 1950 1951 void object_property_add_alias(Object *obj, const char *name, 1952 Object *target_obj, const char *target_name, 1953 Error **errp) 1954 { 1955 AliasProperty *prop; 1956 ObjectProperty *op; 1957 ObjectProperty *target_prop; 1958 gchar *prop_type; 1959 Error *local_err = NULL; 1960 1961 target_prop = object_property_find(target_obj, target_name, errp); 1962 if (!target_prop) { 1963 return; 1964 } 1965 1966 if (object_property_is_child(target_prop)) { 1967 prop_type = g_strdup_printf("link%s", 1968 target_prop->type + strlen("child")); 1969 } else { 1970 prop_type = g_strdup(target_prop->type); 1971 } 1972 1973 prop = g_malloc(sizeof(*prop)); 1974 prop->target_obj = target_obj; 1975 prop->target_name = g_strdup(target_name); 1976 1977 op = object_property_add(obj, name, prop_type, 1978 property_get_alias, 1979 property_set_alias, 1980 property_release_alias, 1981 prop, &local_err); 1982 if (local_err) { 1983 error_propagate(errp, local_err); 1984 g_free(prop); 1985 goto out; 1986 } 1987 op->resolve = property_resolve_alias; 1988 1989 object_property_set_description(obj, op->name, 1990 target_prop->description, 1991 &error_abort); 1992 1993 out: 1994 g_free(prop_type); 1995 } 1996 1997 void object_property_set_description(Object *obj, const char *name, 1998 const char *description, Error **errp) 1999 { 2000 ObjectProperty *op; 2001 2002 op = object_property_find(obj, name, errp); 2003 if (!op) { 2004 return; 2005 } 2006 2007 g_free(op->description); 2008 op->description = g_strdup(description); 2009 } 2010 2011 static void object_instance_init(Object *obj) 2012 { 2013 object_property_add_str(obj, "type", qdev_get_type, NULL, NULL); 2014 } 2015 2016 static void register_types(void) 2017 { 2018 static TypeInfo interface_info = { 2019 .name = TYPE_INTERFACE, 2020 .class_size = sizeof(InterfaceClass), 2021 .abstract = true, 2022 }; 2023 2024 static TypeInfo object_info = { 2025 .name = TYPE_OBJECT, 2026 .instance_size = sizeof(Object), 2027 .instance_init = object_instance_init, 2028 .abstract = true, 2029 }; 2030 2031 type_interface = type_register_internal(&interface_info); 2032 type_register_internal(&object_info); 2033 } 2034 2035 type_init(register_types) 2036