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