2 * Core Definitions for QAPI/QMP Command Registry
4 * Copyright (C) 2012-2016 Red Hat, Inc.
5 * Copyright IBM, Corp. 2011
8 * Anthony Liguori <aliguori@us.ibm.com>
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.
15 #include "qemu/osdep.h"
16 #include "qapi/compat-policy.h"
17 #include "qapi/qobject-output-visitor.h"
18 #include "qapi/visitor-impl.h"
19 #include "qemu/queue.h"
20 #include "qapi/qmp/qbool.h"
21 #include "qapi/qmp/qdict.h"
22 #include "qapi/qmp/qlist.h"
23 #include "qapi/qmp/qnull.h"
24 #include "qapi/qmp/qnum.h"
25 #include "qapi/qmp/qstring.h"
27 typedef struct QStackEntry
{
29 void *qapi
; /* sanity check that caller uses same pointer */
30 QSLIST_ENTRY(QStackEntry
) node
;
33 struct QObjectOutputVisitor
{
35 CompatPolicyOutput deprecated_policy
;
37 QSLIST_HEAD(, QStackEntry
) stack
; /* Stack of unfinished containers */
38 QObject
*root
; /* Root of the output visit */
39 QObject
**result
; /* User's storage location for result */
42 #define qobject_output_add(qov, name, value) \
43 qobject_output_add_obj(qov, name, QOBJECT(value))
44 #define qobject_output_push(qov, value, qapi) \
45 qobject_output_push_obj(qov, QOBJECT(value), qapi)
47 static QObjectOutputVisitor
*to_qov(Visitor
*v
)
49 return container_of(v
, QObjectOutputVisitor
, visitor
);
52 /* Push @value onto the stack of current QObjects being built */
53 static void qobject_output_push_obj(QObjectOutputVisitor
*qov
, QObject
*value
,
56 QStackEntry
*e
= g_malloc0(sizeof(*e
));
62 QSLIST_INSERT_HEAD(&qov
->stack
, e
, node
);
65 /* Pop a value off the stack of QObjects being built, and return it. */
66 static QObject
*qobject_output_pop(QObjectOutputVisitor
*qov
, void *qapi
)
68 QStackEntry
*e
= QSLIST_FIRST(&qov
->stack
);
72 assert(e
->qapi
== qapi
);
73 QSLIST_REMOVE_HEAD(&qov
->stack
, node
);
80 /* Add @value to the current QObject being built.
81 * If the stack is visiting a dictionary or list, @value is now owned
82 * by that container. Otherwise, @value is now the root. */
83 static void qobject_output_add_obj(QObjectOutputVisitor
*qov
, const char *name
,
86 QStackEntry
*e
= QSLIST_FIRST(&qov
->stack
);
87 QObject
*cur
= e
? e
->value
: NULL
;
90 /* Don't allow reuse of visitor on more than one root */
94 switch (qobject_type(cur
)) {
97 qdict_put_obj(qobject_to(QDict
, cur
), name
, value
);
101 qlist_append_obj(qobject_to(QList
, cur
), value
);
104 g_assert_not_reached();
109 static bool qobject_output_start_struct(Visitor
*v
, const char *name
,
110 void **obj
, size_t unused
, Error
**errp
)
112 QObjectOutputVisitor
*qov
= to_qov(v
);
113 QDict
*dict
= qdict_new();
115 qobject_output_add(qov
, name
, dict
);
116 qobject_output_push(qov
, dict
, obj
);
120 static void qobject_output_end_struct(Visitor
*v
, void **obj
)
122 QObjectOutputVisitor
*qov
= to_qov(v
);
123 QObject
*value
= qobject_output_pop(qov
, obj
);
124 assert(qobject_type(value
) == QTYPE_QDICT
);
127 static bool qobject_output_start_list(Visitor
*v
, const char *name
,
128 GenericList
**listp
, size_t size
,
131 QObjectOutputVisitor
*qov
= to_qov(v
);
132 QList
*list
= qlist_new();
134 qobject_output_add(qov
, name
, list
);
135 qobject_output_push(qov
, list
, listp
);
139 static GenericList
*qobject_output_next_list(Visitor
*v
, GenericList
*tail
,
145 static void qobject_output_end_list(Visitor
*v
, void **obj
)
147 QObjectOutputVisitor
*qov
= to_qov(v
);
148 QObject
*value
= qobject_output_pop(qov
, obj
);
149 assert(qobject_type(value
) == QTYPE_QLIST
);
152 static bool qobject_output_type_int64(Visitor
*v
, const char *name
,
153 int64_t *obj
, Error
**errp
)
155 QObjectOutputVisitor
*qov
= to_qov(v
);
156 qobject_output_add(qov
, name
, qnum_from_int(*obj
));
160 static bool qobject_output_type_uint64(Visitor
*v
, const char *name
,
161 uint64_t *obj
, Error
**errp
)
163 QObjectOutputVisitor
*qov
= to_qov(v
);
164 qobject_output_add(qov
, name
, qnum_from_uint(*obj
));
168 static bool qobject_output_type_bool(Visitor
*v
, const char *name
, bool *obj
,
171 QObjectOutputVisitor
*qov
= to_qov(v
);
172 qobject_output_add(qov
, name
, qbool_from_bool(*obj
));
176 static bool qobject_output_type_str(Visitor
*v
, const char *name
, char **obj
,
179 QObjectOutputVisitor
*qov
= to_qov(v
);
181 qobject_output_add(qov
, name
, qstring_from_str(*obj
));
183 qobject_output_add(qov
, name
, qstring_from_str(""));
188 static bool qobject_output_type_number(Visitor
*v
, const char *name
,
189 double *obj
, Error
**errp
)
191 QObjectOutputVisitor
*qov
= to_qov(v
);
192 qobject_output_add(qov
, name
, qnum_from_double(*obj
));
196 static bool qobject_output_type_any(Visitor
*v
, const char *name
,
197 QObject
**obj
, Error
**errp
)
199 QObjectOutputVisitor
*qov
= to_qov(v
);
201 qobject_output_add_obj(qov
, name
, qobject_ref(*obj
));
205 static bool qobject_output_type_null(Visitor
*v
, const char *name
,
206 QNull
**obj
, Error
**errp
)
208 QObjectOutputVisitor
*qov
= to_qov(v
);
209 qobject_output_add(qov
, name
, qnull());
213 static bool qobject_output_deprecated(Visitor
*v
, const char *name
)
215 QObjectOutputVisitor
*qov
= to_qov(v
);
217 return qov
->deprecated_policy
!= COMPAT_POLICY_OUTPUT_HIDE
;
220 /* Finish building, and return the root object.
221 * The root object is never null. The caller becomes the object's
222 * owner, and should use qobject_unref() when done with it. */
223 static void qobject_output_complete(Visitor
*v
, void *opaque
)
225 QObjectOutputVisitor
*qov
= to_qov(v
);
227 /* A visit must have occurred, with each start paired with end. */
228 assert(qov
->root
&& QSLIST_EMPTY(&qov
->stack
));
229 assert(opaque
== qov
->result
);
231 *qov
->result
= qobject_ref(qov
->root
);
235 static void qobject_output_free(Visitor
*v
)
237 QObjectOutputVisitor
*qov
= to_qov(v
);
240 while (!QSLIST_EMPTY(&qov
->stack
)) {
241 e
= QSLIST_FIRST(&qov
->stack
);
242 QSLIST_REMOVE_HEAD(&qov
->stack
, node
);
246 qobject_unref(qov
->root
);
250 Visitor
*qobject_output_visitor_new(QObject
**result
)
252 QObjectOutputVisitor
*v
;
254 v
= g_malloc0(sizeof(*v
));
256 v
->visitor
.type
= VISITOR_OUTPUT
;
257 v
->visitor
.start_struct
= qobject_output_start_struct
;
258 v
->visitor
.end_struct
= qobject_output_end_struct
;
259 v
->visitor
.start_list
= qobject_output_start_list
;
260 v
->visitor
.next_list
= qobject_output_next_list
;
261 v
->visitor
.end_list
= qobject_output_end_list
;
262 v
->visitor
.type_int64
= qobject_output_type_int64
;
263 v
->visitor
.type_uint64
= qobject_output_type_uint64
;
264 v
->visitor
.type_bool
= qobject_output_type_bool
;
265 v
->visitor
.type_str
= qobject_output_type_str
;
266 v
->visitor
.type_number
= qobject_output_type_number
;
267 v
->visitor
.type_any
= qobject_output_type_any
;
268 v
->visitor
.type_null
= qobject_output_type_null
;
269 v
->visitor
.deprecated
= qobject_output_deprecated
;
270 v
->visitor
.complete
= qobject_output_complete
;
271 v
->visitor
.free
= qobject_output_free
;
279 void qobject_output_visitor_set_policy(Visitor
*v
,
280 CompatPolicyOutput deprecated
)
282 QObjectOutputVisitor
*qov
= to_qov(v
);
284 qov
->deprecated_policy
= deprecated
;