#include "qapi/qobject-input-visitor.h"
#include "qapi/visitor-impl.h"
#include "qemu/queue.h"
-#include "qemu-common.h"
#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/types.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qnull.h"
+#include "qapi/qmp/qnum.h"
+#include "qapi/qmp/qstring.h"
#include "qemu/cutils.h"
#include "qemu/option.h"
if (qobject_type(qobj) == QTYPE_QDICT) {
assert(name);
- ret = qdict_get(qobject_to_qdict(qobj), name);
+ ret = qdict_get(qobject_to(QDict, qobj), name);
if (tos->h && consume && ret) {
bool removed = g_hash_table_remove(tos->h, name);
assert(removed);
return NULL;
}
- qstr = qobject_to_qstring(qobj);
+ qstr = qobject_to(QString, qobj);
if (!qstr) {
switch (qobject_type(qobj)) {
case QTYPE_QDICT:
return qstring_get_str(qstr);
}
-static void qdict_add_key(const char *key, QObject *obj, void *opaque)
-{
- GHashTable *h = opaque;
- g_hash_table_insert(h, (gpointer) key, NULL);
-}
-
static const QListEntry *qobject_input_push(QObjectInputVisitor *qiv,
const char *name,
QObject *obj, void *qapi)
{
GHashTable *h;
StackObject *tos = g_new0(StackObject, 1);
+ QDict *qdict = qobject_to(QDict, obj);
+ QList *qlist = qobject_to(QList, obj);
+ const QDictEntry *entry;
assert(obj);
tos->name = name;
tos->obj = obj;
tos->qapi = qapi;
- if (qobject_type(obj) == QTYPE_QDICT) {
+ if (qdict) {
h = g_hash_table_new(g_str_hash, g_str_equal);
- qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
+ for (entry = qdict_first(qdict);
+ entry;
+ entry = qdict_next(qdict, entry)) {
+ g_hash_table_insert(h, (void *)qdict_entry_key(entry), NULL);
+ }
tos->h = h;
} else {
- assert(qobject_type(obj) == QTYPE_QLIST);
- tos->entry = qlist_first(qobject_to_qlist(obj));
+ assert(qlist);
+ tos->entry = qlist_first(qlist);
tos->index = -1;
}
}
-static void qobject_input_check_struct(Visitor *v, Error **errp)
+static bool qobject_input_check_struct(Visitor *v, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
StackObject *tos = QSLIST_FIRST(&qiv->stack);
if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
error_setg(errp, "Parameter '%s' is unexpected",
full_name(qiv, key));
+ return false;
}
+ return true;
}
static void qobject_input_stack_object_free(StackObject *tos)
qobject_input_stack_object_free(tos);
}
-static void qobject_input_start_struct(Visitor *v, const char *name, void **obj,
+static bool qobject_input_start_struct(Visitor *v, const char *name, void **obj,
size_t size, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
*obj = NULL;
}
if (!qobj) {
- return;
+ return false;
}
if (qobject_type(qobj) != QTYPE_QDICT) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "object");
- return;
+ return false;
}
qobject_input_push(qiv, name, qobj, obj);
if (obj) {
*obj = g_malloc0(size);
}
+ return true;
}
static void qobject_input_end_struct(Visitor *v, void **obj)
}
-static void qobject_input_start_list(Visitor *v, const char *name,
+static bool qobject_input_start_list(Visitor *v, const char *name,
GenericList **list, size_t size,
Error **errp)
{
*list = NULL;
}
if (!qobj) {
- return;
+ return false;
}
if (qobject_type(qobj) != QTYPE_QLIST) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "array");
- return;
+ return false;
}
entry = qobject_input_push(qiv, name, qobj, list);
if (entry && list) {
*list = g_malloc0(size);
}
+ return true;
}
static GenericList *qobject_input_next_list(Visitor *v, GenericList *tail,
QObjectInputVisitor *qiv = to_qiv(v);
StackObject *tos = QSLIST_FIRST(&qiv->stack);
- assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
+ assert(tos && qobject_to(QList, tos->obj));
if (!tos->entry) {
return NULL;
return tail->next;
}
-static void qobject_input_check_list(Visitor *v, Error **errp)
+static bool qobject_input_check_list(Visitor *v, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
StackObject *tos = QSLIST_FIRST(&qiv->stack);
- assert(tos && tos->obj && qobject_type(tos->obj) == QTYPE_QLIST);
+ assert(tos && qobject_to(QList, tos->obj));
if (tos->entry) {
error_setg(errp, "Only %u list elements expected in %s",
tos->index + 1, full_name_nth(qiv, NULL, 1));
+ return false;
}
+ return true;
}
static void qobject_input_end_list(Visitor *v, void **obj)
qobject_input_pop(v, obj);
}
-static void qobject_input_start_alternate(Visitor *v, const char *name,
+static bool qobject_input_start_alternate(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
Error **errp)
{
if (!qobj) {
*obj = NULL;
- return;
+ return false;
}
*obj = g_malloc0(size);
(*obj)->type = qobject_type(qobj);
+ return true;
}
-static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
+static bool qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
QNum *qnum;
if (!qobj) {
- return;
+ return false;
}
- qnum = qobject_to_qnum(qobj);
+ qnum = qobject_to(QNum, qobj);
if (!qnum || !qnum_get_try_int(qnum, obj)) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "integer");
+ return false;
}
+ return true;
}
-static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
+static bool qobject_input_type_int64_keyval(Visitor *v, const char *name,
int64_t *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
const char *str = qobject_input_get_keyval(qiv, name, errp);
if (!str) {
- return;
+ return false;
}
if (qemu_strtoi64(str, NULL, 0, obj) < 0) {
/* TODO report -ERANGE more nicely */
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
full_name(qiv, name), "integer");
+ return false;
}
+ return true;
}
-static void qobject_input_type_uint64(Visitor *v, const char *name,
+static bool qobject_input_type_uint64(Visitor *v, const char *name,
uint64_t *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
int64_t val;
if (!qobj) {
- return;
+ return false;
}
- qnum = qobject_to_qnum(qobj);
+ qnum = qobject_to(QNum, qobj);
if (!qnum) {
goto err;
}
if (qnum_get_try_uint(qnum, obj)) {
- return;
+ return true;
}
/* Need to accept negative values for backward compatibility */
if (qnum_get_try_int(qnum, &val)) {
*obj = val;
- return;
+ return true;
}
err:
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
full_name(qiv, name), "uint64");
+ return false;
}
-static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
+static bool qobject_input_type_uint64_keyval(Visitor *v, const char *name,
uint64_t *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
const char *str = qobject_input_get_keyval(qiv, name, errp);
if (!str) {
- return;
+ return false;
}
if (qemu_strtou64(str, NULL, 0, obj) < 0) {
/* TODO report -ERANGE more nicely */
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
full_name(qiv, name), "integer");
+ return false;
}
+ return true;
}
-static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj,
+static bool qobject_input_type_bool(Visitor *v, const char *name, bool *obj,
Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
QBool *qbool;
if (!qobj) {
- return;
+ return false;
}
- qbool = qobject_to_qbool(qobj);
+ qbool = qobject_to(QBool, qobj);
if (!qbool) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "boolean");
- return;
+ return false;
}
*obj = qbool_get_bool(qbool);
+ return true;
}
-static void qobject_input_type_bool_keyval(Visitor *v, const char *name,
+static bool qobject_input_type_bool_keyval(Visitor *v, const char *name,
bool *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
const char *str = qobject_input_get_keyval(qiv, name, errp);
if (!str) {
- return;
+ return false;
}
- if (!strcmp(str, "on")) {
- *obj = true;
- } else if (!strcmp(str, "off")) {
- *obj = false;
- } else {
+ if (!qapi_bool_parse(name, str, obj, NULL)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
full_name(qiv, name), "'on' or 'off'");
+ return false;
}
+ return true;
}
-static void qobject_input_type_str(Visitor *v, const char *name, char **obj,
+static bool qobject_input_type_str(Visitor *v, const char *name, char **obj,
Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
*obj = NULL;
if (!qobj) {
- return;
+ return false;
}
- qstr = qobject_to_qstring(qobj);
+ qstr = qobject_to(QString, qobj);
if (!qstr) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "string");
- return;
+ return false;
}
*obj = g_strdup(qstring_get_str(qstr));
+ return true;
}
-static void qobject_input_type_str_keyval(Visitor *v, const char *name,
+static bool qobject_input_type_str_keyval(Visitor *v, const char *name,
char **obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
const char *str = qobject_input_get_keyval(qiv, name, errp);
*obj = g_strdup(str);
+ return !!str;
}
-static void qobject_input_type_number(Visitor *v, const char *name, double *obj,
+static bool qobject_input_type_number(Visitor *v, const char *name, double *obj,
Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
QNum *qnum;
if (!qobj) {
- return;
+ return false;
}
- qnum = qobject_to_qnum(qobj);
+ qnum = qobject_to(QNum, qobj);
if (!qnum) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "number");
- return;
+ return false;
}
*obj = qnum_get_double(qnum);
+ return true;
}
-static void qobject_input_type_number_keyval(Visitor *v, const char *name,
+static bool qobject_input_type_number_keyval(Visitor *v, const char *name,
double *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
const char *str = qobject_input_get_keyval(qiv, name, errp);
- char *endp;
+ double val;
if (!str) {
- return;
+ return false;
}
- errno = 0;
- *obj = strtod(str, &endp);
- if (errno || endp == str || *endp || !isfinite(*obj)) {
+ if (qemu_strtod_finite(str, NULL, &val)) {
/* TODO report -ERANGE more nicely */
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "number");
+ return false;
}
+
+ *obj = val;
+ return true;
}
-static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj,
+static bool qobject_input_type_any(Visitor *v, const char *name, QObject **obj,
Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
*obj = NULL;
if (!qobj) {
- return;
+ return false;
}
- qobject_incref(qobj);
- *obj = qobj;
+ *obj = qobject_ref(qobj);
+ return true;
}
-static void qobject_input_type_null(Visitor *v, const char *name, Error **errp)
+static bool qobject_input_type_null(Visitor *v, const char *name,
+ QNull **obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
+ *obj = NULL;
if (!qobj) {
- return;
+ return false;
}
if (qobject_type(qobj) != QTYPE_QNULL) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "null");
+ return false;
}
+ *obj = qnull();
+ return true;
}
-static void qobject_input_type_size_keyval(Visitor *v, const char *name,
+static bool qobject_input_type_size_keyval(Visitor *v, const char *name,
uint64_t *obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
const char *str = qobject_input_get_keyval(qiv, name, errp);
if (!str) {
- return;
+ return false;
}
if (qemu_strtosz(str, NULL, obj) < 0) {
/* TODO report -ERANGE more nicely */
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
full_name(qiv, name), "size");
+ return false;
}
+ return true;
}
static void qobject_input_optional(Visitor *v, const char *name, bool *present)
qobject_input_stack_object_free(tos);
}
- qobject_decref(qiv->root);
+ qobject_unref(qiv->root);
if (qiv->errname) {
g_string_free(qiv->errname, TRUE);
}
v->visitor.optional = qobject_input_optional;
v->visitor.free = qobject_input_free;
- v->root = obj;
- qobject_incref(obj);
+ v->root = qobject_ref(obj);
return v;
}
if (is_json) {
obj = qobject_from_json(str, errp);
if (!obj) {
- /* Work around qobject_from_json() lossage TODO fix that */
- if (errp && !*errp) {
- error_setg(errp, "JSON parse error");
- return NULL;
- }
return NULL;
}
- args = qobject_to_qdict(obj);
+ args = qobject_to(QDict, obj);
assert(args);
v = qobject_input_visitor_new(QOBJECT(args));
} else {
- args = keyval_parse(str, implied_key, errp);
+ args = keyval_parse(str, implied_key, NULL, errp);
if (!args) {
return NULL;
}
v = qobject_input_visitor_new_keyval(QOBJECT(args));
}
- QDECREF(args);
+ qobject_unref(args);
return v;
}