1 /* 2 * Core Definitions for QAPI Visitor Classes 3 * 4 * Copyright IBM, Corp. 2011 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 10 * See the COPYING.LIB file in the top-level directory. 11 * 12 */ 13 14 #include "qemu-common.h" 15 #include "qapi/qmp/qobject.h" 16 #include "qapi/qmp/qerror.h" 17 #include "qapi/visitor.h" 18 #include "qapi/visitor-impl.h" 19 20 void visit_start_struct(Visitor *v, void **obj, const char *kind, 21 const char *name, size_t size, Error **errp) 22 { 23 v->start_struct(v, obj, kind, name, size, errp); 24 } 25 26 void visit_end_struct(Visitor *v, Error **errp) 27 { 28 v->end_struct(v, errp); 29 } 30 31 void visit_start_implicit_struct(Visitor *v, void **obj, size_t size, 32 Error **errp) 33 { 34 if (v->start_implicit_struct) { 35 v->start_implicit_struct(v, obj, size, errp); 36 } 37 } 38 39 void visit_end_implicit_struct(Visitor *v, Error **errp) 40 { 41 if (v->end_implicit_struct) { 42 v->end_implicit_struct(v, errp); 43 } 44 } 45 46 void visit_start_list(Visitor *v, const char *name, Error **errp) 47 { 48 v->start_list(v, name, errp); 49 } 50 51 GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp) 52 { 53 return v->next_list(v, list, errp); 54 } 55 56 void visit_end_list(Visitor *v, Error **errp) 57 { 58 v->end_list(v, errp); 59 } 60 61 void visit_optional(Visitor *v, bool *present, const char *name, 62 Error **errp) 63 { 64 if (v->optional) { 65 v->optional(v, present, name, errp); 66 } 67 } 68 69 void visit_get_next_type(Visitor *v, int *obj, const int *qtypes, 70 const char *name, Error **errp) 71 { 72 if (v->get_next_type) { 73 v->get_next_type(v, obj, qtypes, name, errp); 74 } 75 } 76 77 void visit_type_enum(Visitor *v, int *obj, const char *strings[], 78 const char *kind, const char *name, Error **errp) 79 { 80 v->type_enum(v, obj, strings, kind, name, errp); 81 } 82 83 void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp) 84 { 85 v->type_int(v, obj, name, errp); 86 } 87 88 void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp) 89 { 90 int64_t value; 91 92 if (v->type_uint8) { 93 v->type_uint8(v, obj, name, errp); 94 } else { 95 value = *obj; 96 v->type_int(v, &value, name, errp); 97 if (value < 0 || value > UINT8_MAX) { 98 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 99 "uint8_t"); 100 return; 101 } 102 *obj = value; 103 } 104 } 105 106 void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp) 107 { 108 int64_t value; 109 110 if (v->type_uint16) { 111 v->type_uint16(v, obj, name, errp); 112 } else { 113 value = *obj; 114 v->type_int(v, &value, name, errp); 115 if (value < 0 || value > UINT16_MAX) { 116 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 117 "uint16_t"); 118 return; 119 } 120 *obj = value; 121 } 122 } 123 124 void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp) 125 { 126 int64_t value; 127 128 if (v->type_uint32) { 129 v->type_uint32(v, obj, name, errp); 130 } else { 131 value = *obj; 132 v->type_int(v, &value, name, errp); 133 if (value < 0 || value > UINT32_MAX) { 134 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 135 "uint32_t"); 136 return; 137 } 138 *obj = value; 139 } 140 } 141 142 void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp) 143 { 144 int64_t value; 145 146 if (v->type_uint64) { 147 v->type_uint64(v, obj, name, errp); 148 } else { 149 value = *obj; 150 v->type_int(v, &value, name, errp); 151 *obj = value; 152 } 153 } 154 155 void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp) 156 { 157 int64_t value; 158 159 if (v->type_int8) { 160 v->type_int8(v, obj, name, errp); 161 } else { 162 value = *obj; 163 v->type_int(v, &value, name, errp); 164 if (value < INT8_MIN || value > INT8_MAX) { 165 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 166 "int8_t"); 167 return; 168 } 169 *obj = value; 170 } 171 } 172 173 void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp) 174 { 175 int64_t value; 176 177 if (v->type_int16) { 178 v->type_int16(v, obj, name, errp); 179 } else { 180 value = *obj; 181 v->type_int(v, &value, name, errp); 182 if (value < INT16_MIN || value > INT16_MAX) { 183 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 184 "int16_t"); 185 return; 186 } 187 *obj = value; 188 } 189 } 190 191 void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp) 192 { 193 int64_t value; 194 195 if (v->type_int32) { 196 v->type_int32(v, obj, name, errp); 197 } else { 198 value = *obj; 199 v->type_int(v, &value, name, errp); 200 if (value < INT32_MIN || value > INT32_MAX) { 201 error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", 202 "int32_t"); 203 return; 204 } 205 *obj = value; 206 } 207 } 208 209 void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp) 210 { 211 if (v->type_int64) { 212 v->type_int64(v, obj, name, errp); 213 } else { 214 v->type_int(v, obj, name, errp); 215 } 216 } 217 218 void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp) 219 { 220 int64_t value; 221 222 if (v->type_size) { 223 v->type_size(v, obj, name, errp); 224 } else if (v->type_uint64) { 225 v->type_uint64(v, obj, name, errp); 226 } else { 227 value = *obj; 228 v->type_int(v, &value, name, errp); 229 *obj = value; 230 } 231 } 232 233 void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) 234 { 235 v->type_bool(v, obj, name, errp); 236 } 237 238 void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp) 239 { 240 v->type_str(v, obj, name, errp); 241 } 242 243 void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp) 244 { 245 v->type_number(v, obj, name, errp); 246 } 247 248 void output_type_enum(Visitor *v, int *obj, const char *strings[], 249 const char *kind, const char *name, 250 Error **errp) 251 { 252 int i = 0; 253 int value = *obj; 254 char *enum_str; 255 256 assert(strings); 257 while (strings[i++] != NULL); 258 if (value < 0 || value >= i - 1) { 259 error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null"); 260 return; 261 } 262 263 enum_str = (char *)strings[value]; 264 visit_type_str(v, &enum_str, name, errp); 265 } 266 267 void input_type_enum(Visitor *v, int *obj, const char *strings[], 268 const char *kind, const char *name, 269 Error **errp) 270 { 271 Error *local_err = NULL; 272 int64_t value = 0; 273 char *enum_str; 274 275 assert(strings); 276 277 visit_type_str(v, &enum_str, name, &local_err); 278 if (local_err) { 279 error_propagate(errp, local_err); 280 return; 281 } 282 283 while (strings[value] != NULL) { 284 if (strcmp(strings[value], enum_str) == 0) { 285 break; 286 } 287 value++; 288 } 289 290 if (strings[value] == NULL) { 291 error_set(errp, QERR_INVALID_PARAMETER, enum_str); 292 g_free(enum_str); 293 return; 294 } 295 296 g_free(enum_str); 297 *obj = value; 298 } 299