blob: 21edb3928edbdd518d2f88e6d924cae6241c10be [file] [log] [blame]
Michael Rothc40cc0a2011-07-19 14:50:33 -05001/*
2 * Input Visitor
3 *
Eric Blake08f95412016-01-29 06:48:59 -07004 * Copyright (C) 2012-2016 Red Hat, Inc.
Michael Rothc40cc0a2011-07-19 14:50:33 -05005 * Copyright IBM, Corp. 2011
6 *
7 * Authors:
8 * Anthony Liguori <aliguori@us.ibm.com>
9 *
10 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
11 * See the COPYING.LIB file in the top-level directory.
12 *
13 */
14
Peter Maydellcbf21152016-01-29 17:49:57 +000015#include "qemu/osdep.h"
Markus Armbrusterda34e652016-03-14 09:01:28 +010016#include "qapi/error.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010017#include "qapi/qmp-input-visitor.h"
18#include "qapi/visitor-impl.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010019#include "qemu/queue.h"
Michael Rothc40cc0a2011-07-19 14:50:33 -050020#include "qemu-common.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010021#include "qapi/qmp/types.h"
22#include "qapi/qmp/qerror.h"
Michael Rothc40cc0a2011-07-19 14:50:33 -050023
24#define QIV_STACK_SIZE 1024
25
26typedef struct StackObject
27{
Eric Blakeb471d012016-04-28 15:45:12 -060028 QObject *obj; /* Object being visited */
Eric Blake1158bb22016-06-09 10:48:34 -060029 void *qapi; /* sanity check that caller uses same pointer */
Eric Blakeb471d012016-04-28 15:45:12 -060030
31 GHashTable *h; /* If obj is dict: unvisited keys */
32 const QListEntry *entry; /* If obj is list: unvisited tail */
Michael Rothc40cc0a2011-07-19 14:50:33 -050033} StackObject;
34
35struct QmpInputVisitor
36{
37 Visitor visitor;
Eric Blakeb471d012016-04-28 15:45:12 -060038
Eric Blakece140b12016-04-28 15:45:18 -060039 /* Root of visit at visitor creation. */
40 QObject *root;
41
42 /* Stack of objects being visited (all entries will be either
43 * QDict or QList). */
Michael Rothc40cc0a2011-07-19 14:50:33 -050044 StackObject stack[QIV_STACK_SIZE];
45 int nb_stack;
Eric Blakeb471d012016-04-28 15:45:12 -060046
47 /* True to reject parse in visit_end_struct() if unvisited keys remain. */
Paolo Bonzinie38ac962012-03-22 12:51:10 +010048 bool strict;
Michael Rothc40cc0a2011-07-19 14:50:33 -050049};
50
51static QmpInputVisitor *to_qiv(Visitor *v)
52{
53 return container_of(v, QmpInputVisitor, visitor);
54}
55
Paolo Bonzini4faaec62012-03-22 12:51:09 +010056static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
Kevin Wolfe8316d72013-07-08 11:33:07 +020057 const char *name,
58 bool consume)
Michael Rothc40cc0a2011-07-19 14:50:33 -050059{
Eric Blakece140b12016-04-28 15:45:18 -060060 StackObject *tos;
61 QObject *qobj;
Eric Blakee5826a22016-04-28 15:45:15 -060062 QObject *ret;
Michael Rothc40cc0a2011-07-19 14:50:33 -050063
Eric Blakece140b12016-04-28 15:45:18 -060064 if (!qiv->nb_stack) {
65 /* Starting at root, name is ignored. */
66 return qiv->root;
67 }
68
69 /* We are in a container; find the next element. */
70 tos = &qiv->stack[qiv->nb_stack - 1];
71 qobj = tos->obj;
Eric Blakeb471d012016-04-28 15:45:12 -060072 assert(qobj);
73
Eric Blakece140b12016-04-28 15:45:18 -060074 if (qobject_type(qobj) == QTYPE_QDICT) {
75 assert(name);
Eric Blakee5826a22016-04-28 15:45:15 -060076 ret = qdict_get(qobject_to_qdict(qobj), name);
77 if (tos->h && consume && ret) {
78 bool removed = g_hash_table_remove(tos->h, name);
79 assert(removed);
Paolo Bonzini47c6d3e2011-12-18 17:05:04 +010080 }
Eric Blakece140b12016-04-28 15:45:18 -060081 } else {
Eric Blakeb471d012016-04-28 15:45:12 -060082 assert(qobject_type(qobj) == QTYPE_QLIST);
Eric Blakece140b12016-04-28 15:45:18 -060083 assert(!name);
84 ret = qlist_entry_obj(tos->entry);
Eric Blakefcf3cb22016-04-28 15:45:19 -060085 if (consume) {
86 tos->entry = qlist_next(tos->entry);
87 }
Eric Blakeb471d012016-04-28 15:45:12 -060088 }
89
Eric Blakece140b12016-04-28 15:45:18 -060090 return ret;
Michael Rothc40cc0a2011-07-19 14:50:33 -050091}
92
Paolo Bonzinie38ac962012-03-22 12:51:10 +010093static void qdict_add_key(const char *key, QObject *obj, void *opaque)
94{
95 GHashTable *h = opaque;
96 g_hash_table_insert(h, (gpointer) key, NULL);
97}
98
Eric Blaked9f62dd2016-04-28 15:45:31 -060099static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
Eric Blake1158bb22016-06-09 10:48:34 -0600100 void *qapi, Error **errp)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500101{
Paolo Bonzinie38ac962012-03-22 12:51:10 +0100102 GHashTable *h;
Eric Blakeb471d012016-04-28 15:45:12 -0600103 StackObject *tos = &qiv->stack[qiv->nb_stack];
Michael Rothc40cc0a2011-07-19 14:50:33 -0500104
Eric Blakeb471d012016-04-28 15:45:12 -0600105 assert(obj);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500106 if (qiv->nb_stack >= QIV_STACK_SIZE) {
Cole Robinsonf231b882014-03-21 19:42:26 -0400107 error_setg(errp, "An internal buffer overran");
Eric Blaked9f62dd2016-04-28 15:45:31 -0600108 return NULL;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500109 }
Paolo Bonzinie38ac962012-03-22 12:51:10 +0100110
Eric Blakeb471d012016-04-28 15:45:12 -0600111 tos->obj = obj;
Eric Blake1158bb22016-06-09 10:48:34 -0600112 tos->qapi = qapi;
Eric Blakefcf3cb22016-04-28 15:45:19 -0600113 assert(!tos->h);
114 assert(!tos->entry);
Paolo Bonzinie38ac962012-03-22 12:51:10 +0100115
116 if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
117 h = g_hash_table_new(g_str_hash, g_str_equal);
118 qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
Eric Blakeb471d012016-04-28 15:45:12 -0600119 tos->h = h;
Eric Blakefcf3cb22016-04-28 15:45:19 -0600120 } else if (qobject_type(obj) == QTYPE_QLIST) {
121 tos->entry = qlist_first(qobject_to_qlist(obj));
Paolo Bonzinie38ac962012-03-22 12:51:10 +0100122 }
123
124 qiv->nb_stack++;
Eric Blaked9f62dd2016-04-28 15:45:31 -0600125 return tos->entry;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500126}
127
NODA, Kai57a33d82012-04-21 22:41:27 +0900128
Eric Blake15c2f662016-04-28 15:45:27 -0600129static void qmp_input_check_struct(Visitor *v, Error **errp)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500130{
Eric Blake15c2f662016-04-28 15:45:27 -0600131 QmpInputVisitor *qiv = to_qiv(v);
Eric Blakefcf3cb22016-04-28 15:45:19 -0600132 StackObject *tos = &qiv->stack[qiv->nb_stack - 1];
Eric Blake15c2f662016-04-28 15:45:27 -0600133
NODA, Kai57a33d82012-04-21 22:41:27 +0900134 assert(qiv->nb_stack > 0);
Paolo Bonzinie38ac962012-03-22 12:51:10 +0100135
NODA, Kai57a33d82012-04-21 22:41:27 +0900136 if (qiv->strict) {
Eric Blakefcf3cb22016-04-28 15:45:19 -0600137 GHashTable *const top_ht = tos->h;
NODA, Kai57a33d82012-04-21 22:41:27 +0900138 if (top_ht) {
Eric Blakef96493b2016-02-17 23:48:15 -0700139 GHashTableIter iter;
140 const char *key;
141
142 g_hash_table_iter_init(&iter, top_ht);
143 if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100144 error_setg(errp, QERR_QMP_EXTRA_MEMBER, key);
NODA, Kai57a33d82012-04-21 22:41:27 +0900145 }
Eric Blake15c2f662016-04-28 15:45:27 -0600146 }
147 }
148}
149
Eric Blake1158bb22016-06-09 10:48:34 -0600150static void qmp_input_pop(Visitor *v, void **obj)
Eric Blake15c2f662016-04-28 15:45:27 -0600151{
152 QmpInputVisitor *qiv = to_qiv(v);
153 StackObject *tos = &qiv->stack[qiv->nb_stack - 1];
154
155 assert(qiv->nb_stack > 0);
Eric Blake1158bb22016-06-09 10:48:34 -0600156 assert(tos->qapi == obj);
Eric Blake15c2f662016-04-28 15:45:27 -0600157
158 if (qiv->strict) {
159 GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
160 if (top_ht) {
NODA, Kai57a33d82012-04-21 22:41:27 +0900161 g_hash_table_unref(top_ht);
Paolo Bonzinie38ac962012-03-22 12:51:10 +0100162 }
Eric Blakefcf3cb22016-04-28 15:45:19 -0600163 tos->h = NULL;
Paolo Bonzinie38ac962012-03-22 12:51:10 +0100164 }
165
Michael Rothc40cc0a2011-07-19 14:50:33 -0500166 qiv->nb_stack--;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500167}
168
Eric Blake0b2a0d62016-01-29 06:48:56 -0700169static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
Eric Blake337283d2016-01-29 06:48:57 -0700170 size_t size, Error **errp)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500171{
172 QmpInputVisitor *qiv = to_qiv(v);
Kevin Wolfe8316d72013-07-08 11:33:07 +0200173 QObject *qobj = qmp_input_get_object(qiv, name, true);
Paolo Bonzini8b714d32012-03-22 12:51:05 +0100174 Error *err = NULL;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500175
Eric Blakee58d6952016-04-28 15:45:10 -0600176 if (obj) {
177 *obj = NULL;
178 }
Michael Rothc40cc0a2011-07-19 14:50:33 -0500179 if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100180 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
181 "QDict");
Michael Rothc40cc0a2011-07-19 14:50:33 -0500182 return;
183 }
184
Eric Blake1158bb22016-06-09 10:48:34 -0600185 qmp_input_push(qiv, qobj, obj, &err);
Paolo Bonzini8b714d32012-03-22 12:51:05 +0100186 if (err) {
187 error_propagate(errp, err);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500188 return;
189 }
190
191 if (obj) {
Anthony Liguori7267c092011-08-20 22:09:37 -0500192 *obj = g_malloc0(size);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500193 }
194}
195
Michael Rothc40cc0a2011-07-19 14:50:33 -0500196
Eric Blaked9f62dd2016-04-28 15:45:31 -0600197static void qmp_input_start_list(Visitor *v, const char *name,
198 GenericList **list, size_t size, Error **errp)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500199{
200 QmpInputVisitor *qiv = to_qiv(v);
Kevin Wolfe8316d72013-07-08 11:33:07 +0200201 QObject *qobj = qmp_input_get_object(qiv, name, true);
Eric Blaked9f62dd2016-04-28 15:45:31 -0600202 const QListEntry *entry;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500203
204 if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
Eric Blaked9f62dd2016-04-28 15:45:31 -0600205 if (list) {
206 *list = NULL;
207 }
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100208 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
209 "list");
Michael Rothc40cc0a2011-07-19 14:50:33 -0500210 return;
211 }
212
Eric Blake1158bb22016-06-09 10:48:34 -0600213 entry = qmp_input_push(qiv, qobj, list, errp);
Eric Blaked9f62dd2016-04-28 15:45:31 -0600214 if (list) {
215 if (entry) {
216 *list = g_malloc0(size);
217 } else {
218 *list = NULL;
219 }
220 }
Michael Rothc40cc0a2011-07-19 14:50:33 -0500221}
222
Eric Blaked9f62dd2016-04-28 15:45:31 -0600223static GenericList *qmp_input_next_list(Visitor *v, GenericList *tail,
Eric Blakee65d89b2016-02-17 23:48:23 -0700224 size_t size)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500225{
226 QmpInputVisitor *qiv = to_qiv(v);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500227 StackObject *so = &qiv->stack[qiv->nb_stack - 1];
Paolo Bonzini3a86a0f2012-03-22 22:38:40 +0100228
Eric Blakefcf3cb22016-04-28 15:45:19 -0600229 if (!so->entry) {
Michael Rothc40cc0a2011-07-19 14:50:33 -0500230 return NULL;
231 }
Eric Blaked9f62dd2016-04-28 15:45:31 -0600232 tail->next = g_malloc0(size);
233 return tail->next;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500234}
235
Michael Rothc40cc0a2011-07-19 14:50:33 -0500236
Eric Blakedbf11922016-02-17 23:48:29 -0700237static void qmp_input_start_alternate(Visitor *v, const char *name,
238 GenericAlternate **obj, size_t size,
239 bool promote_int, Error **errp)
Kevin Wolf69dd62d2013-07-08 16:14:21 +0200240{
241 QmpInputVisitor *qiv = to_qiv(v);
242 QObject *qobj = qmp_input_get_object(qiv, name, false);
243
244 if (!qobj) {
Eric Blakedbf11922016-02-17 23:48:29 -0700245 *obj = NULL;
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100246 error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
Kevin Wolf69dd62d2013-07-08 16:14:21 +0200247 return;
248 }
Eric Blakedbf11922016-02-17 23:48:29 -0700249 *obj = g_malloc0(size);
250 (*obj)->type = qobject_type(qobj);
251 if (promote_int && (*obj)->type == QTYPE_QINT) {
252 (*obj)->type = QTYPE_QFLOAT;
Eric Blaked00341a2015-12-01 22:20:51 -0700253 }
Kevin Wolf69dd62d2013-07-08 16:14:21 +0200254}
255
Eric Blake0b2a0d62016-01-29 06:48:56 -0700256static void qmp_input_type_int64(Visitor *v, const char *name, int64_t *obj,
Eric Blake4c403142016-01-29 06:48:49 -0700257 Error **errp)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500258{
259 QmpInputVisitor *qiv = to_qiv(v);
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200260 QInt *qint = qobject_to_qint(qmp_input_get_object(qiv, name, true));
Michael Rothc40cc0a2011-07-19 14:50:33 -0500261
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200262 if (!qint) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100263 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
264 "integer");
Michael Rothc40cc0a2011-07-19 14:50:33 -0500265 return;
266 }
267
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200268 *obj = qint_get_int(qint);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500269}
270
Eric Blake0b2a0d62016-01-29 06:48:56 -0700271static void qmp_input_type_uint64(Visitor *v, const char *name, uint64_t *obj,
Eric Blakef755dea2016-01-29 06:48:50 -0700272 Error **errp)
273{
274 /* FIXME: qobject_to_qint mishandles values over INT64_MAX */
275 QmpInputVisitor *qiv = to_qiv(v);
276 QInt *qint = qobject_to_qint(qmp_input_get_object(qiv, name, true));
277
278 if (!qint) {
279 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
280 "integer");
281 return;
282 }
283
284 *obj = qint_get_int(qint);
285}
286
Eric Blake0b2a0d62016-01-29 06:48:56 -0700287static void qmp_input_type_bool(Visitor *v, const char *name, bool *obj,
Michael Rothc40cc0a2011-07-19 14:50:33 -0500288 Error **errp)
289{
290 QmpInputVisitor *qiv = to_qiv(v);
Markus Armbruster14b61602015-10-15 16:15:33 +0200291 QBool *qbool = qobject_to_qbool(qmp_input_get_object(qiv, name, true));
Michael Rothc40cc0a2011-07-19 14:50:33 -0500292
Markus Armbruster14b61602015-10-15 16:15:33 +0200293 if (!qbool) {
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100294 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
295 "boolean");
Michael Rothc40cc0a2011-07-19 14:50:33 -0500296 return;
297 }
298
Markus Armbruster14b61602015-10-15 16:15:33 +0200299 *obj = qbool_get_bool(qbool);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500300}
301
Eric Blake0b2a0d62016-01-29 06:48:56 -0700302static void qmp_input_type_str(Visitor *v, const char *name, char **obj,
Michael Rothc40cc0a2011-07-19 14:50:33 -0500303 Error **errp)
304{
305 QmpInputVisitor *qiv = to_qiv(v);
Markus Armbruster7f027842015-10-15 16:15:37 +0200306 QString *qstr = qobject_to_qstring(qmp_input_get_object(qiv, name, true));
Michael Rothc40cc0a2011-07-19 14:50:33 -0500307
Markus Armbruster7f027842015-10-15 16:15:37 +0200308 if (!qstr) {
Eric Blakee58d6952016-04-28 15:45:10 -0600309 *obj = NULL;
Markus Armbrusterc6bd8c72015-03-17 11:54:50 +0100310 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
311 "string");
Michael Rothc40cc0a2011-07-19 14:50:33 -0500312 return;
313 }
314
Markus Armbruster7f027842015-10-15 16:15:37 +0200315 *obj = g_strdup(qstring_get_str(qstr));
Michael Rothc40cc0a2011-07-19 14:50:33 -0500316}
317
Eric Blake0b2a0d62016-01-29 06:48:56 -0700318static void qmp_input_type_number(Visitor *v, const char *name, double *obj,
Michael Rothc40cc0a2011-07-19 14:50:33 -0500319 Error **errp)
320{
321 QmpInputVisitor *qiv = to_qiv(v);
Kevin Wolfe8316d72013-07-08 11:33:07 +0200322 QObject *qobj = qmp_input_get_object(qiv, name, true);
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200323 QInt *qint;
324 QFloat *qfloat;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500325
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200326 qint = qobject_to_qint(qobj);
327 if (qint) {
328 *obj = qint_get_int(qobject_to_qint(qobj));
Michael Rothc40cc0a2011-07-19 14:50:33 -0500329 return;
330 }
331
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200332 qfloat = qobject_to_qfloat(qobj);
333 if (qfloat) {
Michael Roth1ee51872012-05-11 12:43:24 -0500334 *obj = qfloat_get_double(qobject_to_qfloat(qobj));
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200335 return;
Michael Roth1ee51872012-05-11 12:43:24 -0500336 }
Markus Armbrusterfcf73f62015-10-15 16:15:35 +0200337
338 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
339 "number");
Michael Rothc40cc0a2011-07-19 14:50:33 -0500340}
341
Eric Blake0b2a0d62016-01-29 06:48:56 -0700342static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj,
Markus Armbruster28770e02015-09-16 13:06:24 +0200343 Error **errp)
344{
345 QmpInputVisitor *qiv = to_qiv(v);
346 QObject *qobj = qmp_input_get_object(qiv, name, true);
347
348 qobject_incref(qobj);
349 *obj = qobj;
350}
351
Eric Blake3bc97fd2016-04-28 15:45:22 -0600352static void qmp_input_type_null(Visitor *v, const char *name, Error **errp)
353{
Eric Blake3df016f2016-04-28 15:45:23 -0600354 QmpInputVisitor *qiv = to_qiv(v);
355 QObject *qobj = qmp_input_get_object(qiv, name, true);
356
357 if (qobject_type(qobj) != QTYPE_QNULL) {
358 error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
359 "null");
360 }
Eric Blake3bc97fd2016-04-28 15:45:22 -0600361}
362
Eric Blake0b2a0d62016-01-29 06:48:56 -0700363static void qmp_input_optional(Visitor *v, const char *name, bool *present)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500364{
365 QmpInputVisitor *qiv = to_qiv(v);
Eric Blakee5826a22016-04-28 15:45:15 -0600366 QObject *qobj = qmp_input_get_object(qiv, name, false);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500367
368 if (!qobj) {
369 *present = false;
370 return;
371 }
372
373 *present = true;
374}
375
Eric Blake2c0ef9f2016-06-09 10:48:35 -0600376static void qmp_input_free(Visitor *v)
377{
378 QmpInputVisitor *qiv = to_qiv(v);
379
Eric Blakeb70ce1012016-06-09 10:48:38 -0600380 qobject_decref(qiv->root);
381 g_free(qiv);
Eric Blake2c0ef9f2016-06-09 10:48:35 -0600382}
383
Eric Blakeb70ce1012016-06-09 10:48:38 -0600384Visitor *qmp_input_visitor_new(QObject *obj, bool strict)
Michael Rothc40cc0a2011-07-19 14:50:33 -0500385{
386 QmpInputVisitor *v;
387
Anthony Liguori7267c092011-08-20 22:09:37 -0500388 v = g_malloc0(sizeof(*v));
Michael Rothc40cc0a2011-07-19 14:50:33 -0500389
Eric Blake983f52d2016-04-28 15:45:09 -0600390 v->visitor.type = VISITOR_INPUT;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500391 v->visitor.start_struct = qmp_input_start_struct;
Eric Blake15c2f662016-04-28 15:45:27 -0600392 v->visitor.check_struct = qmp_input_check_struct;
393 v->visitor.end_struct = qmp_input_pop;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500394 v->visitor.start_list = qmp_input_start_list;
395 v->visitor.next_list = qmp_input_next_list;
Eric Blake15c2f662016-04-28 15:45:27 -0600396 v->visitor.end_list = qmp_input_pop;
Eric Blakedbf11922016-02-17 23:48:29 -0700397 v->visitor.start_alternate = qmp_input_start_alternate;
Eric Blake4c403142016-01-29 06:48:49 -0700398 v->visitor.type_int64 = qmp_input_type_int64;
Eric Blakef755dea2016-01-29 06:48:50 -0700399 v->visitor.type_uint64 = qmp_input_type_uint64;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500400 v->visitor.type_bool = qmp_input_type_bool;
401 v->visitor.type_str = qmp_input_type_str;
402 v->visitor.type_number = qmp_input_type_number;
Markus Armbruster28770e02015-09-16 13:06:24 +0200403 v->visitor.type_any = qmp_input_type_any;
Eric Blake3bc97fd2016-04-28 15:45:22 -0600404 v->visitor.type_null = qmp_input_type_null;
Markus Armbrustere2cd0f42014-05-07 09:53:46 +0200405 v->visitor.optional = qmp_input_optional;
Eric Blake2c0ef9f2016-06-09 10:48:35 -0600406 v->visitor.free = qmp_input_free;
Eric Blakefc471c12016-04-28 15:45:13 -0600407 v->strict = strict;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500408
Eric Blakece140b12016-04-28 15:45:18 -0600409 v->root = obj;
Paolo Bonzini4faaec62012-03-22 12:51:09 +0100410 qobject_incref(obj);
Michael Rothc40cc0a2011-07-19 14:50:33 -0500411
Eric Blakeb70ce1012016-06-09 10:48:38 -0600412 return &v->visitor;
Michael Rothc40cc0a2011-07-19 14:50:33 -0500413}