xref: /openbmc/qemu/qapi/qapi-visit-core.c (revision a719a27c)
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_handle(Visitor *v, void **obj, const char *kind,
21                         const char *name, Error **errp)
22 {
23     if (!error_is_set(errp) && v->start_handle) {
24         v->start_handle(v, obj, kind, name, errp);
25     }
26 }
27 
28 void visit_end_handle(Visitor *v, Error **errp)
29 {
30     if (!error_is_set(errp) && v->end_handle) {
31         v->end_handle(v, errp);
32     }
33 }
34 
35 void visit_start_struct(Visitor *v, void **obj, const char *kind,
36                         const char *name, size_t size, Error **errp)
37 {
38     if (!error_is_set(errp)) {
39         v->start_struct(v, obj, kind, name, size, errp);
40     }
41 }
42 
43 void visit_end_struct(Visitor *v, Error **errp)
44 {
45     assert(!error_is_set(errp));
46     v->end_struct(v, errp);
47 }
48 
49 void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
50                                  Error **errp)
51 {
52     if (!error_is_set(errp) && v->start_implicit_struct) {
53         v->start_implicit_struct(v, obj, size, errp);
54     }
55 }
56 
57 void visit_end_implicit_struct(Visitor *v, Error **errp)
58 {
59     assert(!error_is_set(errp));
60     if (v->end_implicit_struct) {
61         v->end_implicit_struct(v, errp);
62     }
63 }
64 
65 void visit_start_list(Visitor *v, const char *name, Error **errp)
66 {
67     if (!error_is_set(errp)) {
68         v->start_list(v, name, errp);
69     }
70 }
71 
72 GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
73 {
74     if (!error_is_set(errp)) {
75         return v->next_list(v, list, errp);
76     }
77 
78     return 0;
79 }
80 
81 void visit_end_list(Visitor *v, Error **errp)
82 {
83     assert(!error_is_set(errp));
84     v->end_list(v, errp);
85 }
86 
87 void visit_start_optional(Visitor *v, bool *present, const char *name,
88                           Error **errp)
89 {
90     if (!error_is_set(errp) && v->start_optional) {
91         v->start_optional(v, present, name, errp);
92     }
93 }
94 
95 void visit_end_optional(Visitor *v, Error **errp)
96 {
97     if (!error_is_set(errp) && v->end_optional) {
98         v->end_optional(v, errp);
99     }
100 }
101 
102 void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
103                          const char *name, Error **errp)
104 {
105     if (!error_is_set(errp) && v->get_next_type) {
106         v->get_next_type(v, obj, qtypes, name, errp);
107     }
108 }
109 
110 void visit_type_enum(Visitor *v, int *obj, const char *strings[],
111                      const char *kind, const char *name, Error **errp)
112 {
113     if (!error_is_set(errp)) {
114         v->type_enum(v, obj, strings, kind, name, errp);
115     }
116 }
117 
118 void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
119 {
120     if (!error_is_set(errp)) {
121         v->type_int(v, obj, name, errp);
122     }
123 }
124 
125 void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
126 {
127     int64_t value;
128     if (!error_is_set(errp)) {
129         if (v->type_uint8) {
130             v->type_uint8(v, obj, name, errp);
131         } else {
132             value = *obj;
133             v->type_int(v, &value, name, errp);
134             if (value < 0 || value > UINT8_MAX) {
135                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
136                           "uint8_t");
137                 return;
138             }
139             *obj = value;
140         }
141     }
142 }
143 
144 void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
145 {
146     int64_t value;
147     if (!error_is_set(errp)) {
148         if (v->type_uint16) {
149             v->type_uint16(v, obj, name, errp);
150         } else {
151             value = *obj;
152             v->type_int(v, &value, name, errp);
153             if (value < 0 || value > UINT16_MAX) {
154                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
155                           "uint16_t");
156                 return;
157             }
158             *obj = value;
159         }
160     }
161 }
162 
163 void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
164 {
165     int64_t value;
166     if (!error_is_set(errp)) {
167         if (v->type_uint32) {
168             v->type_uint32(v, obj, name, errp);
169         } else {
170             value = *obj;
171             v->type_int(v, &value, name, errp);
172             if (value < 0 || value > UINT32_MAX) {
173                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
174                           "uint32_t");
175                 return;
176             }
177             *obj = value;
178         }
179     }
180 }
181 
182 void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
183 {
184     int64_t value;
185     if (!error_is_set(errp)) {
186         if (v->type_uint64) {
187             v->type_uint64(v, obj, name, errp);
188         } else {
189             value = *obj;
190             v->type_int(v, &value, name, errp);
191             *obj = value;
192         }
193     }
194 }
195 
196 void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
197 {
198     int64_t value;
199     if (!error_is_set(errp)) {
200         if (v->type_int8) {
201             v->type_int8(v, obj, name, errp);
202         } else {
203             value = *obj;
204             v->type_int(v, &value, name, errp);
205             if (value < INT8_MIN || value > INT8_MAX) {
206                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
207                           "int8_t");
208                 return;
209             }
210             *obj = value;
211         }
212     }
213 }
214 
215 void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
216 {
217     int64_t value;
218     if (!error_is_set(errp)) {
219         if (v->type_int16) {
220             v->type_int16(v, obj, name, errp);
221         } else {
222             value = *obj;
223             v->type_int(v, &value, name, errp);
224             if (value < INT16_MIN || value > INT16_MAX) {
225                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
226                           "int16_t");
227                 return;
228             }
229             *obj = value;
230         }
231     }
232 }
233 
234 void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
235 {
236     int64_t value;
237     if (!error_is_set(errp)) {
238         if (v->type_int32) {
239             v->type_int32(v, obj, name, errp);
240         } else {
241             value = *obj;
242             v->type_int(v, &value, name, errp);
243             if (value < INT32_MIN || value > INT32_MAX) {
244                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
245                           "int32_t");
246                 return;
247             }
248             *obj = value;
249         }
250     }
251 }
252 
253 void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
254 {
255     if (!error_is_set(errp)) {
256         if (v->type_int64) {
257             v->type_int64(v, obj, name, errp);
258         } else {
259             v->type_int(v, obj, name, errp);
260         }
261     }
262 }
263 
264 void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
265 {
266     int64_t value;
267     if (!error_is_set(errp)) {
268         if (v->type_size) {
269             v->type_size(v, obj, name, errp);
270         } else if (v->type_uint64) {
271             v->type_uint64(v, obj, name, errp);
272         } else {
273             value = *obj;
274             v->type_int(v, &value, name, errp);
275             *obj = value;
276         }
277     }
278 }
279 
280 void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
281 {
282     if (!error_is_set(errp)) {
283         v->type_bool(v, obj, name, errp);
284     }
285 }
286 
287 void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
288 {
289     if (!error_is_set(errp)) {
290         v->type_str(v, obj, name, errp);
291     }
292 }
293 
294 void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
295 {
296     if (!error_is_set(errp)) {
297         v->type_number(v, obj, name, errp);
298     }
299 }
300 
301 void output_type_enum(Visitor *v, int *obj, const char *strings[],
302                       const char *kind, const char *name,
303                       Error **errp)
304 {
305     int i = 0;
306     int value = *obj;
307     char *enum_str;
308 
309     assert(strings);
310     while (strings[i++] != NULL);
311     if (value < 0 || value >= i - 1) {
312         error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");
313         return;
314     }
315 
316     enum_str = (char *)strings[value];
317     visit_type_str(v, &enum_str, name, errp);
318 }
319 
320 void input_type_enum(Visitor *v, int *obj, const char *strings[],
321                      const char *kind, const char *name,
322                      Error **errp)
323 {
324     int64_t value = 0;
325     char *enum_str;
326 
327     assert(strings);
328 
329     visit_type_str(v, &enum_str, name, errp);
330     if (error_is_set(errp)) {
331         return;
332     }
333 
334     while (strings[value] != NULL) {
335         if (strcmp(strings[value], enum_str) == 0) {
336             break;
337         }
338         value++;
339     }
340 
341     if (strings[value] == NULL) {
342         error_set(errp, QERR_INVALID_PARAMETER, enum_str);
343         g_free(enum_str);
344         return;
345     }
346 
347     g_free(enum_str);
348     *obj = value;
349 }
350