]> git.proxmox.com Git - mirror_qemu.git/blame - qapi/qapi-visit-core.c
qapi: Don't box branches of flat unions
[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"
79ee7df8 16#include "qemu-common.h"
69dd62df 17#include "qapi/qmp/qobject.h"
7b1b5d19
PB
18#include "qapi/qmp/qerror.h"
19#include "qapi/visitor.h"
20#include "qapi/visitor-impl.h"
2345c77c 21
51e72bc1 22void visit_start_struct(Visitor *v, const char *name, void **obj,
337283df 23 size_t size, Error **errp)
2345c77c 24{
337283df 25 v->start_struct(v, name, obj, size, errp);
2345c77c
MR
26}
27
28void visit_end_struct(Visitor *v, Error **errp)
29{
d195325b 30 v->end_struct(v, errp);
2345c77c
MR
31}
32
761d524d
KW
33void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
34 Error **errp)
35{
297a3646 36 if (v->start_implicit_struct) {
761d524d
KW
37 v->start_implicit_struct(v, obj, size, errp);
38 }
39}
40
08f9541d 41void visit_end_implicit_struct(Visitor *v)
761d524d 42{
761d524d 43 if (v->end_implicit_struct) {
08f9541d 44 v->end_implicit_struct(v);
761d524d
KW
45 }
46}
47
2345c77c
MR
48void visit_start_list(Visitor *v, const char *name, Error **errp)
49{
297a3646 50 v->start_list(v, name, errp);
2345c77c
MR
51}
52
e65d89bf 53GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size)
2345c77c 54{
e65d89bf
EB
55 assert(list && size >= sizeof(GenericList));
56 return v->next_list(v, list, size);
2345c77c
MR
57}
58
08f9541d 59void visit_end_list(Visitor *v)
2345c77c 60{
08f9541d 61 v->end_list(v);
2345c77c
MR
62}
63
51e72bc1 64bool visit_optional(Visitor *v, const char *name, bool *present)
2345c77c 65{
297a3646 66 if (v->optional) {
0b2a0d6b 67 v->optional(v, name, present);
2345c77c 68 }
29637a6e 69 return *present;
2345c77c
MR
70}
71
51e72bc1
EB
72void visit_get_next_type(Visitor *v, const char *name, QType *type,
73 bool promote_int, Error **errp)
69dd62df 74{
297a3646 75 if (v->get_next_type) {
0b2a0d6b 76 v->get_next_type(v, name, type, promote_int, errp);
69dd62df
KW
77 }
78}
79
51e72bc1 80void visit_type_enum(Visitor *v, const char *name, int *obj,
337283df 81 const char *const strings[], Error **errp)
2345c77c 82{
337283df 83 v->type_enum(v, name, obj, strings, errp);
2345c77c
MR
84}
85
51e72bc1 86void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
2345c77c 87{
0b2a0d6b 88 v->type_int64(v, name, obj, errp);
2345c77c
MR
89}
90
04e070d2
EB
91static void visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
92 uint64_t max, const char *type, Error **errp)
93{
94 Error *err = NULL;
95 uint64_t value = *obj;
96
0b2a0d6b 97 v->type_uint64(v, name, &value, &err);
04e070d2
EB
98 if (err) {
99 error_propagate(errp, err);
100 } else if (value > max) {
101 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
102 name ? name : "null", type);
297a3646 103 } else {
297a3646 104 *obj = value;
4e27e819
MR
105 }
106}
107
51e72bc1
EB
108void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
109 Error **errp)
4e27e819 110{
04e070d2
EB
111 uint64_t value = *obj;
112 visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
113 *obj = value;
4e27e819
MR
114}
115
51e72bc1 116void visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
04e070d2 117 Error **errp)
4e27e819 118{
04e070d2
EB
119 uint64_t value = *obj;
120 visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
121 *obj = value;
122}
297a3646 123
51e72bc1 124void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
04e070d2
EB
125 Error **errp)
126{
127 uint64_t value = *obj;
128 visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
129 *obj = value;
4e27e819
MR
130}
131
51e72bc1 132void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
04e070d2 133 Error **errp)
4e27e819 134{
0b2a0d6b 135 v->type_uint64(v, name, obj, errp);
4e27e819
MR
136}
137
04e070d2
EB
138static void visit_type_intN(Visitor *v, int64_t *obj, const char *name,
139 int64_t min, int64_t max, const char *type,
140 Error **errp)
4e27e819 141{
04e070d2
EB
142 Error *err = NULL;
143 int64_t value = *obj;
297a3646 144
0b2a0d6b 145 v->type_int64(v, name, &value, &err);
04e070d2
EB
146 if (err) {
147 error_propagate(errp, err);
148 } else if (value < min || value > max) {
149 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
150 name ? name : "null", type);
297a3646 151 } else {
297a3646 152 *obj = value;
4e27e819
MR
153 }
154}
155
51e72bc1 156void visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp)
4e27e819 157{
04e070d2
EB
158 int64_t value = *obj;
159 visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
160 *obj = value;
161}
297a3646 162
51e72bc1
EB
163void visit_type_int16(Visitor *v, const char *name, int16_t *obj,
164 Error **errp)
04e070d2
EB
165{
166 int64_t value = *obj;
167 visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t", errp);
168 *obj = value;
4e27e819
MR
169}
170
51e72bc1
EB
171void visit_type_int32(Visitor *v, const char *name, int32_t *obj,
172 Error **errp)
4e27e819 173{
04e070d2
EB
174 int64_t value = *obj;
175 visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t", errp);
176 *obj = value;
4e27e819
MR
177}
178
51e72bc1
EB
179void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
180 Error **errp)
4e27e819 181{
0b2a0d6b 182 v->type_int64(v, name, obj, errp);
4e27e819
MR
183}
184
51e72bc1
EB
185void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
186 Error **errp)
092705d4 187{
297a3646 188 if (v->type_size) {
0b2a0d6b 189 v->type_size(v, name, obj, errp);
297a3646 190 } else {
0b2a0d6b 191 v->type_uint64(v, name, obj, errp);
092705d4
LE
192 }
193}
194
51e72bc1 195void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
2345c77c 196{
0b2a0d6b 197 v->type_bool(v, name, obj, errp);
2345c77c
MR
198}
199
51e72bc1 200void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
2345c77c 201{
0b2a0d6b 202 v->type_str(v, name, obj, errp);
2345c77c
MR
203}
204
51e72bc1
EB
205void visit_type_number(Visitor *v, const char *name, double *obj,
206 Error **errp)
2345c77c 207{
0b2a0d6b 208 v->type_number(v, name, obj, errp);
2345c77c 209}
0f71a1e0 210
51e72bc1 211void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
28770e05 212{
0b2a0d6b 213 v->type_any(v, name, obj, errp);
28770e05
MA
214}
215
0b2a0d6b 216void output_type_enum(Visitor *v, const char *name, int *obj,
337283df 217 const char *const strings[], Error **errp)
0f71a1e0
PB
218{
219 int i = 0;
220 int value = *obj;
221 char *enum_str;
222
223 assert(strings);
224 while (strings[i++] != NULL);
225 if (value < 0 || value >= i - 1) {
c6bd8c70 226 error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null");
0f71a1e0
PB
227 return;
228 }
229
230 enum_str = (char *)strings[value];
51e72bc1 231 visit_type_str(v, name, &enum_str, errp);
0f71a1e0
PB
232}
233
0b2a0d6b 234void input_type_enum(Visitor *v, const char *name, int *obj,
337283df 235 const char *const strings[], Error **errp)
0f71a1e0 236{
297a3646 237 Error *local_err = NULL;
0f71a1e0
PB
238 int64_t value = 0;
239 char *enum_str;
240
241 assert(strings);
242
51e72bc1 243 visit_type_str(v, name, &enum_str, &local_err);
297a3646
MA
244 if (local_err) {
245 error_propagate(errp, local_err);
0f71a1e0
PB
246 return;
247 }
248
249 while (strings[value] != NULL) {
250 if (strcmp(strings[value], enum_str) == 0) {
251 break;
252 }
253 value++;
254 }
255
256 if (strings[value] == NULL) {
c6bd8c70 257 error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
0f71a1e0
PB
258 g_free(enum_str);
259 return;
260 }
261
262 g_free(enum_str);
263 *obj = value;
264}