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