xref: /qemu/qapi/qapi-visit-core.c (revision 69dd62dfd60631ba69201d8a197fde1ece4b4df3)
12345c77cSMichael Roth /*
22345c77cSMichael Roth  * Core Definitions for QAPI Visitor Classes
32345c77cSMichael Roth  *
42345c77cSMichael Roth  * Copyright IBM, Corp. 2011
52345c77cSMichael Roth  *
62345c77cSMichael Roth  * Authors:
72345c77cSMichael Roth  *  Anthony Liguori   <aliguori@us.ibm.com>
82345c77cSMichael Roth  *
92345c77cSMichael Roth  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
102345c77cSMichael Roth  * See the COPYING.LIB file in the top-level directory.
112345c77cSMichael Roth  *
122345c77cSMichael Roth  */
132345c77cSMichael Roth 
1479ee7df8SPaolo Bonzini #include "qemu-common.h"
15*69dd62dfSKevin Wolf #include "qapi/qmp/qobject.h"
167b1b5d19SPaolo Bonzini #include "qapi/qmp/qerror.h"
177b1b5d19SPaolo Bonzini #include "qapi/visitor.h"
187b1b5d19SPaolo Bonzini #include "qapi/visitor-impl.h"
192345c77cSMichael Roth 
202345c77cSMichael Roth void visit_start_handle(Visitor *v, void **obj, const char *kind,
212345c77cSMichael Roth                         const char *name, Error **errp)
222345c77cSMichael Roth {
232345c77cSMichael Roth     if (!error_is_set(errp) && v->start_handle) {
242345c77cSMichael Roth         v->start_handle(v, obj, kind, name, errp);
252345c77cSMichael Roth     }
262345c77cSMichael Roth }
272345c77cSMichael Roth 
282345c77cSMichael Roth void visit_end_handle(Visitor *v, Error **errp)
292345c77cSMichael Roth {
302345c77cSMichael Roth     if (!error_is_set(errp) && v->end_handle) {
312345c77cSMichael Roth         v->end_handle(v, errp);
322345c77cSMichael Roth     }
332345c77cSMichael Roth }
342345c77cSMichael Roth 
352345c77cSMichael Roth void visit_start_struct(Visitor *v, void **obj, const char *kind,
362345c77cSMichael Roth                         const char *name, size_t size, Error **errp)
372345c77cSMichael Roth {
382345c77cSMichael Roth     if (!error_is_set(errp)) {
392345c77cSMichael Roth         v->start_struct(v, obj, kind, name, size, errp);
402345c77cSMichael Roth     }
412345c77cSMichael Roth }
422345c77cSMichael Roth 
432345c77cSMichael Roth void visit_end_struct(Visitor *v, Error **errp)
442345c77cSMichael Roth {
45d195325bSPaolo Bonzini     assert(!error_is_set(errp));
462345c77cSMichael Roth     v->end_struct(v, errp);
472345c77cSMichael Roth }
482345c77cSMichael Roth 
49761d524dSKevin Wolf void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
50761d524dSKevin Wolf                                  Error **errp)
51761d524dSKevin Wolf {
52761d524dSKevin Wolf     if (!error_is_set(errp) && v->start_implicit_struct) {
53761d524dSKevin Wolf         v->start_implicit_struct(v, obj, size, errp);
54761d524dSKevin Wolf     }
55761d524dSKevin Wolf }
56761d524dSKevin Wolf 
57761d524dSKevin Wolf void visit_end_implicit_struct(Visitor *v, Error **errp)
58761d524dSKevin Wolf {
59761d524dSKevin Wolf     assert(!error_is_set(errp));
60761d524dSKevin Wolf     if (v->end_implicit_struct) {
61761d524dSKevin Wolf         v->end_implicit_struct(v, errp);
62761d524dSKevin Wolf     }
63761d524dSKevin Wolf }
64761d524dSKevin Wolf 
652345c77cSMichael Roth void visit_start_list(Visitor *v, const char *name, Error **errp)
662345c77cSMichael Roth {
672345c77cSMichael Roth     if (!error_is_set(errp)) {
682345c77cSMichael Roth         v->start_list(v, name, errp);
692345c77cSMichael Roth     }
702345c77cSMichael Roth }
712345c77cSMichael Roth 
722345c77cSMichael Roth GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
732345c77cSMichael Roth {
742345c77cSMichael Roth     if (!error_is_set(errp)) {
752345c77cSMichael Roth         return v->next_list(v, list, errp);
762345c77cSMichael Roth     }
772345c77cSMichael Roth 
782345c77cSMichael Roth     return 0;
792345c77cSMichael Roth }
802345c77cSMichael Roth 
812345c77cSMichael Roth void visit_end_list(Visitor *v, Error **errp)
822345c77cSMichael Roth {
83d195325bSPaolo Bonzini     assert(!error_is_set(errp));
842345c77cSMichael Roth     v->end_list(v, errp);
852345c77cSMichael Roth }
862345c77cSMichael Roth 
872345c77cSMichael Roth void visit_start_optional(Visitor *v, bool *present, const char *name,
882345c77cSMichael Roth                           Error **errp)
892345c77cSMichael Roth {
902345c77cSMichael Roth     if (!error_is_set(errp) && v->start_optional) {
912345c77cSMichael Roth         v->start_optional(v, present, name, errp);
922345c77cSMichael Roth     }
932345c77cSMichael Roth }
942345c77cSMichael Roth 
952345c77cSMichael Roth void visit_end_optional(Visitor *v, Error **errp)
962345c77cSMichael Roth {
972345c77cSMichael Roth     if (!error_is_set(errp) && v->end_optional) {
982345c77cSMichael Roth         v->end_optional(v, errp);
992345c77cSMichael Roth     }
1002345c77cSMichael Roth }
1012345c77cSMichael Roth 
102*69dd62dfSKevin Wolf void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
103*69dd62dfSKevin Wolf                          const char *name, Error **errp)
104*69dd62dfSKevin Wolf {
105*69dd62dfSKevin Wolf     if (!error_is_set(errp) && v->get_next_type) {
106*69dd62dfSKevin Wolf         v->get_next_type(v, obj, qtypes, name, errp);
107*69dd62dfSKevin Wolf     }
108*69dd62dfSKevin Wolf }
109*69dd62dfSKevin Wolf 
1102345c77cSMichael Roth void visit_type_enum(Visitor *v, int *obj, const char *strings[],
1112345c77cSMichael Roth                      const char *kind, const char *name, Error **errp)
1122345c77cSMichael Roth {
1132345c77cSMichael Roth     if (!error_is_set(errp)) {
1142345c77cSMichael Roth         v->type_enum(v, obj, strings, kind, name, errp);
1152345c77cSMichael Roth     }
1162345c77cSMichael Roth }
1172345c77cSMichael Roth 
1182345c77cSMichael Roth void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
1192345c77cSMichael Roth {
1202345c77cSMichael Roth     if (!error_is_set(errp)) {
1212345c77cSMichael Roth         v->type_int(v, obj, name, errp);
1222345c77cSMichael Roth     }
1232345c77cSMichael Roth }
1242345c77cSMichael Roth 
1254e27e819SMichael Roth void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
1264e27e819SMichael Roth {
1274e27e819SMichael Roth     int64_t value;
1284e27e819SMichael Roth     if (!error_is_set(errp)) {
1294e27e819SMichael Roth         if (v->type_uint8) {
1304e27e819SMichael Roth             v->type_uint8(v, obj, name, errp);
1314e27e819SMichael Roth         } else {
1324e27e819SMichael Roth             value = *obj;
1334e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1344e27e819SMichael Roth             if (value < 0 || value > UINT8_MAX) {
1354e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1364e27e819SMichael Roth                           "uint8_t");
1374e27e819SMichael Roth                 return;
1384e27e819SMichael Roth             }
1394e27e819SMichael Roth             *obj = value;
1404e27e819SMichael Roth         }
1414e27e819SMichael Roth     }
1424e27e819SMichael Roth }
1434e27e819SMichael Roth 
1444e27e819SMichael Roth void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
1454e27e819SMichael Roth {
1464e27e819SMichael Roth     int64_t value;
1474e27e819SMichael Roth     if (!error_is_set(errp)) {
1484e27e819SMichael Roth         if (v->type_uint16) {
1494e27e819SMichael Roth             v->type_uint16(v, obj, name, errp);
1504e27e819SMichael Roth         } else {
1514e27e819SMichael Roth             value = *obj;
1524e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1534e27e819SMichael Roth             if (value < 0 || value > UINT16_MAX) {
1544e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1554e27e819SMichael Roth                           "uint16_t");
1564e27e819SMichael Roth                 return;
1574e27e819SMichael Roth             }
1584e27e819SMichael Roth             *obj = value;
1594e27e819SMichael Roth         }
1604e27e819SMichael Roth     }
1614e27e819SMichael Roth }
1624e27e819SMichael Roth 
1634e27e819SMichael Roth void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
1644e27e819SMichael Roth {
1654e27e819SMichael Roth     int64_t value;
1664e27e819SMichael Roth     if (!error_is_set(errp)) {
1674e27e819SMichael Roth         if (v->type_uint32) {
1684e27e819SMichael Roth             v->type_uint32(v, obj, name, errp);
1694e27e819SMichael Roth         } else {
1704e27e819SMichael Roth             value = *obj;
1714e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1724e27e819SMichael Roth             if (value < 0 || value > UINT32_MAX) {
1734e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1744e27e819SMichael Roth                           "uint32_t");
1754e27e819SMichael Roth                 return;
1764e27e819SMichael Roth             }
1774e27e819SMichael Roth             *obj = value;
1784e27e819SMichael Roth         }
1794e27e819SMichael Roth     }
1804e27e819SMichael Roth }
1814e27e819SMichael Roth 
1824e27e819SMichael Roth void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
1834e27e819SMichael Roth {
1844e27e819SMichael Roth     int64_t value;
1854e27e819SMichael Roth     if (!error_is_set(errp)) {
1864e27e819SMichael Roth         if (v->type_uint64) {
1874e27e819SMichael Roth             v->type_uint64(v, obj, name, errp);
1884e27e819SMichael Roth         } else {
1894e27e819SMichael Roth             value = *obj;
1904e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1914e27e819SMichael Roth             *obj = value;
1924e27e819SMichael Roth         }
1934e27e819SMichael Roth     }
1944e27e819SMichael Roth }
1954e27e819SMichael Roth 
1964e27e819SMichael Roth void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
1974e27e819SMichael Roth {
1984e27e819SMichael Roth     int64_t value;
1994e27e819SMichael Roth     if (!error_is_set(errp)) {
2004e27e819SMichael Roth         if (v->type_int8) {
2014e27e819SMichael Roth             v->type_int8(v, obj, name, errp);
2024e27e819SMichael Roth         } else {
2034e27e819SMichael Roth             value = *obj;
2044e27e819SMichael Roth             v->type_int(v, &value, name, errp);
2054e27e819SMichael Roth             if (value < INT8_MIN || value > INT8_MAX) {
2064e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
2074e27e819SMichael Roth                           "int8_t");
2084e27e819SMichael Roth                 return;
2094e27e819SMichael Roth             }
2104e27e819SMichael Roth             *obj = value;
2114e27e819SMichael Roth         }
2124e27e819SMichael Roth     }
2134e27e819SMichael Roth }
2144e27e819SMichael Roth 
2154e27e819SMichael Roth void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
2164e27e819SMichael Roth {
2174e27e819SMichael Roth     int64_t value;
2184e27e819SMichael Roth     if (!error_is_set(errp)) {
2194e27e819SMichael Roth         if (v->type_int16) {
2204e27e819SMichael Roth             v->type_int16(v, obj, name, errp);
2214e27e819SMichael Roth         } else {
2224e27e819SMichael Roth             value = *obj;
2234e27e819SMichael Roth             v->type_int(v, &value, name, errp);
2244e27e819SMichael Roth             if (value < INT16_MIN || value > INT16_MAX) {
2254e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
2264e27e819SMichael Roth                           "int16_t");
2274e27e819SMichael Roth                 return;
2284e27e819SMichael Roth             }
2294e27e819SMichael Roth             *obj = value;
2304e27e819SMichael Roth         }
2314e27e819SMichael Roth     }
2324e27e819SMichael Roth }
2334e27e819SMichael Roth 
2344e27e819SMichael Roth void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
2354e27e819SMichael Roth {
2364e27e819SMichael Roth     int64_t value;
2374e27e819SMichael Roth     if (!error_is_set(errp)) {
2384e27e819SMichael Roth         if (v->type_int32) {
2394e27e819SMichael Roth             v->type_int32(v, obj, name, errp);
2404e27e819SMichael Roth         } else {
2414e27e819SMichael Roth             value = *obj;
2424e27e819SMichael Roth             v->type_int(v, &value, name, errp);
2434e27e819SMichael Roth             if (value < INT32_MIN || value > INT32_MAX) {
2444e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
2454e27e819SMichael Roth                           "int32_t");
2464e27e819SMichael Roth                 return;
2474e27e819SMichael Roth             }
2484e27e819SMichael Roth             *obj = value;
2494e27e819SMichael Roth         }
2504e27e819SMichael Roth     }
2514e27e819SMichael Roth }
2524e27e819SMichael Roth 
2534e27e819SMichael Roth void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
2544e27e819SMichael Roth {
2554e27e819SMichael Roth     if (!error_is_set(errp)) {
2564e27e819SMichael Roth         if (v->type_int64) {
2574e27e819SMichael Roth             v->type_int64(v, obj, name, errp);
2584e27e819SMichael Roth         } else {
2594e27e819SMichael Roth             v->type_int(v, obj, name, errp);
2604e27e819SMichael Roth         }
2614e27e819SMichael Roth     }
2624e27e819SMichael Roth }
2634e27e819SMichael Roth 
264092705d4SLaszlo Ersek void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
265092705d4SLaszlo Ersek {
266092705d4SLaszlo Ersek     if (!error_is_set(errp)) {
267092705d4SLaszlo Ersek         (v->type_size ? v->type_size : v->type_uint64)(v, obj, name, errp);
268092705d4SLaszlo Ersek     }
269092705d4SLaszlo Ersek }
270092705d4SLaszlo Ersek 
2712345c77cSMichael Roth void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
2722345c77cSMichael Roth {
2732345c77cSMichael Roth     if (!error_is_set(errp)) {
2742345c77cSMichael Roth         v->type_bool(v, obj, name, errp);
2752345c77cSMichael Roth     }
2762345c77cSMichael Roth }
2772345c77cSMichael Roth 
2782345c77cSMichael Roth void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
2792345c77cSMichael Roth {
2802345c77cSMichael Roth     if (!error_is_set(errp)) {
2812345c77cSMichael Roth         v->type_str(v, obj, name, errp);
2822345c77cSMichael Roth     }
2832345c77cSMichael Roth }
2842345c77cSMichael Roth 
2852345c77cSMichael Roth void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
2862345c77cSMichael Roth {
2872345c77cSMichael Roth     if (!error_is_set(errp)) {
2882345c77cSMichael Roth         v->type_number(v, obj, name, errp);
2892345c77cSMichael Roth     }
2902345c77cSMichael Roth }
2910f71a1e0SPaolo Bonzini 
2920f71a1e0SPaolo Bonzini void output_type_enum(Visitor *v, int *obj, const char *strings[],
2930f71a1e0SPaolo Bonzini                       const char *kind, const char *name,
2940f71a1e0SPaolo Bonzini                       Error **errp)
2950f71a1e0SPaolo Bonzini {
2960f71a1e0SPaolo Bonzini     int i = 0;
2970f71a1e0SPaolo Bonzini     int value = *obj;
2980f71a1e0SPaolo Bonzini     char *enum_str;
2990f71a1e0SPaolo Bonzini 
3000f71a1e0SPaolo Bonzini     assert(strings);
3010f71a1e0SPaolo Bonzini     while (strings[i++] != NULL);
3020f71a1e0SPaolo Bonzini     if (value < 0 || value >= i - 1) {
3030f71a1e0SPaolo Bonzini         error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");
3040f71a1e0SPaolo Bonzini         return;
3050f71a1e0SPaolo Bonzini     }
3060f71a1e0SPaolo Bonzini 
3070f71a1e0SPaolo Bonzini     enum_str = (char *)strings[value];
3080f71a1e0SPaolo Bonzini     visit_type_str(v, &enum_str, name, errp);
3090f71a1e0SPaolo Bonzini }
3100f71a1e0SPaolo Bonzini 
3110f71a1e0SPaolo Bonzini void input_type_enum(Visitor *v, int *obj, const char *strings[],
3120f71a1e0SPaolo Bonzini                      const char *kind, const char *name,
3130f71a1e0SPaolo Bonzini                      Error **errp)
3140f71a1e0SPaolo Bonzini {
3150f71a1e0SPaolo Bonzini     int64_t value = 0;
3160f71a1e0SPaolo Bonzini     char *enum_str;
3170f71a1e0SPaolo Bonzini 
3180f71a1e0SPaolo Bonzini     assert(strings);
3190f71a1e0SPaolo Bonzini 
3200f71a1e0SPaolo Bonzini     visit_type_str(v, &enum_str, name, errp);
3210f71a1e0SPaolo Bonzini     if (error_is_set(errp)) {
3220f71a1e0SPaolo Bonzini         return;
3230f71a1e0SPaolo Bonzini     }
3240f71a1e0SPaolo Bonzini 
3250f71a1e0SPaolo Bonzini     while (strings[value] != NULL) {
3260f71a1e0SPaolo Bonzini         if (strcmp(strings[value], enum_str) == 0) {
3270f71a1e0SPaolo Bonzini             break;
3280f71a1e0SPaolo Bonzini         }
3290f71a1e0SPaolo Bonzini         value++;
3300f71a1e0SPaolo Bonzini     }
3310f71a1e0SPaolo Bonzini 
3320f71a1e0SPaolo Bonzini     if (strings[value] == NULL) {
33394c3db85SLuiz Capitulino         error_set(errp, QERR_INVALID_PARAMETER, enum_str);
3340f71a1e0SPaolo Bonzini         g_free(enum_str);
3350f71a1e0SPaolo Bonzini         return;
3360f71a1e0SPaolo Bonzini     }
3370f71a1e0SPaolo Bonzini 
3380f71a1e0SPaolo Bonzini     g_free(enum_str);
3390f71a1e0SPaolo Bonzini     *obj = value;
3400f71a1e0SPaolo Bonzini }
341