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