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