]>
Commit | Line | Data |
---|---|---|
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 | 22 | void 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 | ||
28 | void visit_end_struct(Visitor *v, Error **errp) | |
29 | { | |
d195325b | 30 | v->end_struct(v, errp); |
2345c77c MR |
31 | } |
32 | ||
761d524d KW |
33 | void 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 | 41 | void 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 |
48 | void visit_start_list(Visitor *v, const char *name, Error **errp) |
49 | { | |
297a3646 | 50 | v->start_list(v, name, errp); |
2345c77c MR |
51 | } |
52 | ||
e65d89bf | 53 | GenericList *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 | 59 | void visit_end_list(Visitor *v) |
2345c77c | 60 | { |
08f9541d | 61 | v->end_list(v); |
2345c77c MR |
62 | } |
63 | ||
51e72bc1 | 64 | bool 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 |
72 | void 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 | 80 | void 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 | 86 | void 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 |
91 | static 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 |
108 | void 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 | 116 | void 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 | 124 | void 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 | 132 | void 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 |
138 | static 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 | 156 | void 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 |
163 | void 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 |
171 | void 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 |
179 | void 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 |
185 | void 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 | 195 | void 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 | 200 | void 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 |
205 | void 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 | 211 | void 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 | 216 | void 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 | 234 | void 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 | } |