2 * Core Definitions for QAPI/QMP Command Registry
4 * Copyright IBM, Corp. 2011
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
14 #include "qmp-output-visitor.h"
15 #include "qemu-queue.h"
16 #include "qemu-common.h"
17 #include "qemu-objects.h"
19 typedef struct QStackEntry
22 QTAILQ_ENTRY(QStackEntry
) node
;
25 typedef QTAILQ_HEAD(QStack
, QStackEntry
) QStack
;
27 struct QmpOutputVisitor
33 #define qmp_output_add(qov, name, value) qmp_output_add_obj(qov, name, QOBJECT(value))
34 #define qmp_output_push(qov, value) qmp_output_push_obj(qov, QOBJECT(value))
36 static QmpOutputVisitor
*to_qov(Visitor
*v
)
38 return container_of(v
, QmpOutputVisitor
, visitor
);
41 static void qmp_output_push_obj(QmpOutputVisitor
*qov
, QObject
*value
)
43 QStackEntry
*e
= qemu_mallocz(sizeof(*e
));
46 QTAILQ_INSERT_HEAD(&qov
->stack
, e
, node
);
49 static QObject
*qmp_output_pop(QmpOutputVisitor
*qov
)
51 QStackEntry
*e
= QTAILQ_FIRST(&qov
->stack
);
53 QTAILQ_REMOVE(&qov
->stack
, e
, node
);
59 static QObject
*qmp_output_first(QmpOutputVisitor
*qov
)
61 QStackEntry
*e
= QTAILQ_LAST(&qov
->stack
, QStack
);
65 static QObject
*qmp_output_last(QmpOutputVisitor
*qov
)
67 QStackEntry
*e
= QTAILQ_FIRST(&qov
->stack
);
71 static void qmp_output_add_obj(QmpOutputVisitor
*qov
, const char *name
, QObject
*value
)
75 if (QTAILQ_EMPTY(&qov
->stack
)) {
76 qmp_output_push_obj(qov
, value
);
80 cur
= qmp_output_last(qov
);
82 switch (qobject_type(cur
)) {
84 qdict_put_obj(qobject_to_qdict(cur
), name
, value
);
87 qlist_append_obj(qobject_to_qlist(cur
), value
);
90 qobject_decref(qmp_output_pop(qov
));
91 qmp_output_push_obj(qov
, value
);
96 static void qmp_output_start_struct(Visitor
*v
, void **obj
, const char *kind
, const char *name
, size_t unused
, Error
**errp
)
98 QmpOutputVisitor
*qov
= to_qov(v
);
99 QDict
*dict
= qdict_new();
101 qmp_output_add(qov
, name
, dict
);
102 qmp_output_push(qov
, dict
);
105 static void qmp_output_end_struct(Visitor
*v
, Error
**errp
)
107 QmpOutputVisitor
*qov
= to_qov(v
);
111 static void qmp_output_start_list(Visitor
*v
, const char *name
, Error
**errp
)
113 QmpOutputVisitor
*qov
= to_qov(v
);
114 QList
*list
= qlist_new();
116 qmp_output_add(qov
, name
, list
);
117 qmp_output_push(qov
, list
);
120 static GenericList
*qmp_output_next_list(Visitor
*v
, GenericList
**list
, Error
**errp
)
122 GenericList
*retval
= *list
;
123 *list
= retval
->next
;
127 static void qmp_output_end_list(Visitor
*v
, Error
**errp
)
129 QmpOutputVisitor
*qov
= to_qov(v
);
133 static void qmp_output_type_int(Visitor
*v
, int64_t *obj
, const char *name
, Error
**errp
)
135 QmpOutputVisitor
*qov
= to_qov(v
);
136 qmp_output_add(qov
, name
, qint_from_int(*obj
));
139 static void qmp_output_type_bool(Visitor
*v
, bool *obj
, const char *name
, Error
**errp
)
141 QmpOutputVisitor
*qov
= to_qov(v
);
142 qmp_output_add(qov
, name
, qbool_from_int(*obj
));
145 static void qmp_output_type_str(Visitor
*v
, char **obj
, const char *name
, Error
**errp
)
147 QmpOutputVisitor
*qov
= to_qov(v
);
149 qmp_output_add(qov
, name
, qstring_from_str(*obj
));
151 qmp_output_add(qov
, name
, qstring_from_str(""));
155 static void qmp_output_type_number(Visitor
*v
, double *obj
, const char *name
, Error
**errp
)
157 QmpOutputVisitor
*qov
= to_qov(v
);
158 qmp_output_add(qov
, name
, qfloat_from_double(*obj
));
161 static void qmp_output_type_enum(Visitor
*v
, int *obj
, const char *kind
, const char *name
, Error
**errp
)
163 int64_t value
= *obj
;
164 qmp_output_type_int(v
, &value
, name
, errp
);
167 QObject
*qmp_output_get_qobject(QmpOutputVisitor
*qov
)
169 QObject
*obj
= qmp_output_first(qov
);
176 Visitor
*qmp_output_get_visitor(QmpOutputVisitor
*v
)
181 void qmp_output_visitor_cleanup(QmpOutputVisitor
*v
)
183 QStackEntry
*e
, *tmp
;
185 QTAILQ_FOREACH_SAFE(e
, &v
->stack
, node
, tmp
) {
186 QTAILQ_REMOVE(&v
->stack
, e
, node
);
188 qobject_decref(e
->value
);
196 QmpOutputVisitor
*qmp_output_visitor_new(void)
200 v
= qemu_mallocz(sizeof(*v
));
202 v
->visitor
.start_struct
= qmp_output_start_struct
;
203 v
->visitor
.end_struct
= qmp_output_end_struct
;
204 v
->visitor
.start_list
= qmp_output_start_list
;
205 v
->visitor
.next_list
= qmp_output_next_list
;
206 v
->visitor
.end_list
= qmp_output_end_list
;
207 v
->visitor
.type_enum
= qmp_output_type_enum
;
208 v
->visitor
.type_int
= qmp_output_type_int
;
209 v
->visitor
.type_bool
= qmp_output_type_bool
;
210 v
->visitor
.type_str
= qmp_output_type_str
;
211 v
->visitor
.type_number
= qmp_output_type_number
;
213 QTAILQ_INIT(&v
->stack
);