Skip to content

Commit

Permalink
qapi: Add visitor for implicit structs
Browse files Browse the repository at this point in the history
These can be used when an embedded struct is parsed and members not
belonging to the struct may be present in the input (e.g. parsing a
flat namespace QMP union, where fields from both the base and one
of the alternative types are mixed in the JSON object)

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
  • Loading branch information
kevmw committed Jul 26, 2013
1 parent 5163149 commit 761d524
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/qapi/visitor-impl.h
Expand Up @@ -22,6 +22,10 @@ struct Visitor
const char *name, size_t size, Error **errp);
void (*end_struct)(Visitor *v, Error **errp);

void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
Error **errp);
void (*end_implicit_struct)(Visitor *v, Error **errp);

void (*start_list)(Visitor *v, const char *name, Error **errp);
GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
void (*end_list)(Visitor *v, Error **errp);
Expand Down
3 changes: 3 additions & 0 deletions include/qapi/visitor.h
Expand Up @@ -33,6 +33,9 @@ void visit_end_handle(Visitor *v, Error **errp);
void visit_start_struct(Visitor *v, void **obj, const char *kind,
const char *name, size_t size, Error **errp);
void visit_end_struct(Visitor *v, Error **errp);
void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
Error **errp);
void visit_end_implicit_struct(Visitor *v, Error **errp);
void visit_start_list(Visitor *v, const char *name, Error **errp);
GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
void visit_end_list(Visitor *v, Error **errp);
Expand Down
16 changes: 16 additions & 0 deletions qapi/qapi-visit-core.c
Expand Up @@ -45,6 +45,22 @@ void visit_end_struct(Visitor *v, Error **errp)
v->end_struct(v, errp);
}

void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
Error **errp)
{
if (!error_is_set(errp) && v->start_implicit_struct) {
v->start_implicit_struct(v, obj, size, errp);
}
}

void visit_end_implicit_struct(Visitor *v, Error **errp)
{
assert(!error_is_set(errp));
if (v->end_implicit_struct) {
v->end_implicit_struct(v, errp);
}
}

void visit_start_list(Visitor *v, const char *name, Error **errp)
{
if (!error_is_set(errp)) {
Expand Down
14 changes: 14 additions & 0 deletions qapi/qmp-input-visitor.c
Expand Up @@ -144,6 +144,18 @@ static void qmp_input_end_struct(Visitor *v, Error **errp)
qmp_input_pop(qiv, errp);
}

static void qmp_input_start_implicit_struct(Visitor *v, void **obj,
size_t size, Error **errp)
{
if (obj) {
*obj = g_malloc0(size);
}
}

static void qmp_input_end_implicit_struct(Visitor *v, Error **errp)
{
}

static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
{
QmpInputVisitor *qiv = to_qiv(v);
Expand Down Expand Up @@ -293,6 +305,8 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)

v->visitor.start_struct = qmp_input_start_struct;
v->visitor.end_struct = qmp_input_end_struct;
v->visitor.start_implicit_struct = qmp_input_start_implicit_struct;
v->visitor.end_implicit_struct = qmp_input_end_implicit_struct;
v->visitor.start_list = qmp_input_start_list;
v->visitor.next_list = qmp_input_next_list;
v->visitor.end_list = qmp_input_end_list;
Expand Down

0 comments on commit 761d524

Please sign in to comment.