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