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