@@ -57,6 +57,9 @@ struct Visitor
/* Must be set to visit structs */
void (*end_struct)(Visitor *v, void **obj);
+ /* Must be set for input visitors to visit structs */
+ const char *(*next_struct_member)(Visitor *v);
+
/* Must be set; implementations may require @list to be non-null,
* but must document it. */
bool (*start_list)(Visitor *v, const char *name, GenericList **list,
@@ -326,6 +326,8 @@ bool visit_check_struct(Visitor *v, Error **errp);
*/
void visit_end_struct(Visitor *v, void **obj);
+/* TODO */
+const char *visit_next_struct_member(Visitor *v);
/*** Visiting lists ***/
@@ -70,6 +70,12 @@ void visit_end_struct(Visitor *v, void **obj)
v->end_struct(v, obj);
}
+const char *visit_next_struct_member(Visitor *v)
+{
+ trace_visit_next_struct_member(v);
+ return v->next_struct_member(v);
+}
+
bool visit_start_list(Visitor *v, const char *name, GenericList **list,
size_t size, Error **errp)
{
@@ -310,6 +310,21 @@ static void qobject_input_end_struct(Visitor *v, void **obj)
qobject_input_pop(v, obj);
}
+static const char *qobject_input_next_struct_member(Visitor *v)
+{
+ QObjectInputVisitor *qiv = to_qiv(v);
+ StackObject *tos = QSLIST_FIRST(&qiv->stack);
+ GHashTableIter iter;
+ const char *key;
+
+ assert(qobject_type(tos->obj) == QTYPE_QDICT && tos->h);
+ g_hash_table_iter_init(&iter, tos->h);
+ if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
+ return key;
+ }
+ return false;
+}
+
static bool qobject_input_start_list(Visitor *v, const char *name,
GenericList **list, size_t size,
@@ -700,6 +715,7 @@ static QObjectInputVisitor *qobject_input_visitor_base_new(QObject *obj)
v->visitor.start_struct = qobject_input_start_struct;
v->visitor.check_struct = qobject_input_check_struct;
v->visitor.end_struct = qobject_input_end_struct;
+ v->visitor.next_struct_member = qobject_input_next_struct_member;
v->visitor.start_list = qobject_input_start_list;
v->visitor.next_list = qobject_input_next_list;
v->visitor.check_list = qobject_input_check_list;
@@ -7,6 +7,7 @@ visit_complete(void *v, void *opaque) "v=%p opaque=%p"
visit_start_struct(void *v, const char *name, void *obj, size_t size) "v=%p name=%s obj=%p size=%zu"
visit_check_struct(void *v) "v=%p"
visit_end_struct(void *v, void *obj) "v=%p obj=%p"
+visit_next_struct_member(void *v) "v=%p"
visit_start_list(void *v, const char *name, void *obj, size_t size) "v=%p name=%s obj=%p size=%zu"
visit_next_list(void *v, void *tail, size_t size) "v=%p tail=%p size=%zu"
This adds a way to generically deal with an unknown set of members in input visitors by just getting the name of the next unvisited member. QOM object creation code will use it to have generic code that calls property setters which then in turn have the more specific knowledge how to visit the respective member. Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- include/qapi/visitor-impl.h | 3 +++ include/qapi/visitor.h | 2 ++ qapi/qapi-visit-core.c | 6 ++++++ qapi/qobject-input-visitor.c | 16 ++++++++++++++++ qapi/trace-events | 1 + 5 files changed, 28 insertions(+)