]> git.proxmox.com Git - mirror_qemu.git/blame - qapi/qobject-input-visitor.c
qapi: Factor out common part of qobject input visitor creation
[mirror_qemu.git] / qapi / qobject-input-visitor.c
CommitLineData
c40cc0a0
MR
1/*
2 * Input Visitor
3 *
cbd8acf3 4 * Copyright (C) 2012-2017 Red Hat, Inc.
c40cc0a0
MR
5 * 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
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"
cbd8acf3 23#include "qemu/cutils.h"
c40cc0a0 24
a9fc37f6
MA
25typedef struct StackObject {
26 const char *name; /* Name of @obj in its parent, if any */
27 QObject *obj; /* QDict or QList being visited */
1158bb2a 28 void *qapi; /* sanity check that caller uses same pointer */
b471d012 29
a9fc37f6
MA
30 GHashTable *h; /* If @obj is QDict: unvisited keys */
31 const QListEntry *entry; /* If @obj is QList: unvisited tail */
32 unsigned index; /* If @obj is QList: list index of @entry */
3d344c2a 33
a9fc37f6 34 QSLIST_ENTRY(StackObject) node; /* parent */
c40cc0a0
MR
35} StackObject;
36
a9fc37f6 37struct QObjectInputVisitor {
c40cc0a0 38 Visitor visitor;
b471d012 39
ce140b17
EB
40 /* Root of visit at visitor creation. */
41 QObject *root;
42
43 /* Stack of objects being visited (all entries will be either
44 * QDict or QList). */
3d344c2a 45 QSLIST_HEAD(, StackObject) stack;
b471d012 46
a9fc37f6 47 GString *errname; /* Accumulator for full_name() */
c40cc0a0
MR
48};
49
09e68369 50static QObjectInputVisitor *to_qiv(Visitor *v)
c40cc0a0 51{
09e68369 52 return container_of(v, QObjectInputVisitor, visitor);
c40cc0a0
MR
53}
54
a4a1c70d
MA
55static const char *full_name_nth(QObjectInputVisitor *qiv, const char *name,
56 int n)
a9fc37f6
MA
57{
58 StackObject *so;
59 char buf[32];
60
61 if (qiv->errname) {
62 g_string_truncate(qiv->errname, 0);
63 } else {
64 qiv->errname = g_string_new("");
65 }
66
67 QSLIST_FOREACH(so , &qiv->stack, node) {
a4a1c70d
MA
68 if (n) {
69 n--;
70 } else if (qobject_type(so->obj) == QTYPE_QDICT) {
71 g_string_prepend(qiv->errname, name ?: "<anonymous>");
a9fc37f6
MA
72 g_string_prepend_c(qiv->errname, '.');
73 } else {
74 snprintf(buf, sizeof(buf), "[%u]", so->index);
75 g_string_prepend(qiv->errname, buf);
76 }
77 name = so->name;
78 }
a4a1c70d 79 assert(!n);
a9fc37f6
MA
80
81 if (name) {
82 g_string_prepend(qiv->errname, name);
83 } else if (qiv->errname->str[0] == '.') {
84 g_string_erase(qiv->errname, 0, 1);
a4a1c70d 85 } else if (!qiv->errname->str[0]) {
a9fc37f6
MA
86 return "<anonymous>";
87 }
88
89 return qiv->errname->str;
90}
91
a4a1c70d
MA
92static const char *full_name(QObjectInputVisitor *qiv, const char *name)
93{
94 return full_name_nth(qiv, name, 0);
95}
96
a9fc37f6
MA
97static QObject *qobject_input_try_get_object(QObjectInputVisitor *qiv,
98 const char *name,
99 bool consume)
c40cc0a0 100{
ce140b17
EB
101 StackObject *tos;
102 QObject *qobj;
e5826a2f 103 QObject *ret;
b471d012 104
3d344c2a 105 if (QSLIST_EMPTY(&qiv->stack)) {
ce140b17 106 /* Starting at root, name is ignored. */
5d0cbbcf 107 assert(qiv->root);
ce140b17
EB
108 return qiv->root;
109 }
110
111 /* We are in a container; find the next element. */
3d344c2a 112 tos = QSLIST_FIRST(&qiv->stack);
ce140b17 113 qobj = tos->obj;
b471d012
EB
114 assert(qobj);
115
ce140b17
EB
116 if (qobject_type(qobj) == QTYPE_QDICT) {
117 assert(name);
e5826a2f
EB
118 ret = qdict_get(qobject_to_qdict(qobj), name);
119 if (tos->h && consume && ret) {
120 bool removed = g_hash_table_remove(tos->h, name);
121 assert(removed);
47c6d3ec 122 }
ce140b17 123 } else {
b471d012 124 assert(qobject_type(qobj) == QTYPE_QLIST);
ce140b17 125 assert(!name);
1f41a645
MA
126 if (tos->entry) {
127 ret = qlist_entry_obj(tos->entry);
128 if (consume) {
129 tos->entry = qlist_next(tos->entry);
130 }
131 } else {
132 ret = NULL;
133 }
fcf3cb21 134 if (consume) {
a9fc37f6 135 tos->index++;
fcf3cb21 136 }
c40cc0a0
MR
137 }
138
ce140b17 139 return ret;
c40cc0a0
MR
140}
141
a9fc37f6
MA
142static QObject *qobject_input_get_object(QObjectInputVisitor *qiv,
143 const char *name,
144 bool consume, Error **errp)
145{
146 QObject *obj = qobject_input_try_get_object(qiv, name, consume);
147
148 if (!obj) {
149 error_setg(errp, QERR_MISSING_PARAMETER, full_name(qiv, name));
150 }
151 return obj;
152}
153
e38ac962
PB
154static void qdict_add_key(const char *key, QObject *obj, void *opaque)
155{
156 GHashTable *h = opaque;
157 g_hash_table_insert(h, (gpointer) key, NULL);
158}
159
09e68369 160static const QListEntry *qobject_input_push(QObjectInputVisitor *qiv,
a9fc37f6 161 const char *name,
b8874fbf 162 QObject *obj, void *qapi)
c40cc0a0 163{
e38ac962 164 GHashTable *h;
3d344c2a 165 StackObject *tos = g_new0(StackObject, 1);
c40cc0a0 166
b471d012 167 assert(obj);
a9fc37f6 168 tos->name = name;
b471d012 169 tos->obj = obj;
1158bb2a 170 tos->qapi = qapi;
e38ac962 171
048abb7b 172 if (qobject_type(obj) == QTYPE_QDICT) {
e38ac962
PB
173 h = g_hash_table_new(g_str_hash, g_str_equal);
174 qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
b471d012 175 tos->h = h;
048abb7b
MA
176 } else {
177 assert(qobject_type(obj) == QTYPE_QLIST);
fcf3cb21 178 tos->entry = qlist_first(qobject_to_qlist(obj));
a9fc37f6 179 tos->index = -1;
e38ac962
PB
180 }
181
3d344c2a 182 QSLIST_INSERT_HEAD(&qiv->stack, tos, node);
d9f62dde 183 return tos->entry;
c40cc0a0
MR
184}
185
57a33d89 186
09e68369 187static void qobject_input_check_struct(Visitor *v, Error **errp)
c40cc0a0 188{
09e68369 189 QObjectInputVisitor *qiv = to_qiv(v);
3d344c2a 190 StackObject *tos = QSLIST_FIRST(&qiv->stack);
048abb7b
MA
191 GHashTableIter iter;
192 const char *key;
e38ac962 193
3d344c2a 194 assert(tos && !tos->entry);
048abb7b
MA
195
196 g_hash_table_iter_init(&iter, tos->h);
197 if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
198 error_setg(errp, "Parameter '%s' is unexpected",
199 full_name(qiv, key));
15c2f669
EB
200 }
201}
202
09e68369 203static void qobject_input_stack_object_free(StackObject *tos)
15c2f669 204{
3d344c2a
PB
205 if (tos->h) {
206 g_hash_table_unref(tos->h);
207 }
15c2f669 208
3d344c2a
PB
209 g_free(tos);
210}
15c2f669 211
09e68369 212static void qobject_input_pop(Visitor *v, void **obj)
3d344c2a 213{
09e68369 214 QObjectInputVisitor *qiv = to_qiv(v);
3d344c2a 215 StackObject *tos = QSLIST_FIRST(&qiv->stack);
e38ac962 216
3d344c2a
PB
217 assert(tos && tos->qapi == obj);
218 QSLIST_REMOVE_HEAD(&qiv->stack, node);
09e68369 219 qobject_input_stack_object_free(tos);
c40cc0a0
MR
220}
221
09e68369
DB
222static void qobject_input_start_struct(Visitor *v, const char *name, void **obj,
223 size_t size, Error **errp)
c40cc0a0 224{
09e68369
DB
225 QObjectInputVisitor *qiv = to_qiv(v);
226 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
c40cc0a0 227
e58d695e
EB
228 if (obj) {
229 *obj = NULL;
230 }
1382d4ab
MAL
231 if (!qobj) {
232 return;
233 }
234 if (qobject_type(qobj) != QTYPE_QDICT) {
a9fc37f6
MA
235 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
236 full_name(qiv, name), "object");
c40cc0a0
MR
237 return;
238 }
239
a9fc37f6 240 qobject_input_push(qiv, name, qobj, obj);
c40cc0a0
MR
241
242 if (obj) {
7267c094 243 *obj = g_malloc0(size);
c40cc0a0
MR
244 }
245}
246
c40cc0a0 247
09e68369
DB
248static void qobject_input_start_list(Visitor *v, const char *name,
249 GenericList **list, size_t size,
250 Error **errp)
c40cc0a0 251{
09e68369
DB
252 QObjectInputVisitor *qiv = to_qiv(v);
253 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
d9f62dde 254 const QListEntry *entry;
c40cc0a0 255
58561c27
MA
256 if (list) {
257 *list = NULL;
258 }
1382d4ab
MAL
259 if (!qobj) {
260 return;
261 }
262 if (qobject_type(qobj) != QTYPE_QLIST) {
a9fc37f6
MA
263 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
264 full_name(qiv, name), "array");
c40cc0a0
MR
265 return;
266 }
267
a9fc37f6 268 entry = qobject_input_push(qiv, name, qobj, list);
58561c27
MA
269 if (entry && list) {
270 *list = g_malloc0(size);
d9f62dde 271 }
c40cc0a0
MR
272}
273
09e68369
DB
274static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail,
275 size_t size)
c40cc0a0 276{
09e68369 277 QObjectInputVisitor *qiv = to_qiv(v);
a4a1c70d
MA
278 StackObject *tos = QSLIST_FIRST(&qiv->stack);
279
280 assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
c40cc0a0 281
a4a1c70d 282 if (!tos->entry) {
c40cc0a0
MR
283 return NULL;
284 }
d9f62dde
EB
285 tail->next = g_malloc0(size);
286 return tail->next;
c40cc0a0
MR
287}
288
a4a1c70d
MA
289static void qobject_input_check_list(Visitor *v, Error **errp)
290{
291 QObjectInputVisitor *qiv = to_qiv(v);
292 StackObject *tos = QSLIST_FIRST(&qiv->stack);
293
294 assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
295
296 if (tos->entry) {
297 error_setg(errp, "Only %u list elements expected in %s",
298 tos->index + 1, full_name_nth(qiv, NULL, 1));
299 }
300}
301
c40cc0a0 302
09e68369
DB
303static void qobject_input_start_alternate(Visitor *v, const char *name,
304 GenericAlternate **obj, size_t size,
305 bool promote_int, Error **errp)
69dd62df 306{
09e68369
DB
307 QObjectInputVisitor *qiv = to_qiv(v);
308 QObject *qobj = qobject_input_get_object(qiv, name, false, errp);
69dd62df
KW
309
310 if (!qobj) {
dbf11922 311 *obj = NULL;
69dd62df
KW
312 return;
313 }
dbf11922
EB
314 *obj = g_malloc0(size);
315 (*obj)->type = qobject_type(qobj);
316 if (promote_int && (*obj)->type == QTYPE_QINT) {
317 (*obj)->type = QTYPE_QFLOAT;
d00341af 318 }
69dd62df
KW
319}
320
09e68369
DB
321static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
322 Error **errp)
c40cc0a0 323{
09e68369
DB
324 QObjectInputVisitor *qiv = to_qiv(v);
325 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 326 QInt *qint;
c40cc0a0 327
1382d4ab
MAL
328 if (!qobj) {
329 return;
330 }
331 qint = qobject_to_qint(qobj);
fcf73f66 332 if (!qint) {
a9fc37f6
MA
333 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
334 full_name(qiv, name), "integer");
c40cc0a0
MR
335 return;
336 }
337
fcf73f66 338 *obj = qint_get_int(qint);
c40cc0a0
MR
339}
340
cbd8acf3
DB
341
342static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
343 int64_t *obj, Error **errp)
344{
345 QObjectInputVisitor *qiv = to_qiv(v);
346 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
347 QString *qstr;
348
349 if (!qobj) {
350 return;
351 }
352 qstr = qobject_to_qstring(qobj);
353 if (!qstr) {
354 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
355 full_name(qiv, name), "string");
356 return;
357 }
358
359 if (qemu_strtoi64(qstring_get_str(qstr), NULL, 0, obj) < 0) {
360 /* TODO report -ERANGE more nicely */
361 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
362 full_name(qiv, name), "integer");
363 }
364}
365
09e68369
DB
366static void qobject_input_type_uint64(Visitor *v, const char *name,
367 uint64_t *obj, Error **errp)
f755dea7
EB
368{
369 /* FIXME: qobject_to_qint mishandles values over INT64_MAX */
09e68369
DB
370 QObjectInputVisitor *qiv = to_qiv(v);
371 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 372 QInt *qint;
f755dea7 373
1382d4ab
MAL
374 if (!qobj) {
375 return;
376 }
377 qint = qobject_to_qint(qobj);
f755dea7 378 if (!qint) {
a9fc37f6
MA
379 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
380 full_name(qiv, name), "integer");
f755dea7
EB
381 return;
382 }
383
384 *obj = qint_get_int(qint);
385}
386
cbd8acf3
DB
387static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
388 uint64_t *obj, Error **errp)
389{
390 QObjectInputVisitor *qiv = to_qiv(v);
391 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
392 QString *qstr;
393
394 if (!qobj) {
395 return;
396 }
397 qstr = qobject_to_qstring(qobj);
398 if (!qstr) {
399 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
400 full_name(qiv, name), "string");
401 return;
402 }
403
404 if (qemu_strtou64(qstring_get_str(qstr), NULL, 0, obj) < 0) {
405 /* TODO report -ERANGE more nicely */
406 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
407 full_name(qiv, name), "integer");
408 }
409}
410
09e68369
DB
411static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj,
412 Error **errp)
c40cc0a0 413{
09e68369
DB
414 QObjectInputVisitor *qiv = to_qiv(v);
415 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 416 QBool *qbool;
c40cc0a0 417
1382d4ab
MAL
418 if (!qobj) {
419 return;
420 }
421 qbool = qobject_to_qbool(qobj);
14b61600 422 if (!qbool) {
a9fc37f6
MA
423 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
424 full_name(qiv, name), "boolean");
c40cc0a0
MR
425 return;
426 }
427
14b61600 428 *obj = qbool_get_bool(qbool);
c40cc0a0
MR
429}
430
cbd8acf3
DB
431static void qobject_input_type_bool_keyval(Visitor *v, const char *name,
432 bool *obj, Error **errp)
433{
434 QObjectInputVisitor *qiv = to_qiv(v);
435 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
436 QString *qstr;
437 const char *str;
438
439 if (!qobj) {
440 return;
441 }
442 qstr = qobject_to_qstring(qobj);
443 if (!qstr) {
444 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
445 full_name(qiv, name), "string");
446 return;
447 }
448
449 str = qstring_get_str(qstr);
450 if (!strcmp(str, "on")) {
451 *obj = true;
452 } else if (!strcmp(str, "off")) {
453 *obj = false;
454 } else {
455 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
456 full_name(qiv, name), "'on' or 'off'");
457 }
458}
459
09e68369
DB
460static void qobject_input_type_str(Visitor *v, const char *name, char **obj,
461 Error **errp)
c40cc0a0 462{
09e68369
DB
463 QObjectInputVisitor *qiv = to_qiv(v);
464 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 465 QString *qstr;
c40cc0a0 466
1382d4ab
MAL
467 *obj = NULL;
468 if (!qobj) {
469 return;
470 }
471 qstr = qobject_to_qstring(qobj);
7f027843 472 if (!qstr) {
a9fc37f6
MA
473 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
474 full_name(qiv, name), "string");
c40cc0a0
MR
475 return;
476 }
477
7f027843 478 *obj = g_strdup(qstring_get_str(qstr));
c40cc0a0
MR
479}
480
09e68369
DB
481static void qobject_input_type_number(Visitor *v, const char *name, double *obj,
482 Error **errp)
c40cc0a0 483{
09e68369
DB
484 QObjectInputVisitor *qiv = to_qiv(v);
485 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
fcf73f66
MA
486 QInt *qint;
487 QFloat *qfloat;
c40cc0a0 488
1382d4ab
MAL
489 if (!qobj) {
490 return;
491 }
fcf73f66
MA
492 qint = qobject_to_qint(qobj);
493 if (qint) {
494 *obj = qint_get_int(qobject_to_qint(qobj));
c40cc0a0
MR
495 return;
496 }
497
fcf73f66
MA
498 qfloat = qobject_to_qfloat(qobj);
499 if (qfloat) {
1ee51876 500 *obj = qfloat_get_double(qobject_to_qfloat(qobj));
fcf73f66 501 return;
1ee51876 502 }
fcf73f66 503
a9fc37f6
MA
504 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
505 full_name(qiv, name), "number");
c40cc0a0
MR
506}
507
cbd8acf3
DB
508static void qobject_input_type_number_keyval(Visitor *v, const char *name,
509 double *obj, Error **errp)
510{
511 QObjectInputVisitor *qiv = to_qiv(v);
512 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
513 QString *qstr;
514 const char *str;
515 char *endp;
516
517 if (!qobj) {
518 return;
519 }
520 qstr = qobject_to_qstring(qobj);
521 if (!qstr) {
522 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
523 full_name(qiv, name), "string");
524 return;
525 }
526
527 str = qstring_get_str(qstr);
528 errno = 0;
529 *obj = strtod(str, &endp);
530 if (errno || endp == str || *endp) {
531 /* TODO report -ERANGE more nicely */
532 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
533 full_name(qiv, name), "number");
534 }
535}
536
09e68369
DB
537static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj,
538 Error **errp)
28770e05 539{
09e68369
DB
540 QObjectInputVisitor *qiv = to_qiv(v);
541 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
28770e05 542
1382d4ab 543 *obj = NULL;
c4897802 544 if (!qobj) {
c4897802
MAL
545 return;
546 }
547
28770e05
MA
548 qobject_incref(qobj);
549 *obj = qobj;
550}
551
09e68369 552static void qobject_input_type_null(Visitor *v, const char *name, Error **errp)
3bc97fd5 553{
09e68369
DB
554 QObjectInputVisitor *qiv = to_qiv(v);
555 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
3df016f1 556
c4897802 557 if (!qobj) {
c4897802
MAL
558 return;
559 }
560
3df016f1 561 if (qobject_type(qobj) != QTYPE_QNULL) {
a9fc37f6
MA
562 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
563 full_name(qiv, name), "null");
3df016f1 564 }
3bc97fd5
EB
565}
566
cbd8acf3
DB
567static void qobject_input_type_size_keyval(Visitor *v, const char *name,
568 uint64_t *obj, Error **errp)
569{
570 QObjectInputVisitor *qiv = to_qiv(v);
571 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
572 QString *qstr;
573
574 if (!qobj) {
575 return;
576 }
577 qstr = qobject_to_qstring(qobj);
578 if (!qstr) {
579 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
580 full_name(qiv, name), "string");
581 return;
582 }
583
584 if (qemu_strtosz(qstring_get_str(qstr), NULL, obj) < 0) {
585 /* TODO report -ERANGE more nicely */
586 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
587 full_name(qiv, name), "size");
588 }
589}
590
09e68369 591static void qobject_input_optional(Visitor *v, const char *name, bool *present)
c40cc0a0 592{
09e68369 593 QObjectInputVisitor *qiv = to_qiv(v);
a9fc37f6 594 QObject *qobj = qobject_input_try_get_object(qiv, name, false);
c40cc0a0
MR
595
596 if (!qobj) {
597 *present = false;
598 return;
599 }
600
601 *present = true;
602}
603
09e68369 604static void qobject_input_free(Visitor *v)
2c0ef9f4 605{
09e68369 606 QObjectInputVisitor *qiv = to_qiv(v);
a9fc37f6 607
3d344c2a
PB
608 while (!QSLIST_EMPTY(&qiv->stack)) {
609 StackObject *tos = QSLIST_FIRST(&qiv->stack);
610
611 QSLIST_REMOVE_HEAD(&qiv->stack, node);
09e68369 612 qobject_input_stack_object_free(tos);
3d344c2a 613 }
2c0ef9f4 614
b70ce101 615 qobject_decref(qiv->root);
a9fc37f6
MA
616 if (qiv->errname) {
617 g_string_free(qiv->errname, TRUE);
618 }
b70ce101 619 g_free(qiv);
2c0ef9f4
EB
620}
621
abe81bc2 622static QObjectInputVisitor *qobject_input_visitor_base_new(QObject *obj)
c40cc0a0 623{
abe81bc2 624 QObjectInputVisitor *v = g_malloc0(sizeof(*v));
c40cc0a0 625
5d0cbbcf 626 assert(obj);
c40cc0a0 627
983f52d4 628 v->visitor.type = VISITOR_INPUT;
09e68369
DB
629 v->visitor.start_struct = qobject_input_start_struct;
630 v->visitor.check_struct = qobject_input_check_struct;
631 v->visitor.end_struct = qobject_input_pop;
632 v->visitor.start_list = qobject_input_start_list;
633 v->visitor.next_list = qobject_input_next_list;
a4a1c70d 634 v->visitor.check_list = qobject_input_check_list;
09e68369
DB
635 v->visitor.end_list = qobject_input_pop;
636 v->visitor.start_alternate = qobject_input_start_alternate;
abe81bc2
MA
637 v->visitor.optional = qobject_input_optional;
638 v->visitor.free = qobject_input_free;
639
640 v->root = obj;
641 qobject_incref(obj);
642
643 return v;
644}
645
646Visitor *qobject_input_visitor_new(QObject *obj)
647{
648 QObjectInputVisitor *v = qobject_input_visitor_base_new(obj);
649
09e68369
DB
650 v->visitor.type_int64 = qobject_input_type_int64;
651 v->visitor.type_uint64 = qobject_input_type_uint64;
652 v->visitor.type_bool = qobject_input_type_bool;
653 v->visitor.type_str = qobject_input_type_str;
654 v->visitor.type_number = qobject_input_type_number;
655 v->visitor.type_any = qobject_input_type_any;
656 v->visitor.type_null = qobject_input_type_null;
c40cc0a0 657
b70ce101 658 return &v->visitor;
c40cc0a0 659}
cbd8acf3
DB
660
661Visitor *qobject_input_visitor_new_keyval(QObject *obj)
662{
abe81bc2 663 QObjectInputVisitor *v = qobject_input_visitor_base_new(obj);
cbd8acf3 664
cbd8acf3
DB
665 v->visitor.type_int64 = qobject_input_type_int64_keyval;
666 v->visitor.type_uint64 = qobject_input_type_uint64_keyval;
667 v->visitor.type_bool = qobject_input_type_bool_keyval;
668 v->visitor.type_str = qobject_input_type_str;
669 v->visitor.type_number = qobject_input_type_number_keyval;
670 v->visitor.type_any = qobject_input_type_any;
671 v->visitor.type_null = qobject_input_type_null;
672 v->visitor.type_size = qobject_input_type_size_keyval;
cbd8acf3
DB
673
674 return &v->visitor;
675}