]>
Commit | Line | Data |
---|---|---|
c40cc0a0 MR |
1 | /* |
2 | * Input Visitor | |
3 | * | |
08f9541d | 4 | * Copyright (C) 2012-2016 Red Hat, Inc. |
c40cc0a0 MR |
5 | * Copyright IBM, Corp. 2011 |
6 | * | |
7 | * Authors: | |
8 | * Anthony Liguori <[email protected]> | |
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 | ||
cbf21151 | 15 | #include "qemu/osdep.h" |
da34e65c | 16 | #include "qapi/error.h" |
b3db211f | 17 | #include "qapi/qobject-input-visitor.h" |
7b1b5d19 | 18 | #include "qapi/visitor-impl.h" |
1de7afc9 | 19 | #include "qemu/queue.h" |
c40cc0a0 | 20 | #include "qemu-common.h" |
7b1b5d19 PB |
21 | #include "qapi/qmp/types.h" |
22 | #include "qapi/qmp/qerror.h" | |
c40cc0a0 | 23 | |
a9fc37f6 MA |
24 | typedef struct StackObject { |
25 | const char *name; /* Name of @obj in its parent, if any */ | |
26 | QObject *obj; /* QDict or QList being visited */ | |
1158bb2a | 27 | void *qapi; /* sanity check that caller uses same pointer */ |
b471d012 | 28 | |
a9fc37f6 MA |
29 | GHashTable *h; /* If @obj is QDict: unvisited keys */ |
30 | const QListEntry *entry; /* If @obj is QList: unvisited tail */ | |
31 | unsigned index; /* If @obj is QList: list index of @entry */ | |
3d344c2a | 32 | |
a9fc37f6 | 33 | QSLIST_ENTRY(StackObject) node; /* parent */ |
c40cc0a0 MR |
34 | } StackObject; |
35 | ||
a9fc37f6 | 36 | struct QObjectInputVisitor { |
c40cc0a0 | 37 | Visitor visitor; |
b471d012 | 38 | |
ce140b17 EB |
39 | /* 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). */ | |
3d344c2a | 44 | QSLIST_HEAD(, StackObject) stack; |
b471d012 | 45 | |
a9fc37f6 | 46 | GString *errname; /* Accumulator for full_name() */ |
c40cc0a0 MR |
47 | }; |
48 | ||
09e68369 | 49 | static QObjectInputVisitor *to_qiv(Visitor *v) |
c40cc0a0 | 50 | { |
09e68369 | 51 | return container_of(v, QObjectInputVisitor, visitor); |
c40cc0a0 MR |
52 | } |
53 | ||
a4a1c70d MA |
54 | static const char *full_name_nth(QObjectInputVisitor *qiv, const char *name, |
55 | int n) | |
a9fc37f6 MA |
56 | { |
57 | StackObject *so; | |
58 | char buf[32]; | |
59 | ||
60 | if (qiv->errname) { | |
61 | g_string_truncate(qiv->errname, 0); | |
62 | } else { | |
63 | qiv->errname = g_string_new(""); | |
64 | } | |
65 | ||
66 | QSLIST_FOREACH(so , &qiv->stack, node) { | |
a4a1c70d MA |
67 | if (n) { |
68 | n--; | |
69 | } else if (qobject_type(so->obj) == QTYPE_QDICT) { | |
70 | g_string_prepend(qiv->errname, name ?: "<anonymous>"); | |
a9fc37f6 MA |
71 | g_string_prepend_c(qiv->errname, '.'); |
72 | } else { | |
73 | snprintf(buf, sizeof(buf), "[%u]", so->index); | |
74 | g_string_prepend(qiv->errname, buf); | |
75 | } | |
76 | name = so->name; | |
77 | } | |
a4a1c70d | 78 | assert(!n); |
a9fc37f6 MA |
79 | |
80 | if (name) { | |
81 | g_string_prepend(qiv->errname, name); | |
82 | } else if (qiv->errname->str[0] == '.') { | |
83 | g_string_erase(qiv->errname, 0, 1); | |
a4a1c70d | 84 | } else if (!qiv->errname->str[0]) { |
a9fc37f6 MA |
85 | return "<anonymous>"; |
86 | } | |
87 | ||
88 | return qiv->errname->str; | |
89 | } | |
90 | ||
a4a1c70d MA |
91 | static const char *full_name(QObjectInputVisitor *qiv, const char *name) |
92 | { | |
93 | return full_name_nth(qiv, name, 0); | |
94 | } | |
95 | ||
a9fc37f6 MA |
96 | static QObject *qobject_input_try_get_object(QObjectInputVisitor *qiv, |
97 | const char *name, | |
98 | bool consume) | |
c40cc0a0 | 99 | { |
ce140b17 EB |
100 | StackObject *tos; |
101 | QObject *qobj; | |
e5826a2f | 102 | QObject *ret; |
b471d012 | 103 | |
3d344c2a | 104 | if (QSLIST_EMPTY(&qiv->stack)) { |
ce140b17 | 105 | /* Starting at root, name is ignored. */ |
5d0cbbcf | 106 | assert(qiv->root); |
ce140b17 EB |
107 | return qiv->root; |
108 | } | |
109 | ||
110 | /* We are in a container; find the next element. */ | |
3d344c2a | 111 | tos = QSLIST_FIRST(&qiv->stack); |
ce140b17 | 112 | qobj = tos->obj; |
b471d012 EB |
113 | assert(qobj); |
114 | ||
ce140b17 EB |
115 | if (qobject_type(qobj) == QTYPE_QDICT) { |
116 | assert(name); | |
e5826a2f EB |
117 | ret = qdict_get(qobject_to_qdict(qobj), name); |
118 | if (tos->h && consume && ret) { | |
119 | bool removed = g_hash_table_remove(tos->h, name); | |
120 | assert(removed); | |
47c6d3ec | 121 | } |
ce140b17 | 122 | } else { |
b471d012 | 123 | assert(qobject_type(qobj) == QTYPE_QLIST); |
ce140b17 EB |
124 | assert(!name); |
125 | ret = qlist_entry_obj(tos->entry); | |
eac8e79f | 126 | assert(ret); |
fcf3cb21 EB |
127 | if (consume) { |
128 | tos->entry = qlist_next(tos->entry); | |
a9fc37f6 | 129 | tos->index++; |
fcf3cb21 | 130 | } |
c40cc0a0 MR |
131 | } |
132 | ||
ce140b17 | 133 | return ret; |
c40cc0a0 MR |
134 | } |
135 | ||
a9fc37f6 MA |
136 | static QObject *qobject_input_get_object(QObjectInputVisitor *qiv, |
137 | const char *name, | |
138 | bool consume, Error **errp) | |
139 | { | |
140 | QObject *obj = qobject_input_try_get_object(qiv, name, consume); | |
141 | ||
142 | if (!obj) { | |
143 | error_setg(errp, QERR_MISSING_PARAMETER, full_name(qiv, name)); | |
144 | } | |
145 | return obj; | |
146 | } | |
147 | ||
e38ac962 PB |
148 | static void qdict_add_key(const char *key, QObject *obj, void *opaque) |
149 | { | |
150 | GHashTable *h = opaque; | |
151 | g_hash_table_insert(h, (gpointer) key, NULL); | |
152 | } | |
153 | ||
09e68369 | 154 | static const QListEntry *qobject_input_push(QObjectInputVisitor *qiv, |
a9fc37f6 | 155 | const char *name, |
b8874fbf | 156 | QObject *obj, void *qapi) |
c40cc0a0 | 157 | { |
e38ac962 | 158 | GHashTable *h; |
3d344c2a | 159 | StackObject *tos = g_new0(StackObject, 1); |
c40cc0a0 | 160 | |
b471d012 | 161 | assert(obj); |
a9fc37f6 | 162 | tos->name = name; |
b471d012 | 163 | tos->obj = obj; |
1158bb2a | 164 | tos->qapi = qapi; |
e38ac962 | 165 | |
048abb7b | 166 | if (qobject_type(obj) == QTYPE_QDICT) { |
e38ac962 PB |
167 | h = g_hash_table_new(g_str_hash, g_str_equal); |
168 | qdict_iter(qobject_to_qdict(obj), qdict_add_key, h); | |
b471d012 | 169 | tos->h = h; |
048abb7b MA |
170 | } else { |
171 | assert(qobject_type(obj) == QTYPE_QLIST); | |
fcf3cb21 | 172 | tos->entry = qlist_first(qobject_to_qlist(obj)); |
a9fc37f6 | 173 | tos->index = -1; |
e38ac962 PB |
174 | } |
175 | ||
3d344c2a | 176 | QSLIST_INSERT_HEAD(&qiv->stack, tos, node); |
d9f62dde | 177 | return tos->entry; |
c40cc0a0 MR |
178 | } |
179 | ||
57a33d89 | 180 | |
09e68369 | 181 | static void qobject_input_check_struct(Visitor *v, Error **errp) |
c40cc0a0 | 182 | { |
09e68369 | 183 | QObjectInputVisitor *qiv = to_qiv(v); |
3d344c2a | 184 | StackObject *tos = QSLIST_FIRST(&qiv->stack); |
048abb7b MA |
185 | GHashTableIter iter; |
186 | const char *key; | |
e38ac962 | 187 | |
3d344c2a | 188 | assert(tos && !tos->entry); |
048abb7b MA |
189 | |
190 | g_hash_table_iter_init(&iter, tos->h); | |
191 | if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) { | |
192 | error_setg(errp, "Parameter '%s' is unexpected", | |
193 | full_name(qiv, key)); | |
15c2f669 EB |
194 | } |
195 | } | |
196 | ||
09e68369 | 197 | static void qobject_input_stack_object_free(StackObject *tos) |
15c2f669 | 198 | { |
3d344c2a PB |
199 | if (tos->h) { |
200 | g_hash_table_unref(tos->h); | |
201 | } | |
15c2f669 | 202 | |
3d344c2a PB |
203 | g_free(tos); |
204 | } | |
15c2f669 | 205 | |
09e68369 | 206 | static void qobject_input_pop(Visitor *v, void **obj) |
3d344c2a | 207 | { |
09e68369 | 208 | QObjectInputVisitor *qiv = to_qiv(v); |
3d344c2a | 209 | StackObject *tos = QSLIST_FIRST(&qiv->stack); |
e38ac962 | 210 | |
3d344c2a PB |
211 | assert(tos && tos->qapi == obj); |
212 | QSLIST_REMOVE_HEAD(&qiv->stack, node); | |
09e68369 | 213 | qobject_input_stack_object_free(tos); |
c40cc0a0 MR |
214 | } |
215 | ||
09e68369 DB |
216 | static void qobject_input_start_struct(Visitor *v, const char *name, void **obj, |
217 | size_t size, Error **errp) | |
c40cc0a0 | 218 | { |
09e68369 DB |
219 | QObjectInputVisitor *qiv = to_qiv(v); |
220 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
c40cc0a0 | 221 | |
e58d695e EB |
222 | if (obj) { |
223 | *obj = NULL; | |
224 | } | |
1382d4ab MAL |
225 | if (!qobj) { |
226 | return; | |
227 | } | |
228 | if (qobject_type(qobj) != QTYPE_QDICT) { | |
a9fc37f6 MA |
229 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
230 | full_name(qiv, name), "object"); | |
c40cc0a0 MR |
231 | return; |
232 | } | |
233 | ||
a9fc37f6 | 234 | qobject_input_push(qiv, name, qobj, obj); |
c40cc0a0 MR |
235 | |
236 | if (obj) { | |
7267c094 | 237 | *obj = g_malloc0(size); |
c40cc0a0 MR |
238 | } |
239 | } | |
240 | ||
c40cc0a0 | 241 | |
09e68369 DB |
242 | static void qobject_input_start_list(Visitor *v, const char *name, |
243 | GenericList **list, size_t size, | |
244 | Error **errp) | |
c40cc0a0 | 245 | { |
09e68369 DB |
246 | QObjectInputVisitor *qiv = to_qiv(v); |
247 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
d9f62dde | 248 | const QListEntry *entry; |
c40cc0a0 | 249 | |
58561c27 MA |
250 | if (list) { |
251 | *list = NULL; | |
252 | } | |
1382d4ab MAL |
253 | if (!qobj) { |
254 | return; | |
255 | } | |
256 | if (qobject_type(qobj) != QTYPE_QLIST) { | |
a9fc37f6 MA |
257 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
258 | full_name(qiv, name), "array"); | |
c40cc0a0 MR |
259 | return; |
260 | } | |
261 | ||
a9fc37f6 | 262 | entry = qobject_input_push(qiv, name, qobj, list); |
58561c27 MA |
263 | if (entry && list) { |
264 | *list = g_malloc0(size); | |
d9f62dde | 265 | } |
c40cc0a0 MR |
266 | } |
267 | ||
09e68369 DB |
268 | static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail, |
269 | size_t size) | |
c40cc0a0 | 270 | { |
09e68369 | 271 | QObjectInputVisitor *qiv = to_qiv(v); |
a4a1c70d MA |
272 | StackObject *tos = QSLIST_FIRST(&qiv->stack); |
273 | ||
274 | assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST); | |
c40cc0a0 | 275 | |
a4a1c70d | 276 | if (!tos->entry) { |
c40cc0a0 MR |
277 | return NULL; |
278 | } | |
d9f62dde EB |
279 | tail->next = g_malloc0(size); |
280 | return tail->next; | |
c40cc0a0 MR |
281 | } |
282 | ||
a4a1c70d MA |
283 | static void qobject_input_check_list(Visitor *v, Error **errp) |
284 | { | |
285 | QObjectInputVisitor *qiv = to_qiv(v); | |
286 | StackObject *tos = QSLIST_FIRST(&qiv->stack); | |
287 | ||
288 | assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST); | |
289 | ||
290 | if (tos->entry) { | |
291 | error_setg(errp, "Only %u list elements expected in %s", | |
292 | tos->index + 1, full_name_nth(qiv, NULL, 1)); | |
293 | } | |
294 | } | |
295 | ||
c40cc0a0 | 296 | |
09e68369 DB |
297 | static void qobject_input_start_alternate(Visitor *v, const char *name, |
298 | GenericAlternate **obj, size_t size, | |
299 | bool promote_int, Error **errp) | |
69dd62df | 300 | { |
09e68369 DB |
301 | QObjectInputVisitor *qiv = to_qiv(v); |
302 | QObject *qobj = qobject_input_get_object(qiv, name, false, errp); | |
69dd62df KW |
303 | |
304 | if (!qobj) { | |
dbf11922 | 305 | *obj = NULL; |
69dd62df KW |
306 | return; |
307 | } | |
dbf11922 EB |
308 | *obj = g_malloc0(size); |
309 | (*obj)->type = qobject_type(qobj); | |
310 | if (promote_int && (*obj)->type == QTYPE_QINT) { | |
311 | (*obj)->type = QTYPE_QFLOAT; | |
d00341af | 312 | } |
69dd62df KW |
313 | } |
314 | ||
09e68369 DB |
315 | static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj, |
316 | Error **errp) | |
c40cc0a0 | 317 | { |
09e68369 DB |
318 | QObjectInputVisitor *qiv = to_qiv(v); |
319 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
1382d4ab | 320 | QInt *qint; |
c40cc0a0 | 321 | |
1382d4ab MAL |
322 | if (!qobj) { |
323 | return; | |
324 | } | |
325 | qint = qobject_to_qint(qobj); | |
fcf73f66 | 326 | if (!qint) { |
a9fc37f6 MA |
327 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
328 | full_name(qiv, name), "integer"); | |
c40cc0a0 MR |
329 | return; |
330 | } | |
331 | ||
fcf73f66 | 332 | *obj = qint_get_int(qint); |
c40cc0a0 MR |
333 | } |
334 | ||
09e68369 DB |
335 | static void qobject_input_type_uint64(Visitor *v, const char *name, |
336 | uint64_t *obj, Error **errp) | |
f755dea7 EB |
337 | { |
338 | /* FIXME: qobject_to_qint mishandles values over INT64_MAX */ | |
09e68369 DB |
339 | QObjectInputVisitor *qiv = to_qiv(v); |
340 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
1382d4ab | 341 | QInt *qint; |
f755dea7 | 342 | |
1382d4ab MAL |
343 | if (!qobj) { |
344 | return; | |
345 | } | |
346 | qint = qobject_to_qint(qobj); | |
f755dea7 | 347 | if (!qint) { |
a9fc37f6 MA |
348 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
349 | full_name(qiv, name), "integer"); | |
f755dea7 EB |
350 | return; |
351 | } | |
352 | ||
353 | *obj = qint_get_int(qint); | |
354 | } | |
355 | ||
09e68369 DB |
356 | static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj, |
357 | Error **errp) | |
c40cc0a0 | 358 | { |
09e68369 DB |
359 | QObjectInputVisitor *qiv = to_qiv(v); |
360 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
1382d4ab | 361 | QBool *qbool; |
c40cc0a0 | 362 | |
1382d4ab MAL |
363 | if (!qobj) { |
364 | return; | |
365 | } | |
366 | qbool = qobject_to_qbool(qobj); | |
14b61600 | 367 | if (!qbool) { |
a9fc37f6 MA |
368 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
369 | full_name(qiv, name), "boolean"); | |
c40cc0a0 MR |
370 | return; |
371 | } | |
372 | ||
14b61600 | 373 | *obj = qbool_get_bool(qbool); |
c40cc0a0 MR |
374 | } |
375 | ||
09e68369 DB |
376 | static void qobject_input_type_str(Visitor *v, const char *name, char **obj, |
377 | Error **errp) | |
c40cc0a0 | 378 | { |
09e68369 DB |
379 | QObjectInputVisitor *qiv = to_qiv(v); |
380 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
1382d4ab | 381 | QString *qstr; |
c40cc0a0 | 382 | |
1382d4ab MAL |
383 | *obj = NULL; |
384 | if (!qobj) { | |
385 | return; | |
386 | } | |
387 | qstr = qobject_to_qstring(qobj); | |
7f027843 | 388 | if (!qstr) { |
a9fc37f6 MA |
389 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
390 | full_name(qiv, name), "string"); | |
c40cc0a0 MR |
391 | return; |
392 | } | |
393 | ||
7f027843 | 394 | *obj = g_strdup(qstring_get_str(qstr)); |
c40cc0a0 MR |
395 | } |
396 | ||
09e68369 DB |
397 | static void qobject_input_type_number(Visitor *v, const char *name, double *obj, |
398 | Error **errp) | |
c40cc0a0 | 399 | { |
09e68369 DB |
400 | QObjectInputVisitor *qiv = to_qiv(v); |
401 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
fcf73f66 MA |
402 | QInt *qint; |
403 | QFloat *qfloat; | |
c40cc0a0 | 404 | |
1382d4ab MAL |
405 | if (!qobj) { |
406 | return; | |
407 | } | |
fcf73f66 MA |
408 | qint = qobject_to_qint(qobj); |
409 | if (qint) { | |
410 | *obj = qint_get_int(qobject_to_qint(qobj)); | |
c40cc0a0 MR |
411 | return; |
412 | } | |
413 | ||
fcf73f66 MA |
414 | qfloat = qobject_to_qfloat(qobj); |
415 | if (qfloat) { | |
1ee51876 | 416 | *obj = qfloat_get_double(qobject_to_qfloat(qobj)); |
fcf73f66 | 417 | return; |
1ee51876 | 418 | } |
fcf73f66 | 419 | |
a9fc37f6 MA |
420 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
421 | full_name(qiv, name), "number"); | |
c40cc0a0 MR |
422 | } |
423 | ||
09e68369 DB |
424 | static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj, |
425 | Error **errp) | |
28770e05 | 426 | { |
09e68369 DB |
427 | QObjectInputVisitor *qiv = to_qiv(v); |
428 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
28770e05 | 429 | |
1382d4ab | 430 | *obj = NULL; |
c4897802 | 431 | if (!qobj) { |
c4897802 MAL |
432 | return; |
433 | } | |
434 | ||
28770e05 MA |
435 | qobject_incref(qobj); |
436 | *obj = qobj; | |
437 | } | |
438 | ||
09e68369 | 439 | static void qobject_input_type_null(Visitor *v, const char *name, Error **errp) |
3bc97fd5 | 440 | { |
09e68369 DB |
441 | QObjectInputVisitor *qiv = to_qiv(v); |
442 | QObject *qobj = qobject_input_get_object(qiv, name, true, errp); | |
3df016f1 | 443 | |
c4897802 | 444 | if (!qobj) { |
c4897802 MAL |
445 | return; |
446 | } | |
447 | ||
3df016f1 | 448 | if (qobject_type(qobj) != QTYPE_QNULL) { |
a9fc37f6 MA |
449 | error_setg(errp, QERR_INVALID_PARAMETER_TYPE, |
450 | full_name(qiv, name), "null"); | |
3df016f1 | 451 | } |
3bc97fd5 EB |
452 | } |
453 | ||
09e68369 | 454 | static void qobject_input_optional(Visitor *v, const char *name, bool *present) |
c40cc0a0 | 455 | { |
09e68369 | 456 | QObjectInputVisitor *qiv = to_qiv(v); |
a9fc37f6 | 457 | QObject *qobj = qobject_input_try_get_object(qiv, name, false); |
c40cc0a0 MR |
458 | |
459 | if (!qobj) { | |
460 | *present = false; | |
461 | return; | |
462 | } | |
463 | ||
464 | *present = true; | |
465 | } | |
466 | ||
09e68369 | 467 | static void qobject_input_free(Visitor *v) |
2c0ef9f4 | 468 | { |
09e68369 | 469 | QObjectInputVisitor *qiv = to_qiv(v); |
a9fc37f6 | 470 | |
3d344c2a PB |
471 | while (!QSLIST_EMPTY(&qiv->stack)) { |
472 | StackObject *tos = QSLIST_FIRST(&qiv->stack); | |
473 | ||
474 | QSLIST_REMOVE_HEAD(&qiv->stack, node); | |
09e68369 | 475 | qobject_input_stack_object_free(tos); |
3d344c2a | 476 | } |
2c0ef9f4 | 477 | |
b70ce101 | 478 | qobject_decref(qiv->root); |
a9fc37f6 MA |
479 | if (qiv->errname) { |
480 | g_string_free(qiv->errname, TRUE); | |
481 | } | |
b70ce101 | 482 | g_free(qiv); |
2c0ef9f4 EB |
483 | } |
484 | ||
048abb7b | 485 | Visitor *qobject_input_visitor_new(QObject *obj) |
c40cc0a0 | 486 | { |
09e68369 | 487 | QObjectInputVisitor *v; |
c40cc0a0 | 488 | |
5d0cbbcf | 489 | assert(obj); |
7267c094 | 490 | v = g_malloc0(sizeof(*v)); |
c40cc0a0 | 491 | |
983f52d4 | 492 | v->visitor.type = VISITOR_INPUT; |
09e68369 DB |
493 | v->visitor.start_struct = qobject_input_start_struct; |
494 | v->visitor.check_struct = qobject_input_check_struct; | |
495 | v->visitor.end_struct = qobject_input_pop; | |
496 | v->visitor.start_list = qobject_input_start_list; | |
497 | v->visitor.next_list = qobject_input_next_list; | |
a4a1c70d | 498 | v->visitor.check_list = qobject_input_check_list; |
09e68369 DB |
499 | v->visitor.end_list = qobject_input_pop; |
500 | v->visitor.start_alternate = qobject_input_start_alternate; | |
501 | v->visitor.type_int64 = qobject_input_type_int64; | |
502 | v->visitor.type_uint64 = qobject_input_type_uint64; | |
503 | v->visitor.type_bool = qobject_input_type_bool; | |
504 | v->visitor.type_str = qobject_input_type_str; | |
505 | v->visitor.type_number = qobject_input_type_number; | |
506 | v->visitor.type_any = qobject_input_type_any; | |
507 | v->visitor.type_null = qobject_input_type_null; | |
508 | v->visitor.optional = qobject_input_optional; | |
509 | v->visitor.free = qobject_input_free; | |
c40cc0a0 | 510 | |
ce140b17 | 511 | v->root = obj; |
4faaec6a | 512 | qobject_incref(obj); |
c40cc0a0 | 513 | |
b70ce101 | 514 | return &v->visitor; |
c40cc0a0 | 515 | } |