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