]> git.proxmox.com Git - mirror_qemu.git/blame - qapi/qapi-visit-core.c
Merge remote-tracking branch 'remotes/dagrh/tags/pull-virtiofs-20211026' into staging
[mirror_qemu.git] / qapi / qapi-visit-core.c
CommitLineData
2345c77c
MR
1/*
2 * Core Definitions for QAPI Visitor Classes
3 *
7c91aabd 4 * Copyright (C) 2012-2016 Red Hat, Inc.
2345c77c
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"
7b1b5d19
PB
17#include "qapi/qmp/qerror.h"
18#include "qapi/visitor.h"
19#include "qapi/visitor-impl.h"
ebfd93b6 20#include "trace.h"
2345c77c 21
3b098d56
EB
22void visit_complete(Visitor *v, void *opaque)
23{
24 assert(v->type != VISITOR_OUTPUT || v->complete);
ebfd93b6 25 trace_visit_complete(v, opaque);
3b098d56
EB
26 if (v->complete) {
27 v->complete(v, opaque);
28 }
29}
30
2c0ef9f4
EB
31void visit_free(Visitor *v)
32{
ebfd93b6 33 trace_visit_free(v);
2c0ef9f4
EB
34 if (v) {
35 v->free(v);
36 }
37}
38
012d4c96 39bool visit_start_struct(Visitor *v, const char *name, void **obj,
337283df 40 size_t size, Error **errp)
2345c77c 41{
7b3cb803 42 bool ok;
e58d695e 43
ebfd93b6 44 trace_visit_start_struct(v, name, obj, size);
adfb264c
EB
45 if (obj) {
46 assert(size);
a15fcc3c 47 assert(!(v->type & VISITOR_OUTPUT) || *obj);
adfb264c 48 }
7b3cb803 49 ok = v->start_struct(v, name, obj, size, errp);
a15fcc3c 50 if (obj && (v->type & VISITOR_INPUT)) {
7b3cb803 51 assert(ok != !*obj);
e58d695e 52 }
7b3cb803 53 return ok;
2345c77c
MR
54}
55
012d4c96 56bool visit_check_struct(Visitor *v, Error **errp)
2345c77c 57{
ebfd93b6 58 trace_visit_check_struct(v);
012d4c96 59 return v->check_struct ? v->check_struct(v, errp) : true;
15c2f669
EB
60}
61
1158bb2a 62void visit_end_struct(Visitor *v, void **obj)
15c2f669 63{
ebfd93b6 64 trace_visit_end_struct(v, obj);
1158bb2a 65 v->end_struct(v, obj);
2345c77c
MR
66}
67
012d4c96 68bool visit_start_list(Visitor *v, const char *name, GenericList **list,
d9f62dde 69 size_t size, Error **errp)
2345c77c 70{
7b3cb803 71 bool ok;
d9f62dde
EB
72
73 assert(!list || size >= sizeof(GenericList));
ebfd93b6 74 trace_visit_start_list(v, name, list, size);
7b3cb803 75 ok = v->start_list(v, name, list, size, errp);
a15fcc3c 76 if (list && (v->type & VISITOR_INPUT)) {
7b3cb803 77 assert(ok || !*list);
d9f62dde 78 }
7b3cb803 79 return ok;
2345c77c
MR
80}
81
d9f62dde 82GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
2345c77c 83{
d9f62dde 84 assert(tail && size >= sizeof(GenericList));
ebfd93b6 85 trace_visit_next_list(v, tail, size);
d9f62dde 86 return v->next_list(v, tail, size);
2345c77c
MR
87}
88
012d4c96 89bool visit_check_list(Visitor *v, Error **errp)
a4a1c70d
MA
90{
91 trace_visit_check_list(v);
012d4c96 92 return v->check_list ? v->check_list(v, errp) : true;
a4a1c70d
MA
93}
94
1158bb2a 95void visit_end_list(Visitor *v, void **obj)
2345c77c 96{
ebfd93b6 97 trace_visit_end_list(v, obj);
1158bb2a 98 v->end_list(v, obj);
2345c77c
MR
99}
100
012d4c96 101bool visit_start_alternate(Visitor *v, const char *name,
dbf11922 102 GenericAlternate **obj, size_t size,
60390d2d 103 Error **errp)
2345c77c 104{
7b3cb803 105 bool ok;
e58d695e 106
dbf11922 107 assert(obj && size >= sizeof(GenericAlternate));
a15fcc3c 108 assert(!(v->type & VISITOR_OUTPUT) || *obj);
60390d2d 109 trace_visit_start_alternate(v, name, obj, size);
7b3cb803
MA
110 if (!v->start_alternate) {
111 assert(!(v->type & VISITOR_INPUT));
112 return true;
e58d695e 113 }
7b3cb803 114 ok = v->start_alternate(v, name, obj, size, errp);
a15fcc3c 115 if (v->type & VISITOR_INPUT) {
7b3cb803 116 assert(ok != !*obj);
dbf11922 117 }
7b3cb803 118 return ok;
dbf11922
EB
119}
120
1158bb2a 121void visit_end_alternate(Visitor *v, void **obj)
dbf11922 122{
ebfd93b6 123 trace_visit_end_alternate(v, obj);
dbf11922 124 if (v->end_alternate) {
1158bb2a 125 v->end_alternate(v, obj);
2345c77c
MR
126 }
127}
128
dbf11922 129bool visit_optional(Visitor *v, const char *name, bool *present)
69dd62df 130{
ebfd93b6 131 trace_visit_optional(v, name, present);
dbf11922
EB
132 if (v->optional) {
133 v->optional(v, name, present);
69dd62df 134 }
dbf11922 135 return *present;
69dd62df
KW
136}
137
db291641
MA
138bool visit_deprecated_accept(Visitor *v, const char *name, Error **errp)
139{
140 trace_visit_deprecated_accept(v, name);
141 if (v->deprecated_accept) {
142 return v->deprecated_accept(v, name, errp);
143 }
144 return true;
145}
146
91fa93e5
MA
147bool visit_deprecated(Visitor *v, const char *name)
148{
149 trace_visit_deprecated(v, name);
150 if (v->deprecated) {
151 return v->deprecated(v, name);
152 }
153 return true;
154}
155
68ab47e4
EB
156bool visit_is_input(Visitor *v)
157{
158 return v->type == VISITOR_INPUT;
159}
160
8e08bf4e
MA
161bool visit_is_dealloc(Visitor *v)
162{
163 return v->type == VISITOR_DEALLOC;
164}
165
012d4c96 166bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
2345c77c 167{
adfb264c 168 assert(obj);
ebfd93b6 169 trace_visit_type_int(v, name, obj);
012d4c96 170 return v->type_int64(v, name, obj, errp);
2345c77c
MR
171}
172
012d4c96 173static bool visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
04e070d2
EB
174 uint64_t max, const char *type, Error **errp)
175{
04e070d2
EB
176 uint64_t value = *obj;
177
faad584a
MA
178 assert(v->type == VISITOR_INPUT || value <= max);
179
012d4c96
MA
180 if (!v->type_uint64(v, name, &value, errp)) {
181 return false;
182 }
183 if (value > max) {
faad584a 184 assert(v->type == VISITOR_INPUT);
04e070d2
EB
185 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
186 name ? name : "null", type);
012d4c96 187 return false;
4e27e819 188 }
012d4c96
MA
189 *obj = value;
190 return true;
4e27e819
MR
191}
192
012d4c96 193bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
51e72bc1 194 Error **errp)
4e27e819 195{
ebfd93b6 196 uint64_t value;
012d4c96 197 bool ok;
ebfd93b6
DB
198
199 trace_visit_type_uint8(v, name, obj);
200 value = *obj;
012d4c96 201 ok = visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
04e070d2 202 *obj = value;
012d4c96 203 return ok;
4e27e819
MR
204}
205
012d4c96 206bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
04e070d2 207 Error **errp)
4e27e819 208{
ebfd93b6 209 uint64_t value;
012d4c96 210 bool ok;
ebfd93b6
DB
211
212 trace_visit_type_uint16(v, name, obj);
213 value = *obj;
012d4c96 214 ok = visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
04e070d2 215 *obj = value;
012d4c96 216 return ok;
04e070d2 217}
297a3646 218
012d4c96 219bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
04e070d2
EB
220 Error **errp)
221{
ebfd93b6 222 uint64_t value;
012d4c96 223 bool ok;
ebfd93b6
DB
224
225 trace_visit_type_uint32(v, name, obj);
226 value = *obj;
012d4c96 227 ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
04e070d2 228 *obj = value;
012d4c96 229 return ok;
4e27e819
MR
230}
231
012d4c96 232bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
04e070d2 233 Error **errp)
4e27e819 234{
adfb264c 235 assert(obj);
ebfd93b6 236 trace_visit_type_uint64(v, name, obj);
012d4c96 237 return v->type_uint64(v, name, obj, errp);
4e27e819
MR
238}
239
012d4c96 240static bool visit_type_intN(Visitor *v, int64_t *obj, const char *name,
04e070d2
EB
241 int64_t min, int64_t max, const char *type,
242 Error **errp)
4e27e819 243{
04e070d2 244 int64_t value = *obj;
297a3646 245
faad584a
MA
246 assert(v->type == VISITOR_INPUT || (value >= min && value <= max));
247
012d4c96
MA
248 if (!v->type_int64(v, name, &value, errp)) {
249 return false;
250 }
251 if (value < min || value > max) {
faad584a 252 assert(v->type == VISITOR_INPUT);
04e070d2
EB
253 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
254 name ? name : "null", type);
012d4c96 255 return false;
4e27e819 256 }
012d4c96
MA
257 *obj = value;
258 return true;
4e27e819
MR
259}
260
012d4c96 261bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp)
4e27e819 262{
ebfd93b6 263 int64_t value;
012d4c96 264 bool ok;
ebfd93b6
DB
265
266 trace_visit_type_int8(v, name, obj);
267 value = *obj;
012d4c96 268 ok = visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
04e070d2 269 *obj = value;
012d4c96 270 return ok;
04e070d2 271}
297a3646 272
012d4c96 273bool visit_type_int16(Visitor *v, const char *name, int16_t *obj,
51e72bc1 274 Error **errp)
04e070d2 275{
ebfd93b6 276 int64_t value;
012d4c96 277 bool ok;
ebfd93b6
DB
278
279 trace_visit_type_int16(v, name, obj);
280 value = *obj;
012d4c96
MA
281 ok = visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t",
282 errp);
04e070d2 283 *obj = value;
012d4c96 284 return ok;
4e27e819
MR
285}
286
012d4c96 287bool visit_type_int32(Visitor *v, const char *name, int32_t *obj,
51e72bc1 288 Error **errp)
4e27e819 289{
ebfd93b6 290 int64_t value;
012d4c96 291 bool ok;
ebfd93b6
DB
292
293 trace_visit_type_int32(v, name, obj);
294 value = *obj;
012d4c96
MA
295 ok = visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t",
296 errp);
04e070d2 297 *obj = value;
012d4c96 298 return ok;
4e27e819
MR
299}
300
012d4c96 301bool visit_type_int64(Visitor *v, const char *name, int64_t *obj,
51e72bc1 302 Error **errp)
4e27e819 303{
adfb264c 304 assert(obj);
ebfd93b6 305 trace_visit_type_int64(v, name, obj);
012d4c96 306 return v->type_int64(v, name, obj, errp);
4e27e819
MR
307}
308
012d4c96 309bool visit_type_size(Visitor *v, const char *name, uint64_t *obj,
51e72bc1 310 Error **errp)
092705d4 311{
adfb264c 312 assert(obj);
ebfd93b6 313 trace_visit_type_size(v, name, obj);
297a3646 314 if (v->type_size) {
012d4c96 315 return v->type_size(v, name, obj, errp);
092705d4 316 }
012d4c96 317 return v->type_uint64(v, name, obj, errp);
092705d4
LE
318}
319
012d4c96 320bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
2345c77c 321{
adfb264c 322 assert(obj);
ebfd93b6 323 trace_visit_type_bool(v, name, obj);
012d4c96 324 return v->type_bool(v, name, obj, errp);
2345c77c
MR
325}
326
012d4c96 327bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
2345c77c 328{
7b3cb803 329 bool ok;
e58d695e
EB
330
331 assert(obj);
adfb264c
EB
332 /* TODO: Fix callers to not pass NULL when they mean "", so that we
333 * can enable:
a15fcc3c 334 assert(!(v->type & VISITOR_OUTPUT) || *obj);
adfb264c 335 */
ebfd93b6 336 trace_visit_type_str(v, name, obj);
7b3cb803 337 ok = v->type_str(v, name, obj, errp);
a15fcc3c 338 if (v->type & VISITOR_INPUT) {
7b3cb803 339 assert(ok != !*obj);
e58d695e 340 }
7b3cb803 341 return ok;
2345c77c
MR
342}
343
012d4c96 344bool visit_type_number(Visitor *v, const char *name, double *obj,
51e72bc1 345 Error **errp)
2345c77c 346{
adfb264c 347 assert(obj);
ebfd93b6 348 trace_visit_type_number(v, name, obj);
012d4c96 349 return v->type_number(v, name, obj, errp);
2345c77c 350}
0f71a1e0 351
012d4c96 352bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
28770e05 353{
012d4c96 354 bool ok;
e58d695e
EB
355
356 assert(obj);
adfb264c 357 assert(v->type != VISITOR_OUTPUT || *obj);
ebfd93b6 358 trace_visit_type_any(v, name, obj);
012d4c96 359 ok = v->type_any(v, name, obj, errp);
e58d695e 360 if (v->type == VISITOR_INPUT) {
012d4c96 361 assert(ok != !*obj);
e58d695e 362 }
012d4c96 363 return ok;
28770e05
MA
364}
365
012d4c96 366bool visit_type_null(Visitor *v, const char *name, QNull **obj,
d2f95f4d 367 Error **errp)
3bc97fd5 368{
d2f95f4d 369 trace_visit_type_null(v, name, obj);
012d4c96 370 return v->type_null(v, name, obj, errp);
3bc97fd5
EB
371}
372
012d4c96 373static bool output_type_enum(Visitor *v, const char *name, int *obj,
f7abe0ec 374 const QEnumLookup *lookup, Error **errp)
0f71a1e0 375{
0f71a1e0
PB
376 int value = *obj;
377 char *enum_str;
378
f7abe0ec 379 enum_str = (char *)qapi_enum_lookup(lookup, value);
012d4c96 380 return visit_type_str(v, name, &enum_str, errp);
0f71a1e0
PB
381}
382
012d4c96 383static bool input_type_enum(Visitor *v, const char *name, int *obj,
f7abe0ec 384 const QEnumLookup *lookup, Error **errp)
0f71a1e0 385{
113e47ae 386 int64_t value;
0f71a1e0
PB
387 char *enum_str;
388
012d4c96
MA
389 if (!visit_type_str(v, name, &enum_str, errp)) {
390 return false;
0f71a1e0
PB
391 }
392
f7abe0ec 393 value = qapi_enum_parse(lookup, enum_str, -1, NULL);
113e47ae 394 if (value < 0) {
c6bd8c70 395 error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
0f71a1e0 396 g_free(enum_str);
012d4c96 397 return false;
0f71a1e0
PB
398 }
399
400 g_free(enum_str);
401 *obj = value;
012d4c96 402 return true;
0f71a1e0 403}
983f52d4 404
012d4c96 405bool visit_type_enum(Visitor *v, const char *name, int *obj,
f7abe0ec 406 const QEnumLookup *lookup, Error **errp)
983f52d4 407{
f7abe0ec 408 assert(obj && lookup);
6514532f 409 trace_visit_type_enum(v, name, obj);
a15fcc3c
EB
410 switch (v->type) {
411 case VISITOR_INPUT:
012d4c96 412 return input_type_enum(v, name, obj, lookup, errp);
a15fcc3c 413 case VISITOR_OUTPUT:
012d4c96 414 return output_type_enum(v, name, obj, lookup, errp);
a15fcc3c
EB
415 case VISITOR_CLONE:
416 /* nothing further to do, scalar value was already copied by
417 * g_memdup() during visit_start_*() */
012d4c96 418 return true;
a15fcc3c
EB
419 case VISITOR_DEALLOC:
420 /* nothing to deallocate for a scalar */
012d4c96
MA
421 return true;
422 default:
423 abort();
983f52d4
EB
424 }
425}