xref: /qemu/qapi/qapi-visit-core.c (revision 7ce5fc63)
12345c77cSMichael Roth /*
22345c77cSMichael Roth  * Core Definitions for QAPI Visitor Classes
32345c77cSMichael Roth  *
47c91aabdSEric Blake  * Copyright (C) 2012-2016 Red Hat, Inc.
52345c77cSMichael Roth  * Copyright IBM, Corp. 2011
62345c77cSMichael Roth  *
72345c77cSMichael Roth  * Authors:
82345c77cSMichael Roth  *  Anthony Liguori   <aliguori@us.ibm.com>
92345c77cSMichael Roth  *
102345c77cSMichael Roth  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
112345c77cSMichael Roth  * See the COPYING.LIB file in the top-level directory.
122345c77cSMichael Roth  *
132345c77cSMichael Roth  */
142345c77cSMichael Roth 
15cbf21151SPeter Maydell #include "qemu/osdep.h"
16*7ce5fc63SMarkus Armbruster #include "qapi/compat-policy.h"
17da34e65cSMarkus Armbruster #include "qapi/error.h"
187b1b5d19SPaolo Bonzini #include "qapi/qmp/qerror.h"
197b1b5d19SPaolo Bonzini #include "qapi/visitor.h"
207b1b5d19SPaolo Bonzini #include "qapi/visitor-impl.h"
21ebfd93b6SDaniel P. Berrange #include "trace.h"
222345c77cSMichael Roth 
23ed29bb28SMarkus Armbruster /* Zero-initialization must result in default policy */
24ed29bb28SMarkus Armbruster QEMU_BUILD_BUG_ON(COMPAT_POLICY_INPUT_ACCEPT || COMPAT_POLICY_OUTPUT_ACCEPT);
25ed29bb28SMarkus Armbruster 
26ed29bb28SMarkus Armbruster 
visit_complete(Visitor * v,void * opaque)273b098d56SEric Blake void visit_complete(Visitor *v, void *opaque)
283b098d56SEric Blake {
293b098d56SEric Blake     assert(v->type != VISITOR_OUTPUT || v->complete);
30ebfd93b6SDaniel P. Berrange     trace_visit_complete(v, opaque);
313b098d56SEric Blake     if (v->complete) {
323b098d56SEric Blake         v->complete(v, opaque);
333b098d56SEric Blake     }
343b098d56SEric Blake }
353b098d56SEric Blake 
visit_free(Visitor * v)362c0ef9f4SEric Blake void visit_free(Visitor *v)
372c0ef9f4SEric Blake {
38ebfd93b6SDaniel P. Berrange     trace_visit_free(v);
392c0ef9f4SEric Blake     if (v) {
402c0ef9f4SEric Blake         v->free(v);
412c0ef9f4SEric Blake     }
422c0ef9f4SEric Blake }
432c0ef9f4SEric Blake 
visit_start_struct(Visitor * v,const char * name,void ** obj,size_t size,Error ** errp)44012d4c96SMarkus Armbruster bool visit_start_struct(Visitor *v, const char *name, void **obj,
45337283dfSEric Blake                         size_t size, Error **errp)
462345c77cSMichael Roth {
477b3cb803SMarkus Armbruster     bool ok;
48e58d695eSEric Blake 
49ebfd93b6SDaniel P. Berrange     trace_visit_start_struct(v, name, obj, size);
50adfb264cSEric Blake     if (obj) {
51adfb264cSEric Blake         assert(size);
52a15fcc3cSEric Blake         assert(!(v->type & VISITOR_OUTPUT) || *obj);
53adfb264cSEric Blake     }
547b3cb803SMarkus Armbruster     ok = v->start_struct(v, name, obj, size, errp);
55a15fcc3cSEric Blake     if (obj && (v->type & VISITOR_INPUT)) {
567b3cb803SMarkus Armbruster         assert(ok != !*obj);
57e58d695eSEric Blake     }
587b3cb803SMarkus Armbruster     return ok;
592345c77cSMichael Roth }
602345c77cSMichael Roth 
visit_check_struct(Visitor * v,Error ** errp)61012d4c96SMarkus Armbruster bool visit_check_struct(Visitor *v, Error **errp)
622345c77cSMichael Roth {
63ebfd93b6SDaniel P. Berrange     trace_visit_check_struct(v);
64012d4c96SMarkus Armbruster     return v->check_struct ? v->check_struct(v, errp) : true;
6515c2f669SEric Blake }
6615c2f669SEric Blake 
visit_end_struct(Visitor * v,void ** obj)671158bb2aSEric Blake void visit_end_struct(Visitor *v, void **obj)
6815c2f669SEric Blake {
69ebfd93b6SDaniel P. Berrange     trace_visit_end_struct(v, obj);
701158bb2aSEric Blake     v->end_struct(v, obj);
712345c77cSMichael Roth }
722345c77cSMichael Roth 
visit_start_list(Visitor * v,const char * name,GenericList ** list,size_t size,Error ** errp)73012d4c96SMarkus Armbruster bool visit_start_list(Visitor *v, const char *name, GenericList **list,
74d9f62ddeSEric Blake                       size_t size, Error **errp)
752345c77cSMichael Roth {
767b3cb803SMarkus Armbruster     bool ok;
77d9f62ddeSEric Blake 
78d9f62ddeSEric Blake     assert(!list || size >= sizeof(GenericList));
79ebfd93b6SDaniel P. Berrange     trace_visit_start_list(v, name, list, size);
807b3cb803SMarkus Armbruster     ok = v->start_list(v, name, list, size, errp);
81a15fcc3cSEric Blake     if (list && (v->type & VISITOR_INPUT)) {
827b3cb803SMarkus Armbruster         assert(ok || !*list);
83d9f62ddeSEric Blake     }
847b3cb803SMarkus Armbruster     return ok;
852345c77cSMichael Roth }
862345c77cSMichael Roth 
visit_next_list(Visitor * v,GenericList * tail,size_t size)87d9f62ddeSEric Blake GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
882345c77cSMichael Roth {
89d9f62ddeSEric Blake     assert(tail && size >= sizeof(GenericList));
90ebfd93b6SDaniel P. Berrange     trace_visit_next_list(v, tail, size);
91d9f62ddeSEric Blake     return v->next_list(v, tail, size);
922345c77cSMichael Roth }
932345c77cSMichael Roth 
visit_check_list(Visitor * v,Error ** errp)94012d4c96SMarkus Armbruster bool visit_check_list(Visitor *v, Error **errp)
95a4a1c70dSMarkus Armbruster {
96a4a1c70dSMarkus Armbruster     trace_visit_check_list(v);
97012d4c96SMarkus Armbruster     return v->check_list ? v->check_list(v, errp) : true;
98a4a1c70dSMarkus Armbruster }
99a4a1c70dSMarkus Armbruster 
visit_end_list(Visitor * v,void ** obj)1001158bb2aSEric Blake void visit_end_list(Visitor *v, void **obj)
1012345c77cSMichael Roth {
102ebfd93b6SDaniel P. Berrange     trace_visit_end_list(v, obj);
1031158bb2aSEric Blake     v->end_list(v, obj);
1042345c77cSMichael Roth }
1052345c77cSMichael Roth 
visit_start_alternate(Visitor * v,const char * name,GenericAlternate ** obj,size_t size,Error ** errp)106012d4c96SMarkus Armbruster bool visit_start_alternate(Visitor *v, const char *name,
107dbf11922SEric Blake                            GenericAlternate **obj, size_t size,
10860390d2dSMarc-André Lureau                            Error **errp)
109dbf11922SEric Blake {
1107b3cb803SMarkus Armbruster     bool ok;
111e58d695eSEric Blake 
112dbf11922SEric Blake     assert(obj && size >= sizeof(GenericAlternate));
113a15fcc3cSEric Blake     assert(!(v->type & VISITOR_OUTPUT) || *obj);
11460390d2dSMarc-André Lureau     trace_visit_start_alternate(v, name, obj, size);
1157b3cb803SMarkus Armbruster     if (!v->start_alternate) {
1167b3cb803SMarkus Armbruster         assert(!(v->type & VISITOR_INPUT));
1177b3cb803SMarkus Armbruster         return true;
118dbf11922SEric Blake     }
1197b3cb803SMarkus Armbruster     ok = v->start_alternate(v, name, obj, size, errp);
120a15fcc3cSEric Blake     if (v->type & VISITOR_INPUT) {
1217b3cb803SMarkus Armbruster         assert(ok != !*obj);
122e58d695eSEric Blake     }
1237b3cb803SMarkus Armbruster     return ok;
124dbf11922SEric Blake }
125dbf11922SEric Blake 
visit_end_alternate(Visitor * v,void ** obj)1261158bb2aSEric Blake void visit_end_alternate(Visitor *v, void **obj)
127dbf11922SEric Blake {
128ebfd93b6SDaniel P. Berrange     trace_visit_end_alternate(v, obj);
129dbf11922SEric Blake     if (v->end_alternate) {
1301158bb2aSEric Blake         v->end_alternate(v, obj);
131dbf11922SEric Blake     }
132dbf11922SEric Blake }
133dbf11922SEric Blake 
visit_optional(Visitor * v,const char * name,bool * present)13451e72bc1SEric Blake bool visit_optional(Visitor *v, const char *name, bool *present)
1352345c77cSMichael Roth {
136ebfd93b6SDaniel P. Berrange     trace_visit_optional(v, name, present);
137297a3646SMarkus Armbruster     if (v->optional) {
1380b2a0d6bSEric Blake         v->optional(v, name, present);
1392345c77cSMichael Roth     }
14029637a6eSEric Blake     return *present;
1412345c77cSMichael Roth }
1422345c77cSMichael Roth 
visit_policy_reject(Visitor * v,const char * name,unsigned special_features,Error ** errp)143a1307285SMarkus Armbruster bool visit_policy_reject(Visitor *v, const char *name,
144a1307285SMarkus Armbruster                          unsigned special_features, Error **errp)
145db291641SMarkus Armbruster {
146a1307285SMarkus Armbruster     trace_visit_policy_reject(v, name);
147a1307285SMarkus Armbruster     if (v->policy_reject) {
148a1307285SMarkus Armbruster         return v->policy_reject(v, name, special_features, errp);
149db291641SMarkus Armbruster     }
150a1307285SMarkus Armbruster     return false;
151db291641SMarkus Armbruster }
152db291641SMarkus Armbruster 
visit_policy_skip(Visitor * v,const char * name,unsigned special_features)153a1307285SMarkus Armbruster bool visit_policy_skip(Visitor *v, const char *name,
154a1307285SMarkus Armbruster                        unsigned special_features)
15591fa93e5SMarkus Armbruster {
156a1307285SMarkus Armbruster     trace_visit_policy_skip(v, name);
157a1307285SMarkus Armbruster     if (v->policy_skip) {
158a1307285SMarkus Armbruster         return v->policy_skip(v, name, special_features);
15991fa93e5SMarkus Armbruster     }
160a1307285SMarkus Armbruster     return false;
16191fa93e5SMarkus Armbruster }
16291fa93e5SMarkus Armbruster 
visit_set_policy(Visitor * v,CompatPolicy * policy)163ed29bb28SMarkus Armbruster void visit_set_policy(Visitor *v, CompatPolicy *policy)
164ed29bb28SMarkus Armbruster {
165ed29bb28SMarkus Armbruster     v->compat_policy = *policy;
166ed29bb28SMarkus Armbruster }
167ed29bb28SMarkus Armbruster 
visit_is_input(Visitor * v)16868ab47e4SEric Blake bool visit_is_input(Visitor *v)
16968ab47e4SEric Blake {
17068ab47e4SEric Blake     return v->type == VISITOR_INPUT;
17168ab47e4SEric Blake }
17268ab47e4SEric Blake 
visit_is_dealloc(Visitor * v)1738e08bf4eSMarkus Armbruster bool visit_is_dealloc(Visitor *v)
1748e08bf4eSMarkus Armbruster {
1758e08bf4eSMarkus Armbruster     return v->type == VISITOR_DEALLOC;
1768e08bf4eSMarkus Armbruster }
1778e08bf4eSMarkus Armbruster 
visit_type_int(Visitor * v,const char * name,int64_t * obj,Error ** errp)178012d4c96SMarkus Armbruster bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
1792345c77cSMichael Roth {
180adfb264cSEric Blake     assert(obj);
181ebfd93b6SDaniel P. Berrange     trace_visit_type_int(v, name, obj);
182012d4c96SMarkus Armbruster     return v->type_int64(v, name, obj, errp);
1832345c77cSMichael Roth }
1842345c77cSMichael Roth 
visit_type_uintN(Visitor * v,uint64_t * obj,const char * name,uint64_t max,const char * type,Error ** errp)185012d4c96SMarkus Armbruster static bool visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
18604e070d2SEric Blake                              uint64_t max, const char *type, Error **errp)
18704e070d2SEric Blake {
18804e070d2SEric Blake     uint64_t value = *obj;
18904e070d2SEric Blake 
190faad584aSMarkus Armbruster     assert(v->type == VISITOR_INPUT || value <= max);
191faad584aSMarkus Armbruster 
192012d4c96SMarkus Armbruster     if (!v->type_uint64(v, name, &value, errp)) {
193012d4c96SMarkus Armbruster         return false;
194012d4c96SMarkus Armbruster     }
195012d4c96SMarkus Armbruster     if (value > max) {
196faad584aSMarkus Armbruster         assert(v->type == VISITOR_INPUT);
19704e070d2SEric Blake         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
19804e070d2SEric Blake                    name ? name : "null", type);
199012d4c96SMarkus Armbruster         return false;
20004e070d2SEric Blake     }
201012d4c96SMarkus Armbruster     *obj = value;
202012d4c96SMarkus Armbruster     return true;
20304e070d2SEric Blake }
20404e070d2SEric Blake 
visit_type_uint8(Visitor * v,const char * name,uint8_t * obj,Error ** errp)205012d4c96SMarkus Armbruster bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
20651e72bc1SEric Blake                       Error **errp)
2074e27e819SMichael Roth {
208ebfd93b6SDaniel P. Berrange     uint64_t value;
209012d4c96SMarkus Armbruster     bool ok;
210ebfd93b6SDaniel P. Berrange 
211ebfd93b6SDaniel P. Berrange     trace_visit_type_uint8(v, name, obj);
212ebfd93b6SDaniel P. Berrange     value = *obj;
213012d4c96SMarkus Armbruster     ok = visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
2144e27e819SMichael Roth     *obj = value;
215012d4c96SMarkus Armbruster     return ok;
2164e27e819SMichael Roth }
2174e27e819SMichael Roth 
visit_type_uint16(Visitor * v,const char * name,uint16_t * obj,Error ** errp)218012d4c96SMarkus Armbruster bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
21904e070d2SEric Blake                        Error **errp)
2204e27e819SMichael Roth {
221ebfd93b6SDaniel P. Berrange     uint64_t value;
222012d4c96SMarkus Armbruster     bool ok;
223ebfd93b6SDaniel P. Berrange 
224ebfd93b6SDaniel P. Berrange     trace_visit_type_uint16(v, name, obj);
225ebfd93b6SDaniel P. Berrange     value = *obj;
226012d4c96SMarkus Armbruster     ok = visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
2274e27e819SMichael Roth     *obj = value;
228012d4c96SMarkus Armbruster     return ok;
2294e27e819SMichael Roth }
2304e27e819SMichael Roth 
visit_type_uint32(Visitor * v,const char * name,uint32_t * obj,Error ** errp)231012d4c96SMarkus Armbruster bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
23204e070d2SEric Blake                        Error **errp)
2334e27e819SMichael Roth {
234ebfd93b6SDaniel P. Berrange     uint64_t value;
235012d4c96SMarkus Armbruster     bool ok;
236ebfd93b6SDaniel P. Berrange 
237ebfd93b6SDaniel P. Berrange     trace_visit_type_uint32(v, name, obj);
238ebfd93b6SDaniel P. Berrange     value = *obj;
239012d4c96SMarkus Armbruster     ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
2404e27e819SMichael Roth     *obj = value;
241012d4c96SMarkus Armbruster     return ok;
2424e27e819SMichael Roth }
2434e27e819SMichael Roth 
visit_type_uint64(Visitor * v,const char * name,uint64_t * obj,Error ** errp)244012d4c96SMarkus Armbruster bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
24504e070d2SEric Blake                        Error **errp)
2464e27e819SMichael Roth {
247adfb264cSEric Blake     assert(obj);
248ebfd93b6SDaniel P. Berrange     trace_visit_type_uint64(v, name, obj);
249012d4c96SMarkus Armbruster     return v->type_uint64(v, name, obj, errp);
2504e27e819SMichael Roth }
2514e27e819SMichael Roth 
visit_type_intN(Visitor * v,int64_t * obj,const char * name,int64_t min,int64_t max,const char * type,Error ** errp)252012d4c96SMarkus Armbruster static bool visit_type_intN(Visitor *v, int64_t *obj, const char *name,
25304e070d2SEric Blake                             int64_t min, int64_t max, const char *type,
25404e070d2SEric Blake                             Error **errp)
2554e27e819SMichael Roth {
25604e070d2SEric Blake     int64_t value = *obj;
257297a3646SMarkus Armbruster 
258faad584aSMarkus Armbruster     assert(v->type == VISITOR_INPUT || (value >= min && value <= max));
259faad584aSMarkus Armbruster 
260012d4c96SMarkus Armbruster     if (!v->type_int64(v, name, &value, errp)) {
261012d4c96SMarkus Armbruster         return false;
262012d4c96SMarkus Armbruster     }
263012d4c96SMarkus Armbruster     if (value < min || value > max) {
264faad584aSMarkus Armbruster         assert(v->type == VISITOR_INPUT);
265c6bd8c70SMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
26604e070d2SEric Blake                    name ? name : "null", type);
267012d4c96SMarkus Armbruster         return false;
2684e27e819SMichael Roth     }
269012d4c96SMarkus Armbruster     *obj = value;
270012d4c96SMarkus Armbruster     return true;
2714e27e819SMichael Roth }
2724e27e819SMichael Roth 
visit_type_int8(Visitor * v,const char * name,int8_t * obj,Error ** errp)273012d4c96SMarkus Armbruster bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp)
27404e070d2SEric Blake {
275ebfd93b6SDaniel P. Berrange     int64_t value;
276012d4c96SMarkus Armbruster     bool ok;
277ebfd93b6SDaniel P. Berrange 
278ebfd93b6SDaniel P. Berrange     trace_visit_type_int8(v, name, obj);
279ebfd93b6SDaniel P. Berrange     value = *obj;
280012d4c96SMarkus Armbruster     ok = visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
28104e070d2SEric Blake     *obj = value;
282012d4c96SMarkus Armbruster     return ok;
28304e070d2SEric Blake }
28404e070d2SEric Blake 
visit_type_int16(Visitor * v,const char * name,int16_t * obj,Error ** errp)285012d4c96SMarkus Armbruster bool visit_type_int16(Visitor *v, const char *name, int16_t *obj,
28651e72bc1SEric Blake                       Error **errp)
2874e27e819SMichael Roth {
288ebfd93b6SDaniel P. Berrange     int64_t value;
289012d4c96SMarkus Armbruster     bool ok;
290ebfd93b6SDaniel P. Berrange 
291ebfd93b6SDaniel P. Berrange     trace_visit_type_int16(v, name, obj);
292ebfd93b6SDaniel P. Berrange     value = *obj;
293012d4c96SMarkus Armbruster     ok = visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t",
294012d4c96SMarkus Armbruster                          errp);
2954e27e819SMichael Roth     *obj = value;
296012d4c96SMarkus Armbruster     return ok;
2974e27e819SMichael Roth }
2984e27e819SMichael Roth 
visit_type_int32(Visitor * v,const char * name,int32_t * obj,Error ** errp)299012d4c96SMarkus Armbruster bool visit_type_int32(Visitor *v, const char *name, int32_t *obj,
30051e72bc1SEric Blake                       Error **errp)
3014e27e819SMichael Roth {
302ebfd93b6SDaniel P. Berrange     int64_t value;
303012d4c96SMarkus Armbruster     bool ok;
304ebfd93b6SDaniel P. Berrange 
305ebfd93b6SDaniel P. Berrange     trace_visit_type_int32(v, name, obj);
306ebfd93b6SDaniel P. Berrange     value = *obj;
307012d4c96SMarkus Armbruster     ok = visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t",
308012d4c96SMarkus Armbruster                         errp);
3094e27e819SMichael Roth     *obj = value;
310012d4c96SMarkus Armbruster     return ok;
3114e27e819SMichael Roth }
3124e27e819SMichael Roth 
visit_type_int64(Visitor * v,const char * name,int64_t * obj,Error ** errp)313012d4c96SMarkus Armbruster bool visit_type_int64(Visitor *v, const char *name, int64_t *obj,
31451e72bc1SEric Blake                       Error **errp)
3154e27e819SMichael Roth {
316adfb264cSEric Blake     assert(obj);
317ebfd93b6SDaniel P. Berrange     trace_visit_type_int64(v, name, obj);
318012d4c96SMarkus Armbruster     return v->type_int64(v, name, obj, errp);
3194e27e819SMichael Roth }
3204e27e819SMichael Roth 
visit_type_size(Visitor * v,const char * name,uint64_t * obj,Error ** errp)321012d4c96SMarkus Armbruster bool visit_type_size(Visitor *v, const char *name, uint64_t *obj,
32251e72bc1SEric Blake                      Error **errp)
323092705d4SLaszlo Ersek {
324adfb264cSEric Blake     assert(obj);
325ebfd93b6SDaniel P. Berrange     trace_visit_type_size(v, name, obj);
326b8877962SVasilis Liaskovitis     if (v->type_size) {
327012d4c96SMarkus Armbruster         return v->type_size(v, name, obj, errp);
328b8877962SVasilis Liaskovitis     }
329012d4c96SMarkus Armbruster     return v->type_uint64(v, name, obj, errp);
330092705d4SLaszlo Ersek }
331092705d4SLaszlo Ersek 
visit_type_bool(Visitor * v,const char * name,bool * obj,Error ** errp)332012d4c96SMarkus Armbruster bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
3332345c77cSMichael Roth {
334adfb264cSEric Blake     assert(obj);
335ebfd93b6SDaniel P. Berrange     trace_visit_type_bool(v, name, obj);
336012d4c96SMarkus Armbruster     return v->type_bool(v, name, obj, errp);
3372345c77cSMichael Roth }
3382345c77cSMichael Roth 
visit_type_str(Visitor * v,const char * name,char ** obj,Error ** errp)339012d4c96SMarkus Armbruster bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
3402345c77cSMichael Roth {
3417b3cb803SMarkus Armbruster     bool ok;
342e58d695eSEric Blake 
343e58d695eSEric Blake     assert(obj);
344adfb264cSEric Blake     /* TODO: Fix callers to not pass NULL when they mean "", so that we
345adfb264cSEric Blake      * can enable:
346a15fcc3cSEric Blake     assert(!(v->type & VISITOR_OUTPUT) || *obj);
347adfb264cSEric Blake      */
348ebfd93b6SDaniel P. Berrange     trace_visit_type_str(v, name, obj);
3497b3cb803SMarkus Armbruster     ok = v->type_str(v, name, obj, errp);
350a15fcc3cSEric Blake     if (v->type & VISITOR_INPUT) {
3517b3cb803SMarkus Armbruster         assert(ok != !*obj);
352e58d695eSEric Blake     }
3537b3cb803SMarkus Armbruster     return ok;
3542345c77cSMichael Roth }
3552345c77cSMichael Roth 
visit_type_number(Visitor * v,const char * name,double * obj,Error ** errp)356012d4c96SMarkus Armbruster bool visit_type_number(Visitor *v, const char *name, double *obj,
35751e72bc1SEric Blake                        Error **errp)
3582345c77cSMichael Roth {
359adfb264cSEric Blake     assert(obj);
360ebfd93b6SDaniel P. Berrange     trace_visit_type_number(v, name, obj);
361012d4c96SMarkus Armbruster     return v->type_number(v, name, obj, errp);
3622345c77cSMichael Roth }
3630f71a1e0SPaolo Bonzini 
visit_type_any(Visitor * v,const char * name,QObject ** obj,Error ** errp)364012d4c96SMarkus Armbruster bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
36528770e05SMarkus Armbruster {
366012d4c96SMarkus Armbruster     bool ok;
367e58d695eSEric Blake 
368e58d695eSEric Blake     assert(obj);
369adfb264cSEric Blake     assert(v->type != VISITOR_OUTPUT || *obj);
370ebfd93b6SDaniel P. Berrange     trace_visit_type_any(v, name, obj);
371012d4c96SMarkus Armbruster     ok = v->type_any(v, name, obj, errp);
372e58d695eSEric Blake     if (v->type == VISITOR_INPUT) {
373012d4c96SMarkus Armbruster         assert(ok != !*obj);
374e58d695eSEric Blake     }
375012d4c96SMarkus Armbruster     return ok;
37628770e05SMarkus Armbruster }
37728770e05SMarkus Armbruster 
visit_type_null(Visitor * v,const char * name,QNull ** obj,Error ** errp)378012d4c96SMarkus Armbruster bool visit_type_null(Visitor *v, const char *name, QNull **obj,
379d2f95f4dSMarkus Armbruster                      Error **errp)
3803bc97fd5SEric Blake {
381d2f95f4dSMarkus Armbruster     trace_visit_type_null(v, name, obj);
382012d4c96SMarkus Armbruster     return v->type_null(v, name, obj, errp);
3833bc97fd5SEric Blake }
3843bc97fd5SEric Blake 
output_type_enum(Visitor * v,const char * name,int * obj,const QEnumLookup * lookup,Error ** errp)385012d4c96SMarkus Armbruster static bool output_type_enum(Visitor *v, const char *name, int *obj,
386f7abe0ecSMarc-André Lureau                              const QEnumLookup *lookup, Error **errp)
3870f71a1e0SPaolo Bonzini {
3880f71a1e0SPaolo Bonzini     int value = *obj;
3890f71a1e0SPaolo Bonzini     char *enum_str;
3900f71a1e0SPaolo Bonzini 
391f7abe0ecSMarc-André Lureau     enum_str = (char *)qapi_enum_lookup(lookup, value);
392012d4c96SMarkus Armbruster     return visit_type_str(v, name, &enum_str, errp);
3930f71a1e0SPaolo Bonzini }
3940f71a1e0SPaolo Bonzini 
input_type_enum(Visitor * v,const char * name,int * obj,const QEnumLookup * lookup,Error ** errp)395012d4c96SMarkus Armbruster static bool input_type_enum(Visitor *v, const char *name, int *obj,
396f7abe0ecSMarc-André Lureau                             const QEnumLookup *lookup, Error **errp)
3970f71a1e0SPaolo Bonzini {
398113e47aeSMarkus Armbruster     int64_t value;
399aa237044SMarkus Armbruster     g_autofree char *enum_str = NULL;
4000f71a1e0SPaolo Bonzini 
401012d4c96SMarkus Armbruster     if (!visit_type_str(v, name, &enum_str, errp)) {
402012d4c96SMarkus Armbruster         return false;
4030f71a1e0SPaolo Bonzini     }
4040f71a1e0SPaolo Bonzini 
405f7abe0ecSMarc-André Lureau     value = qapi_enum_parse(lookup, enum_str, -1, NULL);
406113e47aeSMarkus Armbruster     if (value < 0) {
407ea29331bSMarkus Armbruster         error_setg(errp, "Parameter '%s' does not accept value '%s'",
408ea29331bSMarkus Armbruster                    name ? name : "null", enum_str);
409012d4c96SMarkus Armbruster         return false;
4100f71a1e0SPaolo Bonzini     }
4110f71a1e0SPaolo Bonzini 
412c8688760SMarkus Armbruster     if (lookup->special_features
413*7ce5fc63SMarkus Armbruster         && !compat_policy_input_ok(lookup->special_features[value],
414*7ce5fc63SMarkus Armbruster                                    &v->compat_policy,
415*7ce5fc63SMarkus Armbruster                                    ERROR_CLASS_GENERIC_ERROR,
416*7ce5fc63SMarkus Armbruster                                    "value", enum_str, errp)) {
417aa237044SMarkus Armbruster         return false;
418aa237044SMarkus Armbruster     }
419aa237044SMarkus Armbruster 
4200f71a1e0SPaolo Bonzini     *obj = value;
421012d4c96SMarkus Armbruster     return true;
4220f71a1e0SPaolo Bonzini }
423983f52d4SEric Blake 
visit_type_enum(Visitor * v,const char * name,int * obj,const QEnumLookup * lookup,Error ** errp)424012d4c96SMarkus Armbruster bool visit_type_enum(Visitor *v, const char *name, int *obj,
425f7abe0ecSMarc-André Lureau                      const QEnumLookup *lookup, Error **errp)
426983f52d4SEric Blake {
427f7abe0ecSMarc-André Lureau     assert(obj && lookup);
4286514532fSStefan Hajnoczi     trace_visit_type_enum(v, name, obj);
429a15fcc3cSEric Blake     switch (v->type) {
430a15fcc3cSEric Blake     case VISITOR_INPUT:
431012d4c96SMarkus Armbruster         return input_type_enum(v, name, obj, lookup, errp);
432a15fcc3cSEric Blake     case VISITOR_OUTPUT:
433012d4c96SMarkus Armbruster         return output_type_enum(v, name, obj, lookup, errp);
434a15fcc3cSEric Blake     case VISITOR_CLONE:
435a15fcc3cSEric Blake         /* nothing further to do, scalar value was already copied by
436a15fcc3cSEric Blake          * g_memdup() during visit_start_*() */
437012d4c96SMarkus Armbruster         return true;
438a15fcc3cSEric Blake     case VISITOR_DEALLOC:
439a15fcc3cSEric Blake         /* nothing to deallocate for a scalar */
440012d4c96SMarkus Armbruster         return true;
441012d4c96SMarkus Armbruster     default:
442012d4c96SMarkus Armbruster         abort();
443983f52d4SEric Blake     }
444983f52d4SEric Blake }
445