/*
 * Core Definitions for QAPI Visitor Classes
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#include "qemu-common.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qerror.h"
#include "qapi/visitor.h"
#include "qapi/visitor-impl.h"

void visit_start_struct(Visitor *v, void **obj, const char *kind,
                        const char *name, size_t size, Error **errp)
{
    v->start_struct(v, obj, kind, name, size, errp);
}

void visit_end_struct(Visitor *v, Error **errp)
{
    v->end_struct(v, errp);
}

void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
                                 Error **errp)
{
    if (v->start_implicit_struct) {
        v->start_implicit_struct(v, obj, size, errp);
    }
}

void visit_end_implicit_struct(Visitor *v, Error **errp)
{
    if (v->end_implicit_struct) {
        v->end_implicit_struct(v, errp);
    }
}

void visit_start_list(Visitor *v, const char *name, Error **errp)
{
    v->start_list(v, name, errp);
}

GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp)
{
    return v->next_list(v, list, errp);
}

void visit_end_list(Visitor *v, Error **errp)
{
    v->end_list(v, errp);
}

bool visit_start_union(Visitor *v, bool data_present, Error **errp)
{
    if (v->start_union) {
        return v->start_union(v, data_present, errp);
    }
    return true;
}

void visit_end_union(Visitor *v, bool data_present, Error **errp)
{
    if (v->end_union) {
        v->end_union(v, data_present, errp);
    }
}

void visit_optional(Visitor *v, bool *present, const char *name,
                    Error **errp)
{
    if (v->optional) {
        v->optional(v, present, name, errp);
    }
}

void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
                         const char *name, Error **errp)
{
    if (v->get_next_type) {
        v->get_next_type(v, obj, qtypes, name, errp);
    }
}

void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
                     const char *kind, const char *name, Error **errp)
{
    v->type_enum(v, obj, strings, kind, name, errp);
}

void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
{
    v->type_int(v, obj, name, errp);
}

void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_uint8) {
        v->type_uint8(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        if (value < 0 || value > UINT8_MAX) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "uint8_t");
            return;
        }
        *obj = value;
    }
}

void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_uint16) {
        v->type_uint16(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        if (value < 0 || value > UINT16_MAX) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "uint16_t");
            return;
        }
        *obj = value;
    }
}

void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_uint32) {
        v->type_uint32(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        if (value < 0 || value > UINT32_MAX) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "uint32_t");
            return;
        }
        *obj = value;
    }
}

void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_uint64) {
        v->type_uint64(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        *obj = value;
    }
}

void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_int8) {
        v->type_int8(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        if (value < INT8_MIN || value > INT8_MAX) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "int8_t");
            return;
        }
        *obj = value;
    }
}

void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_int16) {
        v->type_int16(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        if (value < INT16_MIN || value > INT16_MAX) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "int16_t");
            return;
        }
        *obj = value;
    }
}

void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_int32) {
        v->type_int32(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        if (value < INT32_MIN || value > INT32_MAX) {
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
                       name ? name : "null", "int32_t");
            return;
        }
        *obj = value;
    }
}

void visit_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
{
    if (v->type_int64) {
        v->type_int64(v, obj, name, errp);
    } else {
        v->type_int(v, obj, name, errp);
    }
}

void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
{
    int64_t value;

    if (v->type_size) {
        v->type_size(v, obj, name, errp);
    } else if (v->type_uint64) {
        v->type_uint64(v, obj, name, errp);
    } else {
        value = *obj;
        v->type_int(v, &value, name, errp);
        *obj = value;
    }
}

void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
{
    v->type_bool(v, obj, name, errp);
}

void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp)
{
    v->type_str(v, obj, name, errp);
}

void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
{
    v->type_number(v, obj, name, errp);
}

void visit_type_any(Visitor *v, QObject **obj, const char *name,
                    Error **errp)
{
    v->type_any(v, obj, name, errp);
}

void output_type_enum(Visitor *v, int *obj, const char * const strings[],
                      const char *kind, const char *name,
                      Error **errp)
{
    int i = 0;
    int value = *obj;
    char *enum_str;

    assert(strings);
    while (strings[i++] != NULL);
    if (value < 0 || value >= i - 1) {
        error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null");
        return;
    }

    enum_str = (char *)strings[value];
    visit_type_str(v, &enum_str, name, errp);
}

void input_type_enum(Visitor *v, int *obj, const char * const strings[],
                     const char *kind, const char *name,
                     Error **errp)
{
    Error *local_err = NULL;
    int64_t value = 0;
    char *enum_str;

    assert(strings);

    visit_type_str(v, &enum_str, name, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    while (strings[value] != NULL) {
        if (strcmp(strings[value], enum_str) == 0) {
            break;
        }
        value++;
    }

    if (strings[value] == NULL) {
        error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
        g_free(enum_str);
        return;
    }

    g_free(enum_str);
    *obj = value;
}
