xref: /qemu/qapi/qapi-visit-core.c (revision 72ac97cd)
1 /*
2  * Core Definitions for QAPI Visitor Classes
3  *
4  * Copyright IBM, Corp. 2011
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10  * See the COPYING.LIB file in the top-level directory.
11  *
12  */
13 
14 #include "qemu-common.h"
15 #include "qapi/qmp/qobject.h"
16 #include "qapi/qmp/qerror.h"
17 #include "qapi/visitor.h"
18 #include "qapi/visitor-impl.h"
19 
20 void visit_start_struct(Visitor *v, void **obj, const char *kind,
21                         const char *name, size_t size, Error **errp)
22 {
23     v->start_struct(v, obj, kind, name, size, errp);
24 }
25 
26 void visit_end_struct(Visitor *v, Error **errp)
27 {
28     v->end_struct(v, errp);
29 }
30 
31 void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
32                                  Error **errp)
33 {
34     if (v->start_implicit_struct) {
35         v->start_implicit_struct(v, obj, size, errp);
36     }
37 }
38 
39 void visit_end_implicit_struct(Visitor *v, Error **errp)
40 {
41     if (v->end_implicit_struct) {
42         v->end_implicit_struct(v, errp);
43     }
44 }
45 
46 void visit_start_list(Visitor *v, const char *name, Error **errp)
47 {
48     v->start_list(v, name, errp);
49 }
50 
51 GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
52 {
53     return v->next_list(v, list, errp);
54 }
55 
56 void visit_end_list(Visitor *v, Error **errp)
57 {
58     v->end_list(v, errp);
59 }
60 
61 void visit_optional(Visitor *v, bool *present, const char *name,
62                     Error **errp)
63 {
64     if (v->optional) {
65         v->optional(v, present, name, errp);
66     }
67 }
68 
69 void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
70                          const char *name, Error **errp)
71 {
72     if (v->get_next_type) {
73         v->get_next_type(v, obj, qtypes, name, errp);
74     }
75 }
76 
77 void visit_type_enum(Visitor *v, int *obj, const char *strings[],
78                      const char *kind, const char *name, Error **errp)
79 {
80     v->type_enum(v, obj, strings, kind, name, errp);
81 }
82 
83 void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
84 {
85     v->type_int(v, obj, name, errp);
86 }
87 
88 void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
89 {
90     int64_t value;
91 
92     if (v->type_uint8) {
93         v->type_uint8(v, obj, name, errp);
94     } else {
95         value = *obj;
96         v->type_int(v, &value, name, errp);
97         if (value < 0 || value > UINT8_MAX) {
98             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
99                       "uint8_t");
100             return;
101         }
102         *obj = value;
103     }
104 }
105 
106 void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
107 {
108     int64_t value;
109 
110     if (v->type_uint16) {
111         v->type_uint16(v, obj, name, errp);
112     } else {
113         value = *obj;
114         v->type_int(v, &value, name, errp);
115         if (value < 0 || value > UINT16_MAX) {
116             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
117                       "uint16_t");
118             return;
119         }
120         *obj = value;
121     }
122 }
123 
124 void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
125 {
126     int64_t value;
127 
128     if (v->type_uint32) {
129         v->type_uint32(v, obj, name, errp);
130     } else {
131         value = *obj;
132         v->type_int(v, &value, name, errp);
133         if (value < 0 || value > UINT32_MAX) {
134             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
135                       "uint32_t");
136             return;
137         }
138         *obj = value;
139     }
140 }
141 
142 void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
143 {
144     int64_t value;
145 
146     if (v->type_uint64) {
147         v->type_uint64(v, obj, name, errp);
148     } else {
149         value = *obj;
150         v->type_int(v, &value, name, errp);
151         *obj = value;
152     }
153 }
154 
155 void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
156 {
157     int64_t value;
158 
159     if (v->type_int8) {
160         v->type_int8(v, obj, name, errp);
161     } else {
162         value = *obj;
163         v->type_int(v, &value, name, errp);
164         if (value < INT8_MIN || value > INT8_MAX) {
165             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
166                       "int8_t");
167             return;
168         }
169         *obj = value;
170     }
171 }
172 
173 void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
174 {
175     int64_t value;
176 
177     if (v->type_int16) {
178         v->type_int16(v, obj, name, errp);
179     } else {
180         value = *obj;
181         v->type_int(v, &value, name, errp);
182         if (value < INT16_MIN || value > INT16_MAX) {
183             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
184                       "int16_t");
185             return;
186         }
187         *obj = value;
188     }
189 }
190 
191 void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
192 {
193     int64_t value;
194 
195     if (v->type_int32) {
196         v->type_int32(v, obj, name, errp);
197     } else {
198         value = *obj;
199         v->type_int(v, &value, name, errp);
200         if (value < INT32_MIN || value > INT32_MAX) {
201             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
202                       "int32_t");
203             return;
204         }
205         *obj = value;
206     }
207 }
208 
209 void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
210 {
211     if (v->type_int64) {
212         v->type_int64(v, obj, name, errp);
213     } else {
214         v->type_int(v, obj, name, errp);
215     }
216 }
217 
218 void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
219 {
220     int64_t value;
221 
222     if (v->type_size) {
223         v->type_size(v, obj, name, errp);
224     } else if (v->type_uint64) {
225         v->type_uint64(v, obj, name, errp);
226     } else {
227         value = *obj;
228         v->type_int(v, &value, name, errp);
229         *obj = value;
230     }
231 }
232 
233 void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
234 {
235     v->type_bool(v, obj, name, errp);
236 }
237 
238 void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
239 {
240     v->type_str(v, obj, name, errp);
241 }
242 
243 void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
244 {
245     v->type_number(v, obj, name, errp);
246 }
247 
248 void output_type_enum(Visitor *v, int *obj, const char *strings[],
249                       const char *kind, const char *name,
250                       Error **errp)
251 {
252     int i = 0;
253     int value = *obj;
254     char *enum_str;
255 
256     assert(strings);
257     while (strings[i++] != NULL);
258     if (value < 0 || value >= i - 1) {
259         error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");
260         return;
261     }
262 
263     enum_str = (char *)strings[value];
264     visit_type_str(v, &enum_str, name, errp);
265 }
266 
267 void input_type_enum(Visitor *v, int *obj, const char *strings[],
268                      const char *kind, const char *name,
269                      Error **errp)
270 {
271     Error *local_err = NULL;
272     int64_t value = 0;
273     char *enum_str;
274 
275     assert(strings);
276 
277     visit_type_str(v, &enum_str, name, &local_err);
278     if (local_err) {
279         error_propagate(errp, local_err);
280         return;
281     }
282 
283     while (strings[value] != NULL) {
284         if (strcmp(strings[value], enum_str) == 0) {
285             break;
286         }
287         value++;
288     }
289 
290     if (strings[value] == NULL) {
291         error_set(errp, QERR_INVALID_PARAMETER, enum_str);
292         g_free(enum_str);
293         return;
294     }
295 
296     g_free(enum_str);
297     *obj = value;
298 }
299