xref: /qemu/qapi/qapi-visit-core.c (revision d195325b05199038b5907fa791729425b9720d21)
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 
142345c77cSMichael Roth #include "qapi/qapi-visit-core.h"
150f71a1e0SPaolo Bonzini #include "qapi/qapi-visit-impl.h"
162345c77cSMichael Roth 
172345c77cSMichael Roth void visit_start_handle(Visitor *v, void **obj, const char *kind,
182345c77cSMichael Roth                         const char *name, Error **errp)
192345c77cSMichael Roth {
202345c77cSMichael Roth     if (!error_is_set(errp) && v->start_handle) {
212345c77cSMichael Roth         v->start_handle(v, obj, kind, name, errp);
222345c77cSMichael Roth     }
232345c77cSMichael Roth }
242345c77cSMichael Roth 
252345c77cSMichael Roth void visit_end_handle(Visitor *v, Error **errp)
262345c77cSMichael Roth {
272345c77cSMichael Roth     if (!error_is_set(errp) && v->end_handle) {
282345c77cSMichael Roth         v->end_handle(v, errp);
292345c77cSMichael Roth     }
302345c77cSMichael Roth }
312345c77cSMichael Roth 
322345c77cSMichael Roth void visit_start_struct(Visitor *v, void **obj, const char *kind,
332345c77cSMichael Roth                         const char *name, size_t size, Error **errp)
342345c77cSMichael Roth {
352345c77cSMichael Roth     if (!error_is_set(errp)) {
362345c77cSMichael Roth         v->start_struct(v, obj, kind, name, size, errp);
372345c77cSMichael Roth     }
382345c77cSMichael Roth }
392345c77cSMichael Roth 
402345c77cSMichael Roth void visit_end_struct(Visitor *v, Error **errp)
412345c77cSMichael Roth {
42*d195325bSPaolo Bonzini     assert(!error_is_set(errp));
432345c77cSMichael Roth     v->end_struct(v, errp);
442345c77cSMichael Roth }
452345c77cSMichael Roth 
462345c77cSMichael Roth void visit_start_list(Visitor *v, const char *name, Error **errp)
472345c77cSMichael Roth {
482345c77cSMichael Roth     if (!error_is_set(errp)) {
492345c77cSMichael Roth         v->start_list(v, name, errp);
502345c77cSMichael Roth     }
512345c77cSMichael Roth }
522345c77cSMichael Roth 
532345c77cSMichael Roth GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
542345c77cSMichael Roth {
552345c77cSMichael Roth     if (!error_is_set(errp)) {
562345c77cSMichael Roth         return v->next_list(v, list, errp);
572345c77cSMichael Roth     }
582345c77cSMichael Roth 
592345c77cSMichael Roth     return 0;
602345c77cSMichael Roth }
612345c77cSMichael Roth 
622345c77cSMichael Roth void visit_end_list(Visitor *v, Error **errp)
632345c77cSMichael Roth {
64*d195325bSPaolo Bonzini     assert(!error_is_set(errp));
652345c77cSMichael Roth     v->end_list(v, errp);
662345c77cSMichael Roth }
672345c77cSMichael Roth 
682345c77cSMichael Roth void visit_start_optional(Visitor *v, bool *present, const char *name,
692345c77cSMichael Roth                           Error **errp)
702345c77cSMichael Roth {
712345c77cSMichael Roth     if (!error_is_set(errp) && v->start_optional) {
722345c77cSMichael Roth         v->start_optional(v, present, name, errp);
732345c77cSMichael Roth     }
742345c77cSMichael Roth }
752345c77cSMichael Roth 
762345c77cSMichael Roth void visit_end_optional(Visitor *v, Error **errp)
772345c77cSMichael Roth {
782345c77cSMichael Roth     if (!error_is_set(errp) && v->end_optional) {
792345c77cSMichael Roth         v->end_optional(v, errp);
802345c77cSMichael Roth     }
812345c77cSMichael Roth }
822345c77cSMichael Roth 
832345c77cSMichael Roth void visit_type_enum(Visitor *v, int *obj, const char *strings[],
842345c77cSMichael Roth                      const char *kind, const char *name, Error **errp)
852345c77cSMichael Roth {
862345c77cSMichael Roth     if (!error_is_set(errp)) {
872345c77cSMichael Roth         v->type_enum(v, obj, strings, kind, name, errp);
882345c77cSMichael Roth     }
892345c77cSMichael Roth }
902345c77cSMichael Roth 
912345c77cSMichael Roth void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
922345c77cSMichael Roth {
932345c77cSMichael Roth     if (!error_is_set(errp)) {
942345c77cSMichael Roth         v->type_int(v, obj, name, errp);
952345c77cSMichael Roth     }
962345c77cSMichael Roth }
972345c77cSMichael Roth 
984e27e819SMichael Roth void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
994e27e819SMichael Roth {
1004e27e819SMichael Roth     int64_t value;
1014e27e819SMichael Roth     if (!error_is_set(errp)) {
1024e27e819SMichael Roth         if (v->type_uint8) {
1034e27e819SMichael Roth             v->type_uint8(v, obj, name, errp);
1044e27e819SMichael Roth         } else {
1054e27e819SMichael Roth             value = *obj;
1064e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1074e27e819SMichael Roth             if (value < 0 || value > UINT8_MAX) {
1084e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1094e27e819SMichael Roth                           "uint8_t");
1104e27e819SMichael Roth                 return;
1114e27e819SMichael Roth             }
1124e27e819SMichael Roth             *obj = value;
1134e27e819SMichael Roth         }
1144e27e819SMichael Roth     }
1154e27e819SMichael Roth }
1164e27e819SMichael Roth 
1174e27e819SMichael Roth void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
1184e27e819SMichael Roth {
1194e27e819SMichael Roth     int64_t value;
1204e27e819SMichael Roth     if (!error_is_set(errp)) {
1214e27e819SMichael Roth         if (v->type_uint16) {
1224e27e819SMichael Roth             v->type_uint16(v, obj, name, errp);
1234e27e819SMichael Roth         } else {
1244e27e819SMichael Roth             value = *obj;
1254e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1264e27e819SMichael Roth             if (value < 0 || value > UINT16_MAX) {
1274e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1284e27e819SMichael Roth                           "uint16_t");
1294e27e819SMichael Roth                 return;
1304e27e819SMichael Roth             }
1314e27e819SMichael Roth             *obj = value;
1324e27e819SMichael Roth         }
1334e27e819SMichael Roth     }
1344e27e819SMichael Roth }
1354e27e819SMichael Roth 
1364e27e819SMichael Roth void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
1374e27e819SMichael Roth {
1384e27e819SMichael Roth     int64_t value;
1394e27e819SMichael Roth     if (!error_is_set(errp)) {
1404e27e819SMichael Roth         if (v->type_uint32) {
1414e27e819SMichael Roth             v->type_uint32(v, obj, name, errp);
1424e27e819SMichael Roth         } else {
1434e27e819SMichael Roth             value = *obj;
1444e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1454e27e819SMichael Roth             if (value < 0 || value > UINT32_MAX) {
1464e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1474e27e819SMichael Roth                           "uint32_t");
1484e27e819SMichael Roth                 return;
1494e27e819SMichael Roth             }
1504e27e819SMichael Roth             *obj = value;
1514e27e819SMichael Roth         }
1524e27e819SMichael Roth     }
1534e27e819SMichael Roth }
1544e27e819SMichael Roth 
1554e27e819SMichael Roth void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
1564e27e819SMichael Roth {
1574e27e819SMichael Roth     int64_t value;
1584e27e819SMichael Roth     if (!error_is_set(errp)) {
1594e27e819SMichael Roth         if (v->type_uint64) {
1604e27e819SMichael Roth             v->type_uint64(v, obj, name, errp);
1614e27e819SMichael Roth         } else {
1624e27e819SMichael Roth             value = *obj;
1634e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1644e27e819SMichael Roth             *obj = value;
1654e27e819SMichael Roth         }
1664e27e819SMichael Roth     }
1674e27e819SMichael Roth }
1684e27e819SMichael Roth 
1694e27e819SMichael Roth void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
1704e27e819SMichael Roth {
1714e27e819SMichael Roth     int64_t value;
1724e27e819SMichael Roth     if (!error_is_set(errp)) {
1734e27e819SMichael Roth         if (v->type_int8) {
1744e27e819SMichael Roth             v->type_int8(v, obj, name, errp);
1754e27e819SMichael Roth         } else {
1764e27e819SMichael Roth             value = *obj;
1774e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1784e27e819SMichael Roth             if (value < INT8_MIN || value > INT8_MAX) {
1794e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1804e27e819SMichael Roth                           "int8_t");
1814e27e819SMichael Roth                 return;
1824e27e819SMichael Roth             }
1834e27e819SMichael Roth             *obj = value;
1844e27e819SMichael Roth         }
1854e27e819SMichael Roth     }
1864e27e819SMichael Roth }
1874e27e819SMichael Roth 
1884e27e819SMichael Roth void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
1894e27e819SMichael Roth {
1904e27e819SMichael Roth     int64_t value;
1914e27e819SMichael Roth     if (!error_is_set(errp)) {
1924e27e819SMichael Roth         if (v->type_int16) {
1934e27e819SMichael Roth             v->type_int16(v, obj, name, errp);
1944e27e819SMichael Roth         } else {
1954e27e819SMichael Roth             value = *obj;
1964e27e819SMichael Roth             v->type_int(v, &value, name, errp);
1974e27e819SMichael Roth             if (value < INT16_MIN || value > INT16_MAX) {
1984e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
1994e27e819SMichael Roth                           "int16_t");
2004e27e819SMichael Roth                 return;
2014e27e819SMichael Roth             }
2024e27e819SMichael Roth             *obj = value;
2034e27e819SMichael Roth         }
2044e27e819SMichael Roth     }
2054e27e819SMichael Roth }
2064e27e819SMichael Roth 
2074e27e819SMichael Roth void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
2084e27e819SMichael Roth {
2094e27e819SMichael Roth     int64_t value;
2104e27e819SMichael Roth     if (!error_is_set(errp)) {
2114e27e819SMichael Roth         if (v->type_int32) {
2124e27e819SMichael Roth             v->type_int32(v, obj, name, errp);
2134e27e819SMichael Roth         } else {
2144e27e819SMichael Roth             value = *obj;
2154e27e819SMichael Roth             v->type_int(v, &value, name, errp);
2164e27e819SMichael Roth             if (value < INT32_MIN || value > INT32_MAX) {
2174e27e819SMichael Roth                 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
2184e27e819SMichael Roth                           "int32_t");
2194e27e819SMichael Roth                 return;
2204e27e819SMichael Roth             }
2214e27e819SMichael Roth             *obj = value;
2224e27e819SMichael Roth         }
2234e27e819SMichael Roth     }
2244e27e819SMichael Roth }
2254e27e819SMichael Roth 
2264e27e819SMichael Roth void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
2274e27e819SMichael Roth {
2284e27e819SMichael Roth     if (!error_is_set(errp)) {
2294e27e819SMichael Roth         if (v->type_int64) {
2304e27e819SMichael Roth             v->type_int64(v, obj, name, errp);
2314e27e819SMichael Roth         } else {
2324e27e819SMichael Roth             v->type_int(v, obj, name, errp);
2334e27e819SMichael Roth         }
2344e27e819SMichael Roth     }
2354e27e819SMichael Roth }
2364e27e819SMichael Roth 
2372345c77cSMichael Roth void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
2382345c77cSMichael Roth {
2392345c77cSMichael Roth     if (!error_is_set(errp)) {
2402345c77cSMichael Roth         v->type_bool(v, obj, name, errp);
2412345c77cSMichael Roth     }
2422345c77cSMichael Roth }
2432345c77cSMichael Roth 
2442345c77cSMichael Roth void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
2452345c77cSMichael Roth {
2462345c77cSMichael Roth     if (!error_is_set(errp)) {
2472345c77cSMichael Roth         v->type_str(v, obj, name, errp);
2482345c77cSMichael Roth     }
2492345c77cSMichael Roth }
2502345c77cSMichael Roth 
2512345c77cSMichael Roth void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
2522345c77cSMichael Roth {
2532345c77cSMichael Roth     if (!error_is_set(errp)) {
2542345c77cSMichael Roth         v->type_number(v, obj, name, errp);
2552345c77cSMichael Roth     }
2562345c77cSMichael Roth }
2570f71a1e0SPaolo Bonzini 
2580f71a1e0SPaolo Bonzini void output_type_enum(Visitor *v, int *obj, const char *strings[],
2590f71a1e0SPaolo Bonzini                       const char *kind, const char *name,
2600f71a1e0SPaolo Bonzini                       Error **errp)
2610f71a1e0SPaolo Bonzini {
2620f71a1e0SPaolo Bonzini     int i = 0;
2630f71a1e0SPaolo Bonzini     int value = *obj;
2640f71a1e0SPaolo Bonzini     char *enum_str;
2650f71a1e0SPaolo Bonzini 
2660f71a1e0SPaolo Bonzini     assert(strings);
2670f71a1e0SPaolo Bonzini     while (strings[i++] != NULL);
2680f71a1e0SPaolo Bonzini     if (value < 0 || value >= i - 1) {
2690f71a1e0SPaolo Bonzini         error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");
2700f71a1e0SPaolo Bonzini         return;
2710f71a1e0SPaolo Bonzini     }
2720f71a1e0SPaolo Bonzini 
2730f71a1e0SPaolo Bonzini     enum_str = (char *)strings[value];
2740f71a1e0SPaolo Bonzini     visit_type_str(v, &enum_str, name, errp);
2750f71a1e0SPaolo Bonzini }
2760f71a1e0SPaolo Bonzini 
2770f71a1e0SPaolo Bonzini void input_type_enum(Visitor *v, int *obj, const char *strings[],
2780f71a1e0SPaolo Bonzini                      const char *kind, const char *name,
2790f71a1e0SPaolo Bonzini                      Error **errp)
2800f71a1e0SPaolo Bonzini {
2810f71a1e0SPaolo Bonzini     int64_t value = 0;
2820f71a1e0SPaolo Bonzini     char *enum_str;
2830f71a1e0SPaolo Bonzini 
2840f71a1e0SPaolo Bonzini     assert(strings);
2850f71a1e0SPaolo Bonzini 
2860f71a1e0SPaolo Bonzini     visit_type_str(v, &enum_str, name, errp);
2870f71a1e0SPaolo Bonzini     if (error_is_set(errp)) {
2880f71a1e0SPaolo Bonzini         return;
2890f71a1e0SPaolo Bonzini     }
2900f71a1e0SPaolo Bonzini 
2910f71a1e0SPaolo Bonzini     while (strings[value] != NULL) {
2920f71a1e0SPaolo Bonzini         if (strcmp(strings[value], enum_str) == 0) {
2930f71a1e0SPaolo Bonzini             break;
2940f71a1e0SPaolo Bonzini         }
2950f71a1e0SPaolo Bonzini         value++;
2960f71a1e0SPaolo Bonzini     }
2970f71a1e0SPaolo Bonzini 
2980f71a1e0SPaolo Bonzini     if (strings[value] == NULL) {
29994c3db85SLuiz Capitulino         error_set(errp, QERR_INVALID_PARAMETER, enum_str);
3000f71a1e0SPaolo Bonzini         g_free(enum_str);
3010f71a1e0SPaolo Bonzini         return;
3020f71a1e0SPaolo Bonzini     }
3030f71a1e0SPaolo Bonzini 
3040f71a1e0SPaolo Bonzini     g_free(enum_str);
3050f71a1e0SPaolo Bonzini     *obj = value;
3060f71a1e0SPaolo Bonzini }
307