Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On 07/12/2011 08:53 AM, Luiz Capitulino wrote: On Tue, 12 Jul 2011 08:46:13 -0500 Michael Roth wrote: On 07/12/2011 08:16 AM, Luiz Capitulino wrote: On Mon, 11 Jul 2011 19:05:58 -0500 Michael Roth wrote: On 07/07/2011 09:32 AM, Luiz Capitulino wrote: On Tue, 5 Jul 2011 08:02:32 -0500 Michael Rothwrote: A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Roth --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 264 ++ qapi/qmp-input-visitor.h | 27 + qerror.h |3 + 4 files changed, 295 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..80912bb --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,264 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include "qmp-input-visitor.h" +#include "qemu-queue.h" +#include "qemu-common.h" +#include "qemu-objects.h" +#include "qerror.h" + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +const QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) +{ +const QObject *qobj; + +if (qiv->nb_stack == 0) { +qobj = qiv->obj; +} else { +qobj = qiv->stack[qiv->nb_stack - 1].obj; +} + +if (name&&qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv->nb_stack>0&&qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv->stack[qiv->nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv->nb_stack++; + +if (qiv->nb_stack>= QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv->nb_stack--; +if (qiv->nb_stack<0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "QDict"); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "list"); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so =&qiv->stack[qiv->nb_stack - 1]; + +if (so->entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so->ent
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On Tue, 12 Jul 2011 08:46:13 -0500 Michael Roth wrote: > On 07/12/2011 08:16 AM, Luiz Capitulino wrote: > > On Mon, 11 Jul 2011 19:05:58 -0500 > > Michael Roth wrote: > > > >> On 07/07/2011 09:32 AM, Luiz Capitulino wrote: > >>> On Tue, 5 Jul 2011 08:02:32 -0500 > >>> Michael Roth wrote: > >>> > A type of Visiter class that is used to walk a qobject's > structure and assign each entry to the corresponding native C type. > Command marshaling function will use this to pull out QMP command > parameters recieved over the wire and pass them as native arguments > to the corresponding C functions. > > Signed-off-by: Michael Roth > --- > Makefile.objs|2 +- > qapi/qmp-input-visitor.c | 264 > ++ > qapi/qmp-input-visitor.h | 27 + > qerror.h |3 + > 4 files changed, 295 insertions(+), 1 deletions(-) > create mode 100644 qapi/qmp-input-visitor.c > create mode 100644 qapi/qmp-input-visitor.h > > diff --git a/Makefile.objs b/Makefile.objs > index 0077014..997ecef 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o > vcard_emul_nss.o vcard_emul_type.o > ## > # qapi > > -qapi-nested-y = qapi-visit-core.o > +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o > qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) > > vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) > diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c > new file mode 100644 > index 000..80912bb > --- /dev/null > +++ b/qapi/qmp-input-visitor.c > @@ -0,0 +1,264 @@ > +/* > + * Input Visitor > + * > + * Copyright IBM, Corp. 2011 > + * > + * Authors: > + * Anthony Liguori > + * > + * This work is licensed under the terms of the GNU LGPL, version 2.1 > or later. > + * See the COPYING.LIB file in the top-level directory. > + * > + */ > + > +#include "qmp-input-visitor.h" > +#include "qemu-queue.h" > +#include "qemu-common.h" > +#include "qemu-objects.h" > +#include "qerror.h" > + > +#define QIV_STACK_SIZE 1024 > + > +typedef struct StackObject > +{ > +const QObject *obj; > +const QListEntry *entry; > +} StackObject; > + > +struct QmpInputVisitor > +{ > +Visitor visitor; > +const QObject *obj; > +StackObject stack[QIV_STACK_SIZE]; > +int nb_stack; > +}; > + > +static QmpInputVisitor *to_qiv(Visitor *v) > +{ > +return container_of(v, QmpInputVisitor, visitor); > +} > + > +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const > char *name) > +{ > +const QObject *qobj; > + > +if (qiv->nb_stack == 0) { > +qobj = qiv->obj; > +} else { > +qobj = qiv->stack[qiv->nb_stack - 1].obj; > +} > + > +if (name&& qobject_type(qobj) == QTYPE_QDICT) { > +return qdict_get(qobject_to_qdict(qobj), name); > +} else if (qiv->nb_stack> 0&& qobject_type(qobj) == > QTYPE_QLIST) { > +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); > +} > + > +return qobj; > +} > + > +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, > Error **errp) > +{ > +qiv->stack[qiv->nb_stack].obj = obj; > +if (qobject_type(obj) == QTYPE_QLIST) { > +qiv->stack[qiv->nb_stack].entry = > qlist_first(qobject_to_qlist(obj)); > +} > +qiv->nb_stack++; > + > +if (qiv->nb_stack>= QIV_STACK_SIZE) { > +error_set(errp, QERR_BUFFER_OVERRUN); > +return; > +} > +} > + > +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) > +{ > +qiv->nb_stack--; > +if (qiv->nb_stack< 0) { > +error_set(errp, QERR_BUFFER_OVERRUN); > +return; > +} > +} > + > +static void qmp_input_start_struct(Visitor *v, void **obj, const char > *kind, const char *name, size_t size, Error **errp) > +{ > +QmpInputVisitor *qiv = to_qiv(v); > +const QObject *qobj = qmp_input_get_object(qiv, name); > + > +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { > +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : > "null", "QDict"); > +return; > +} > + > +qmp_input_push(qiv, qobj, errp); > +if (error_is_set(errp)) { > +return; > +} > >>
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On 07/12/2011 08:16 AM, Luiz Capitulino wrote: On Mon, 11 Jul 2011 19:05:58 -0500 Michael Roth wrote: On 07/07/2011 09:32 AM, Luiz Capitulino wrote: On Tue, 5 Jul 2011 08:02:32 -0500 Michael Roth wrote: A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Roth --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 264 ++ qapi/qmp-input-visitor.h | 27 + qerror.h |3 + 4 files changed, 295 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..80912bb --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,264 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include "qmp-input-visitor.h" +#include "qemu-queue.h" +#include "qemu-common.h" +#include "qemu-objects.h" +#include "qerror.h" + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +const QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) +{ +const QObject *qobj; + +if (qiv->nb_stack == 0) { +qobj = qiv->obj; +} else { +qobj = qiv->stack[qiv->nb_stack - 1].obj; +} + +if (name&& qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv->nb_stack> 0&& qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv->stack[qiv->nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv->nb_stack++; + +if (qiv->nb_stack>= QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv->nb_stack--; +if (qiv->nb_stack< 0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "QDict"); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "list"); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so =&qiv->stack[qiv->nb_stack - 1]; + +if (so->entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so->entry = qlist_next(so->entry); +if (so->entry == NULL) { +qemu_free(entry); +return NULL; +
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On Mon, 11 Jul 2011 19:05:58 -0500 Michael Roth wrote: > On 07/07/2011 09:32 AM, Luiz Capitulino wrote: > > On Tue, 5 Jul 2011 08:02:32 -0500 > > Michael Roth wrote: > > > >> A type of Visiter class that is used to walk a qobject's > >> structure and assign each entry to the corresponding native C type. > >> Command marshaling function will use this to pull out QMP command > >> parameters recieved over the wire and pass them as native arguments > >> to the corresponding C functions. > >> > >> Signed-off-by: Michael Roth > >> --- > >> Makefile.objs|2 +- > >> qapi/qmp-input-visitor.c | 264 > >> ++ > >> qapi/qmp-input-visitor.h | 27 + > >> qerror.h |3 + > >> 4 files changed, 295 insertions(+), 1 deletions(-) > >> create mode 100644 qapi/qmp-input-visitor.c > >> create mode 100644 qapi/qmp-input-visitor.h > >> > >> diff --git a/Makefile.objs b/Makefile.objs > >> index 0077014..997ecef 100644 > >> --- a/Makefile.objs > >> +++ b/Makefile.objs > >> @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o > >> vcard_emul_nss.o vcard_emul_type.o > >> ## > >> # qapi > >> > >> -qapi-nested-y = qapi-visit-core.o > >> +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o > >> qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) > >> > >> vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) > >> diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c > >> new file mode 100644 > >> index 000..80912bb > >> --- /dev/null > >> +++ b/qapi/qmp-input-visitor.c > >> @@ -0,0 +1,264 @@ > >> +/* > >> + * Input Visitor > >> + * > >> + * Copyright IBM, Corp. 2011 > >> + * > >> + * Authors: > >> + * Anthony Liguori > >> + * > >> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or > >> later. > >> + * See the COPYING.LIB file in the top-level directory. > >> + * > >> + */ > >> + > >> +#include "qmp-input-visitor.h" > >> +#include "qemu-queue.h" > >> +#include "qemu-common.h" > >> +#include "qemu-objects.h" > >> +#include "qerror.h" > >> + > >> +#define QIV_STACK_SIZE 1024 > >> + > >> +typedef struct StackObject > >> +{ > >> +const QObject *obj; > >> +const QListEntry *entry; > >> +} StackObject; > >> + > >> +struct QmpInputVisitor > >> +{ > >> +Visitor visitor; > >> +const QObject *obj; > >> +StackObject stack[QIV_STACK_SIZE]; > >> +int nb_stack; > >> +}; > >> + > >> +static QmpInputVisitor *to_qiv(Visitor *v) > >> +{ > >> +return container_of(v, QmpInputVisitor, visitor); > >> +} > >> + > >> +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const > >> char *name) > >> +{ > >> +const QObject *qobj; > >> + > >> +if (qiv->nb_stack == 0) { > >> +qobj = qiv->obj; > >> +} else { > >> +qobj = qiv->stack[qiv->nb_stack - 1].obj; > >> +} > >> + > >> +if (name&& qobject_type(qobj) == QTYPE_QDICT) { > >> +return qdict_get(qobject_to_qdict(qobj), name); > >> +} else if (qiv->nb_stack> 0&& qobject_type(qobj) == QTYPE_QLIST) { > >> +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); > >> +} > >> + > >> +return qobj; > >> +} > >> + > >> +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, > >> Error **errp) > >> +{ > >> +qiv->stack[qiv->nb_stack].obj = obj; > >> +if (qobject_type(obj) == QTYPE_QLIST) { > >> +qiv->stack[qiv->nb_stack].entry = > >> qlist_first(qobject_to_qlist(obj)); > >> +} > >> +qiv->nb_stack++; > >> + > >> +if (qiv->nb_stack>= QIV_STACK_SIZE) { > >> +error_set(errp, QERR_BUFFER_OVERRUN); > >> +return; > >> +} > >> +} > >> + > >> +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) > >> +{ > >> +qiv->nb_stack--; > >> +if (qiv->nb_stack< 0) { > >> +error_set(errp, QERR_BUFFER_OVERRUN); > >> +return; > >> +} > >> +} > >> + > >> +static void qmp_input_start_struct(Visitor *v, void **obj, const char > >> *kind, const char *name, size_t size, Error **errp) > >> +{ > >> +QmpInputVisitor *qiv = to_qiv(v); > >> +const QObject *qobj = qmp_input_get_object(qiv, name); > >> + > >> +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { > >> +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : > >> "null", "QDict"); > >> +return; > >> +} > >> + > >> +qmp_input_push(qiv, qobj, errp); > >> +if (error_is_set(errp)) { > >> +return; > >> +} > >> + > >> +if (obj) { > >> +*obj = qemu_mallocz(size); > >> +} > >> +} > >> + > >> +static void qmp_input_end_struct(Visitor *v, Error **errp) > >> +{ > >> +QmpInputVisitor *qiv = to_qiv(v); > >> + > >> +qmp_input_pop(qiv, errp); > >> +} > >> + > >> +static void qmp_input_start_list(Visitor *v, const char *name, Error > >> **errp) > >> +{ > >> +QmpInputVisitor *qiv = to_qiv(v); > >> +const QObj
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On 07/07/2011 09:32 AM, Luiz Capitulino wrote: On Tue, 5 Jul 2011 08:02:32 -0500 Michael Roth wrote: A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Roth --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 264 ++ qapi/qmp-input-visitor.h | 27 + qerror.h |3 + 4 files changed, 295 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..80912bb --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,264 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include "qmp-input-visitor.h" +#include "qemu-queue.h" +#include "qemu-common.h" +#include "qemu-objects.h" +#include "qerror.h" + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +const QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) +{ +const QObject *qobj; + +if (qiv->nb_stack == 0) { +qobj = qiv->obj; +} else { +qobj = qiv->stack[qiv->nb_stack - 1].obj; +} + +if (name&& qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv->nb_stack> 0&& qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv->stack[qiv->nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv->nb_stack++; + +if (qiv->nb_stack>= QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv->nb_stack--; +if (qiv->nb_stack< 0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "QDict"); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "list"); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so =&qiv->stack[qiv->nb_stack - 1]; + +if (so->entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so->entry = qlist_next(so->entry); +if (so->entry == NULL) { +qemu_free(entry); +return NULL; +} +(*list)->next = entry; +} +*list = entry; + + +return entry; +} + +static void qmp_input_end_li
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On Tue, 5 Jul 2011 08:02:32 -0500 Michael Roth wrote: > A type of Visiter class that is used to walk a qobject's > structure and assign each entry to the corresponding native C type. > Command marshaling function will use this to pull out QMP command > parameters recieved over the wire and pass them as native arguments > to the corresponding C functions. > > Signed-off-by: Michael Roth > --- > Makefile.objs|2 +- > qapi/qmp-input-visitor.c | 264 > ++ > qapi/qmp-input-visitor.h | 27 + > qerror.h |3 + > 4 files changed, 295 insertions(+), 1 deletions(-) > create mode 100644 qapi/qmp-input-visitor.c > create mode 100644 qapi/qmp-input-visitor.h > > diff --git a/Makefile.objs b/Makefile.objs > index 0077014..997ecef 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o > vcard_emul_nss.o vcard_emul_type.o > ## > # qapi > > -qapi-nested-y = qapi-visit-core.o > +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o > qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) > > vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) > diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c > new file mode 100644 > index 000..80912bb > --- /dev/null > +++ b/qapi/qmp-input-visitor.c > @@ -0,0 +1,264 @@ > +/* > + * Input Visitor > + * > + * Copyright IBM, Corp. 2011 > + * > + * Authors: > + * Anthony Liguori > + * > + * This work is licensed under the terms of the GNU LGPL, version 2.1 or > later. > + * See the COPYING.LIB file in the top-level directory. > + * > + */ > + > +#include "qmp-input-visitor.h" > +#include "qemu-queue.h" > +#include "qemu-common.h" > +#include "qemu-objects.h" > +#include "qerror.h" > + > +#define QIV_STACK_SIZE 1024 > + > +typedef struct StackObject > +{ > +const QObject *obj; > +const QListEntry *entry; > +} StackObject; > + > +struct QmpInputVisitor > +{ > +Visitor visitor; > +const QObject *obj; > +StackObject stack[QIV_STACK_SIZE]; > +int nb_stack; > +}; > + > +static QmpInputVisitor *to_qiv(Visitor *v) > +{ > +return container_of(v, QmpInputVisitor, visitor); > +} > + > +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char > *name) > +{ > +const QObject *qobj; > + > +if (qiv->nb_stack == 0) { > +qobj = qiv->obj; > +} else { > +qobj = qiv->stack[qiv->nb_stack - 1].obj; > +} > + > +if (name && qobject_type(qobj) == QTYPE_QDICT) { > +return qdict_get(qobject_to_qdict(qobj), name); > +} else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) { > +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); > +} > + > +return qobj; > +} > + > +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error > **errp) > +{ > +qiv->stack[qiv->nb_stack].obj = obj; > +if (qobject_type(obj) == QTYPE_QLIST) { > +qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj)); > +} > +qiv->nb_stack++; > + > +if (qiv->nb_stack >= QIV_STACK_SIZE) { > +error_set(errp, QERR_BUFFER_OVERRUN); > +return; > +} > +} > + > +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) > +{ > +qiv->nb_stack--; > +if (qiv->nb_stack < 0) { > +error_set(errp, QERR_BUFFER_OVERRUN); > +return; > +} > +} > + > +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, > const char *name, size_t size, Error **errp) > +{ > +QmpInputVisitor *qiv = to_qiv(v); > +const QObject *qobj = qmp_input_get_object(qiv, name); > + > +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { > +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", > "QDict"); > +return; > +} > + > +qmp_input_push(qiv, qobj, errp); > +if (error_is_set(errp)) { > +return; > +} > + > +if (obj) { > +*obj = qemu_mallocz(size); > +} > +} > + > +static void qmp_input_end_struct(Visitor *v, Error **errp) > +{ > +QmpInputVisitor *qiv = to_qiv(v); > + > +qmp_input_pop(qiv, errp); > +} > + > +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) > +{ > +QmpInputVisitor *qiv = to_qiv(v); > +const QObject *qobj = qmp_input_get_object(qiv, name); > + > +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { > +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", > "list"); > +return; > +} > + > +qmp_input_push(qiv, qobj, errp); > +} > + > +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, > Error **errp) > +{ > +QmpInputVisitor *qiv = to_qiv(v); > +GenericList *entry; > +StackObject *so = &qiv->stack[qiv->nb_stack - 1]; > + > +if (so->entry == NULL) { > +return NULL; > +} > + > +entry = qemu_ma
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On 07/07/2011 09:32 AM, Luiz Capitulino wrote: On Tue, 5 Jul 2011 08:02:32 -0500 Michael Roth wrote: A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Roth --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 264 ++ qapi/qmp-input-visitor.h | 27 + qerror.h |3 + 4 files changed, 295 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..80912bb --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,264 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include "qmp-input-visitor.h" +#include "qemu-queue.h" +#include "qemu-common.h" +#include "qemu-objects.h" +#include "qerror.h" + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +const QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) +{ +const QObject *qobj; + +if (qiv->nb_stack == 0) { +qobj = qiv->obj; +} else { +qobj = qiv->stack[qiv->nb_stack - 1].obj; +} + +if (name&& qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv->nb_stack> 0&& qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv->stack[qiv->nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv->nb_stack++; + +if (qiv->nb_stack>= QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv->nb_stack--; +if (qiv->nb_stack< 0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "QDict"); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "list"); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so =&qiv->stack[qiv->nb_stack - 1]; + +if (so->entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so->entry = qlist_next(so->entry); +if (so->entry == NULL) { +qemu_free(entry); +return NULL; +} +(*list)->next = entry; +} +*list = entry; + + +return entry; +} + +static void qmp_input_end_li
[Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Roth --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 264 ++ qapi/qmp-input-visitor.h | 27 + qerror.h |3 + 4 files changed, 295 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..80912bb --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,264 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include "qmp-input-visitor.h" +#include "qemu-queue.h" +#include "qemu-common.h" +#include "qemu-objects.h" +#include "qerror.h" + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +const QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) +{ +const QObject *qobj; + +if (qiv->nb_stack == 0) { +qobj = qiv->obj; +} else { +qobj = qiv->stack[qiv->nb_stack - 1].obj; +} + +if (name && qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv->stack[qiv->nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv->nb_stack++; + +if (qiv->nb_stack >= QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv->nb_stack--; +if (qiv->nb_stack < 0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "QDict"); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "list"); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so = &qiv->stack[qiv->nb_stack - 1]; + +if (so->entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so->entry = qlist_next(so->entry); +if (so->entry == NULL) { +qemu_free(entry); +return NULL; +} +(*list)->next = entry; +} +*list = entry; + + +return entry; +} + +static void qmp_input_end_list(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +