]> git.proxmox.com Git - mirror_qemu.git/blame - qapi/qobject-input-visitor.c
qapi: Factor out common qobject_input_get_keyval()
[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
e3934b42
MA
154static const char *qobject_input_get_keyval(QObjectInputVisitor *qiv,
155 const char *name,
156 Error **errp)
157{
158 QObject *qobj;
159 QString *qstr;
160
161 qobj = qobject_input_get_object(qiv, name, true, errp);
162 if (!qobj) {
163 return NULL;
164 }
165
166 qstr = qobject_to_qstring(qobj);
167 if (!qstr) {
168 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
169 full_name(qiv, name), "string");
170 return NULL;
171 }
172
173 return qstring_get_str(qstr);
174}
175
e38ac962
PB
176static void qdict_add_key(const char *key, QObject *obj, void *opaque)
177{
178 GHashTable *h = opaque;
179 g_hash_table_insert(h, (gpointer) key, NULL);
180}
181
09e68369 182static const QListEntry *qobject_input_push(QObjectInputVisitor *qiv,
a9fc37f6 183 const char *name,
b8874fbf 184 QObject *obj, void *qapi)
c40cc0a0 185{
e38ac962 186 GHashTable *h;
3d344c2a 187 StackObject *tos = g_new0(StackObject, 1);
c40cc0a0 188
b471d012 189 assert(obj);
a9fc37f6 190 tos->name = name;
b471d012 191 tos->obj = obj;
1158bb2a 192 tos->qapi = qapi;
e38ac962 193
048abb7b 194 if (qobject_type(obj) == QTYPE_QDICT) {
e38ac962
PB
195 h = g_hash_table_new(g_str_hash, g_str_equal);
196 qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
b471d012 197 tos->h = h;
048abb7b
MA
198 } else {
199 assert(qobject_type(obj) == QTYPE_QLIST);
fcf3cb21 200 tos->entry = qlist_first(qobject_to_qlist(obj));
a9fc37f6 201 tos->index = -1;
e38ac962
PB
202 }
203
3d344c2a 204 QSLIST_INSERT_HEAD(&qiv->stack, tos, node);
d9f62dde 205 return tos->entry;
c40cc0a0
MR
206}
207
57a33d89 208
09e68369 209static void qobject_input_check_struct(Visitor *v, Error **errp)
c40cc0a0 210{
09e68369 211 QObjectInputVisitor *qiv = to_qiv(v);
3d344c2a 212 StackObject *tos = QSLIST_FIRST(&qiv->stack);
048abb7b
MA
213 GHashTableIter iter;
214 const char *key;
e38ac962 215
3d344c2a 216 assert(tos && !tos->entry);
048abb7b
MA
217
218 g_hash_table_iter_init(&iter, tos->h);
219 if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
220 error_setg(errp, "Parameter '%s' is unexpected",
221 full_name(qiv, key));
15c2f669
EB
222 }
223}
224
09e68369 225static void qobject_input_stack_object_free(StackObject *tos)
15c2f669 226{
3d344c2a
PB
227 if (tos->h) {
228 g_hash_table_unref(tos->h);
229 }
15c2f669 230
3d344c2a
PB
231 g_free(tos);
232}
15c2f669 233
09e68369 234static void qobject_input_pop(Visitor *v, void **obj)
3d344c2a 235{
09e68369 236 QObjectInputVisitor *qiv = to_qiv(v);
3d344c2a 237 StackObject *tos = QSLIST_FIRST(&qiv->stack);
e38ac962 238
3d344c2a
PB
239 assert(tos && tos->qapi == obj);
240 QSLIST_REMOVE_HEAD(&qiv->stack, node);
09e68369 241 qobject_input_stack_object_free(tos);
c40cc0a0
MR
242}
243
09e68369
DB
244static void qobject_input_start_struct(Visitor *v, const char *name, void **obj,
245 size_t size, Error **errp)
c40cc0a0 246{
09e68369
DB
247 QObjectInputVisitor *qiv = to_qiv(v);
248 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
c40cc0a0 249
e58d695e
EB
250 if (obj) {
251 *obj = NULL;
252 }
1382d4ab
MAL
253 if (!qobj) {
254 return;
255 }
256 if (qobject_type(qobj) != QTYPE_QDICT) {
a9fc37f6
MA
257 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
258 full_name(qiv, name), "object");
c40cc0a0
MR
259 return;
260 }
261
a9fc37f6 262 qobject_input_push(qiv, name, qobj, obj);
c40cc0a0
MR
263
264 if (obj) {
7267c094 265 *obj = g_malloc0(size);
c40cc0a0
MR
266 }
267}
268
c40cc0a0 269
09e68369
DB
270static void qobject_input_start_list(Visitor *v, const char *name,
271 GenericList **list, size_t size,
272 Error **errp)
c40cc0a0 273{
09e68369
DB
274 QObjectInputVisitor *qiv = to_qiv(v);
275 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
d9f62dde 276 const QListEntry *entry;
c40cc0a0 277
58561c27
MA
278 if (list) {
279 *list = NULL;
280 }
1382d4ab
MAL
281 if (!qobj) {
282 return;
283 }
284 if (qobject_type(qobj) != QTYPE_QLIST) {
a9fc37f6
MA
285 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
286 full_name(qiv, name), "array");
c40cc0a0
MR
287 return;
288 }
289
a9fc37f6 290 entry = qobject_input_push(qiv, name, qobj, list);
58561c27
MA
291 if (entry && list) {
292 *list = g_malloc0(size);
d9f62dde 293 }
c40cc0a0
MR
294}
295
09e68369
DB
296static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail,
297 size_t size)
c40cc0a0 298{
09e68369 299 QObjectInputVisitor *qiv = to_qiv(v);
a4a1c70d
MA
300 StackObject *tos = QSLIST_FIRST(&qiv->stack);
301
302 assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
c40cc0a0 303
a4a1c70d 304 if (!tos->entry) {
c40cc0a0
MR
305 return NULL;
306 }
d9f62dde
EB
307 tail->next = g_malloc0(size);
308 return tail->next;
c40cc0a0
MR
309}
310
a4a1c70d
MA
311static void qobject_input_check_list(Visitor *v, Error **errp)
312{
313 QObjectInputVisitor *qiv = to_qiv(v);
314 StackObject *tos = QSLIST_FIRST(&qiv->stack);
315
316 assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
317
318 if (tos->entry) {
319 error_setg(errp, "Only %u list elements expected in %s",
320 tos->index + 1, full_name_nth(qiv, NULL, 1));
321 }
322}
323
c40cc0a0 324
09e68369
DB
325static void qobject_input_start_alternate(Visitor *v, const char *name,
326 GenericAlternate **obj, size_t size,
327 bool promote_int, Error **errp)
69dd62df 328{
09e68369
DB
329 QObjectInputVisitor *qiv = to_qiv(v);
330 QObject *qobj = qobject_input_get_object(qiv, name, false, errp);
69dd62df
KW
331
332 if (!qobj) {
dbf11922 333 *obj = NULL;
69dd62df
KW
334 return;
335 }
dbf11922
EB
336 *obj = g_malloc0(size);
337 (*obj)->type = qobject_type(qobj);
338 if (promote_int && (*obj)->type == QTYPE_QINT) {
339 (*obj)->type = QTYPE_QFLOAT;
d00341af 340 }
69dd62df
KW
341}
342
09e68369
DB
343static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
344 Error **errp)
c40cc0a0 345{
09e68369
DB
346 QObjectInputVisitor *qiv = to_qiv(v);
347 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 348 QInt *qint;
c40cc0a0 349
1382d4ab
MAL
350 if (!qobj) {
351 return;
352 }
353 qint = qobject_to_qint(qobj);
fcf73f66 354 if (!qint) {
a9fc37f6
MA
355 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
356 full_name(qiv, name), "integer");
c40cc0a0
MR
357 return;
358 }
359
fcf73f66 360 *obj = qint_get_int(qint);
c40cc0a0
MR
361}
362
cbd8acf3
DB
363
364static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
365 int64_t *obj, Error **errp)
366{
367 QObjectInputVisitor *qiv = to_qiv(v);
e3934b42 368 const char *str = qobject_input_get_keyval(qiv, name, errp);
cbd8acf3 369
e3934b42 370 if (!str) {
cbd8acf3
DB
371 return;
372 }
373
e3934b42 374 if (qemu_strtoi64(str, NULL, 0, obj) < 0) {
cbd8acf3
DB
375 /* TODO report -ERANGE more nicely */
376 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
377 full_name(qiv, name), "integer");
378 }
379}
380
09e68369
DB
381static void qobject_input_type_uint64(Visitor *v, const char *name,
382 uint64_t *obj, Error **errp)
f755dea7
EB
383{
384 /* FIXME: qobject_to_qint mishandles values over INT64_MAX */
09e68369
DB
385 QObjectInputVisitor *qiv = to_qiv(v);
386 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 387 QInt *qint;
f755dea7 388
1382d4ab
MAL
389 if (!qobj) {
390 return;
391 }
392 qint = qobject_to_qint(qobj);
f755dea7 393 if (!qint) {
a9fc37f6
MA
394 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
395 full_name(qiv, name), "integer");
f755dea7
EB
396 return;
397 }
398
399 *obj = qint_get_int(qint);
400}
401
cbd8acf3
DB
402static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
403 uint64_t *obj, Error **errp)
404{
405 QObjectInputVisitor *qiv = to_qiv(v);
e3934b42 406 const char *str = qobject_input_get_keyval(qiv, name, errp);
cbd8acf3 407
e3934b42 408 if (!str) {
cbd8acf3
DB
409 return;
410 }
411
e3934b42 412 if (qemu_strtou64(str, NULL, 0, obj) < 0) {
cbd8acf3
DB
413 /* TODO report -ERANGE more nicely */
414 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
415 full_name(qiv, name), "integer");
416 }
417}
418
09e68369
DB
419static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj,
420 Error **errp)
c40cc0a0 421{
09e68369
DB
422 QObjectInputVisitor *qiv = to_qiv(v);
423 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 424 QBool *qbool;
c40cc0a0 425
1382d4ab
MAL
426 if (!qobj) {
427 return;
428 }
429 qbool = qobject_to_qbool(qobj);
14b61600 430 if (!qbool) {
a9fc37f6
MA
431 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
432 full_name(qiv, name), "boolean");
c40cc0a0
MR
433 return;
434 }
435
14b61600 436 *obj = qbool_get_bool(qbool);
c40cc0a0
MR
437}
438
cbd8acf3
DB
439static void qobject_input_type_bool_keyval(Visitor *v, const char *name,
440 bool *obj, Error **errp)
441{
442 QObjectInputVisitor *qiv = to_qiv(v);
e3934b42 443 const char *str = qobject_input_get_keyval(qiv, name, errp);
cbd8acf3 444
e3934b42 445 if (!str) {
cbd8acf3
DB
446 return;
447 }
448
cbd8acf3
DB
449 if (!strcmp(str, "on")) {
450 *obj = true;
451 } else if (!strcmp(str, "off")) {
452 *obj = false;
453 } else {
454 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
455 full_name(qiv, name), "'on' or 'off'");
456 }
457}
458
09e68369
DB
459static void qobject_input_type_str(Visitor *v, const char *name, char **obj,
460 Error **errp)
c40cc0a0 461{
09e68369
DB
462 QObjectInputVisitor *qiv = to_qiv(v);
463 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
1382d4ab 464 QString *qstr;
c40cc0a0 465
1382d4ab
MAL
466 *obj = NULL;
467 if (!qobj) {
468 return;
469 }
470 qstr = qobject_to_qstring(qobj);
7f027843 471 if (!qstr) {
a9fc37f6
MA
472 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
473 full_name(qiv, name), "string");
c40cc0a0
MR
474 return;
475 }
476
7f027843 477 *obj = g_strdup(qstring_get_str(qstr));
c40cc0a0
MR
478}
479
09e68369
DB
480static void qobject_input_type_number(Visitor *v, const char *name, double *obj,
481 Error **errp)
c40cc0a0 482{
09e68369
DB
483 QObjectInputVisitor *qiv = to_qiv(v);
484 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
fcf73f66
MA
485 QInt *qint;
486 QFloat *qfloat;
c40cc0a0 487
1382d4ab
MAL
488 if (!qobj) {
489 return;
490 }
fcf73f66
MA
491 qint = qobject_to_qint(qobj);
492 if (qint) {
493 *obj = qint_get_int(qobject_to_qint(qobj));
c40cc0a0
MR
494 return;
495 }
496
fcf73f66
MA
497 qfloat = qobject_to_qfloat(qobj);
498 if (qfloat) {
1ee51876 499 *obj = qfloat_get_double(qobject_to_qfloat(qobj));
fcf73f66 500 return;
1ee51876 501 }
fcf73f66 502
a9fc37f6
MA
503 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
504 full_name(qiv, name), "number");
c40cc0a0
MR
505}
506
cbd8acf3
DB
507static void qobject_input_type_number_keyval(Visitor *v, const char *name,
508 double *obj, Error **errp)
509{
510 QObjectInputVisitor *qiv = to_qiv(v);
e3934b42 511 const char *str = qobject_input_get_keyval(qiv, name, errp);
cbd8acf3
DB
512 char *endp;
513
e3934b42 514 if (!str) {
cbd8acf3
DB
515 return;
516 }
517
cbd8acf3
DB
518 errno = 0;
519 *obj = strtod(str, &endp);
520 if (errno || endp == str || *endp) {
521 /* TODO report -ERANGE more nicely */
522 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
523 full_name(qiv, name), "number");
524 }
525}
526
09e68369
DB
527static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj,
528 Error **errp)
28770e05 529{
09e68369
DB
530 QObjectInputVisitor *qiv = to_qiv(v);
531 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
28770e05 532
1382d4ab 533 *obj = NULL;
c4897802 534 if (!qobj) {
c4897802
MAL
535 return;
536 }
537
28770e05
MA
538 qobject_incref(qobj);
539 *obj = qobj;
540}
541
09e68369 542static void qobject_input_type_null(Visitor *v, const char *name, Error **errp)
3bc97fd5 543{
09e68369
DB
544 QObjectInputVisitor *qiv = to_qiv(v);
545 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
3df016f1 546
c4897802 547 if (!qobj) {
c4897802
MAL
548 return;
549 }
550
3df016f1 551 if (qobject_type(qobj) != QTYPE_QNULL) {
a9fc37f6
MA
552 error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
553 full_name(qiv, name), "null");
3df016f1 554 }
3bc97fd5
EB
555}
556
cbd8acf3
DB
557static void qobject_input_type_size_keyval(Visitor *v, const char *name,
558 uint64_t *obj, Error **errp)
559{
560 QObjectInputVisitor *qiv = to_qiv(v);
e3934b42 561 const char *str = qobject_input_get_keyval(qiv, name, errp);
cbd8acf3 562
e3934b42 563 if (!str) {
cbd8acf3
DB
564 return;
565 }
566
e3934b42 567 if (qemu_strtosz(str, NULL, obj) < 0) {
cbd8acf3
DB
568 /* TODO report -ERANGE more nicely */
569 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
570 full_name(qiv, name), "size");
571 }
572}
573
09e68369 574static void qobject_input_optional(Visitor *v, const char *name, bool *present)
c40cc0a0 575{
09e68369 576 QObjectInputVisitor *qiv = to_qiv(v);
a9fc37f6 577 QObject *qobj = qobject_input_try_get_object(qiv, name, false);
c40cc0a0
MR
578
579 if (!qobj) {
580 *present = false;
581 return;
582 }
583
584 *present = true;
585}
586
09e68369 587static void qobject_input_free(Visitor *v)
2c0ef9f4 588{
09e68369 589 QObjectInputVisitor *qiv = to_qiv(v);
a9fc37f6 590
3d344c2a
PB
591 while (!QSLIST_EMPTY(&qiv->stack)) {
592 StackObject *tos = QSLIST_FIRST(&qiv->stack);
593
594 QSLIST_REMOVE_HEAD(&qiv->stack, node);
09e68369 595 qobject_input_stack_object_free(tos);
3d344c2a 596 }
2c0ef9f4 597
b70ce101 598 qobject_decref(qiv->root);
a9fc37f6
MA
599 if (qiv->errname) {
600 g_string_free(qiv->errname, TRUE);
601 }
b70ce101 602 g_free(qiv);
2c0ef9f4
EB
603}
604
abe81bc2 605static QObjectInputVisitor *qobject_input_visitor_base_new(QObject *obj)
c40cc0a0 606{
abe81bc2 607 QObjectInputVisitor *v = g_malloc0(sizeof(*v));
c40cc0a0 608
5d0cbbcf 609 assert(obj);
c40cc0a0 610
983f52d4 611 v->visitor.type = VISITOR_INPUT;
09e68369
DB
612 v->visitor.start_struct = qobject_input_start_struct;
613 v->visitor.check_struct = qobject_input_check_struct;
614 v->visitor.end_struct = qobject_input_pop;
615 v->visitor.start_list = qobject_input_start_list;
616 v->visitor.next_list = qobject_input_next_list;
a4a1c70d 617 v->visitor.check_list = qobject_input_check_list;
09e68369
DB
618 v->visitor.end_list = qobject_input_pop;
619 v->visitor.start_alternate = qobject_input_start_alternate;
abe81bc2
MA
620 v->visitor.optional = qobject_input_optional;
621 v->visitor.free = qobject_input_free;
622
623 v->root = obj;
624 qobject_incref(obj);
625
626 return v;
627}
628
629Visitor *qobject_input_visitor_new(QObject *obj)
630{
631 QObjectInputVisitor *v = qobject_input_visitor_base_new(obj);
632
09e68369
DB
633 v->visitor.type_int64 = qobject_input_type_int64;
634 v->visitor.type_uint64 = qobject_input_type_uint64;
635 v->visitor.type_bool = qobject_input_type_bool;
636 v->visitor.type_str = qobject_input_type_str;
637 v->visitor.type_number = qobject_input_type_number;
638 v->visitor.type_any = qobject_input_type_any;
639 v->visitor.type_null = qobject_input_type_null;
c40cc0a0 640
b70ce101 641 return &v->visitor;
c40cc0a0 642}
cbd8acf3
DB
643
644Visitor *qobject_input_visitor_new_keyval(QObject *obj)
645{
abe81bc2 646 QObjectInputVisitor *v = qobject_input_visitor_base_new(obj);
cbd8acf3 647
cbd8acf3
DB
648 v->visitor.type_int64 = qobject_input_type_int64_keyval;
649 v->visitor.type_uint64 = qobject_input_type_uint64_keyval;
650 v->visitor.type_bool = qobject_input_type_bool_keyval;
651 v->visitor.type_str = qobject_input_type_str;
652 v->visitor.type_number = qobject_input_type_number_keyval;
653 v->visitor.type_any = qobject_input_type_any;
654 v->visitor.type_null = qobject_input_type_null;
655 v->visitor.type_size = qobject_input_type_size_keyval;
cbd8acf3
DB
656
657 return &v->visitor;
658}