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