39
40
return container_of(v, QmpInputVisitor, visitor);
42
static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
43
static QObject *qmp_input_get_object(QmpInputVisitor *qiv,
47
if (qiv->nb_stack == 0) {
50
qobj = qiv->stack[qiv->nb_stack - 1].obj;
46
QObject *qobj = qiv->stack[qiv->nb_stack - 1].obj;
54
49
if (name && qobject_type(qobj) == QTYPE_QDICT) {
50
if (qiv->stack[qiv->nb_stack - 1].h) {
51
g_hash_table_remove(qiv->stack[qiv->nb_stack - 1].h, name);
55
53
return qdict_get(qobject_to_qdict(qobj), name);
56
} else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
54
} else if (qiv->stack[qiv->nb_stack - 1].entry) {
57
55
return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
64
static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp)
62
static void qdict_add_key(const char *key, QObject *obj, void *opaque)
64
GHashTable *h = opaque;
65
g_hash_table_insert(h, (gpointer) key, NULL);
68
static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)
72
if (qiv->nb_stack >= QIV_STACK_SIZE) {
73
error_set(errp, QERR_BUFFER_OVERRUN);
66
77
qiv->stack[qiv->nb_stack].obj = obj;
67
if (qobject_type(obj) == QTYPE_QLIST) {
68
qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj));
78
qiv->stack[qiv->nb_stack].entry = NULL;
79
qiv->stack[qiv->nb_stack].h = NULL;
81
if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {
82
h = g_hash_table_new(g_str_hash, g_str_equal);
83
qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);
84
qiv->stack[qiv->nb_stack].h = h;
72
if (qiv->nb_stack >= QIV_STACK_SIZE) {
73
error_set(errp, QERR_BUFFER_OVERRUN);
90
/** Only for qmp_input_pop. */
91
static gboolean always_true(gpointer key, gpointer val, gpointer user_pkey)
93
*(const char **)user_pkey = (const char *)key;
78
97
static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
99
assert(qiv->nb_stack > 0);
102
GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
104
if (g_hash_table_size(top_ht)) {
106
g_hash_table_find(top_ht, always_true, &key);
107
error_set(errp, QERR_QMP_EXTRA_MEMBER, key);
109
g_hash_table_unref(top_ht);
81
if (qiv->nb_stack < 0) {
82
error_set(errp, QERR_BUFFER_OVERRUN);
87
116
static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind,
88
117
const char *name, size_t size, Error **errp)
90
119
QmpInputVisitor *qiv = to_qiv(v);
91
const QObject *qobj = qmp_input_get_object(qiv, name);
120
QObject *qobj = qmp_input_get_object(qiv, name);
93
123
if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
94
124
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
116
147
static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
118
149
QmpInputVisitor *qiv = to_qiv(v);
119
const QObject *qobj = qmp_input_get_object(qiv, name);
150
QObject *qobj = qmp_input_get_object(qiv, name);
121
152
if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
122
153
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
164
201
QmpInputVisitor *qiv = to_qiv(v);
165
const QObject *qobj = qmp_input_get_object(qiv, name);
202
QObject *qobj = qmp_input_get_object(qiv, name);
167
204
if (!qobj || qobject_type(qobj) != QTYPE_QINT) {
168
205
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
179
216
QmpInputVisitor *qiv = to_qiv(v);
180
const QObject *qobj = qmp_input_get_object(qiv, name);
217
QObject *qobj = qmp_input_get_object(qiv, name);
182
219
if (!qobj || qobject_type(qobj) != QTYPE_QBOOL) {
183
220
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
194
231
QmpInputVisitor *qiv = to_qiv(v);
195
const QObject *qobj = qmp_input_get_object(qiv, name);
232
QObject *qobj = qmp_input_get_object(qiv, name);
197
234
if (!qobj || qobject_type(qobj) != QTYPE_QSTRING) {
198
235
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
209
246
QmpInputVisitor *qiv = to_qiv(v);
210
const QObject *qobj = qmp_input_get_object(qiv, name);
247
QObject *qobj = qmp_input_get_object(qiv, name);
212
if (!qobj || qobject_type(qobj) != QTYPE_QFLOAT) {
249
if (!qobj || (qobject_type(qobj) != QTYPE_QFLOAT &&
250
qobject_type(qobj) != QTYPE_QINT)) {
213
251
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
218
*obj = qfloat_get_double(qobject_to_qfloat(qobj));
256
if (qobject_type(qobj) == QTYPE_QINT) {
257
*obj = qint_get_int(qobject_to_qint(qobj));
259
*obj = qfloat_get_double(qobject_to_qfloat(qobj));
221
263
static void qmp_input_start_optional(Visitor *v, bool *present,
222
264
const char *name, Error **errp)
224
266
QmpInputVisitor *qiv = to_qiv(v);
225
const QObject *qobj = qmp_input_get_object(qiv, name);
267
QObject *qobj = qmp_input_get_object(qiv, name);
228
270
*present = false;