Annotation of qemu/qapi/qmp-output-visitor.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  * Core Definitions for QAPI/QMP Command Registry
                      3:  *
                      4:  * Copyright IBM, Corp. 2011
                      5:  *
                      6:  * Authors:
                      7:  *  Anthony Liguori   <[email protected]>
                      8:  *
                      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.
                     11:  *
                     12:  */
                     13: 
                     14: #include "qmp-output-visitor.h"
1.1.1.3 ! root       15: #include "qapi/qapi-visit-impl.h"
1.1       root       16: #include "qemu-queue.h"
                     17: #include "qemu-common.h"
                     18: #include "qemu-objects.h"
                     19: #include "qerror.h"
                     20: 
                     21: typedef struct QStackEntry
                     22: {
                     23:     QObject *value;
1.1.1.2   root       24:     bool is_list_head;
1.1       root       25:     QTAILQ_ENTRY(QStackEntry) node;
                     26: } QStackEntry;
                     27: 
                     28: typedef QTAILQ_HEAD(QStack, QStackEntry) QStack;
                     29: 
                     30: struct QmpOutputVisitor
                     31: {
                     32:     Visitor visitor;
                     33:     QStack stack;
                     34: };
                     35: 
                     36: #define qmp_output_add(qov, name, value) \
                     37:     qmp_output_add_obj(qov, name, QOBJECT(value))
                     38: #define qmp_output_push(qov, value) qmp_output_push_obj(qov, QOBJECT(value))
                     39: 
                     40: static QmpOutputVisitor *to_qov(Visitor *v)
                     41: {
                     42:     return container_of(v, QmpOutputVisitor, visitor);
                     43: }
                     44: 
                     45: static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
                     46: {
1.1.1.2   root       47:     QStackEntry *e = g_malloc0(sizeof(*e));
1.1       root       48: 
                     49:     e->value = value;
1.1.1.2   root       50:     if (qobject_type(e->value) == QTYPE_QLIST) {
                     51:         e->is_list_head = true;
                     52:     }
1.1       root       53:     QTAILQ_INSERT_HEAD(&qov->stack, e, node);
                     54: }
                     55: 
                     56: static QObject *qmp_output_pop(QmpOutputVisitor *qov)
                     57: {
                     58:     QStackEntry *e = QTAILQ_FIRST(&qov->stack);
                     59:     QObject *value;
                     60:     QTAILQ_REMOVE(&qov->stack, e, node);
                     61:     value = e->value;
1.1.1.2   root       62:     g_free(e);
1.1       root       63:     return value;
                     64: }
                     65: 
                     66: static QObject *qmp_output_first(QmpOutputVisitor *qov)
                     67: {
                     68:     QStackEntry *e = QTAILQ_LAST(&qov->stack, QStack);
                     69:     return e->value;
                     70: }
                     71: 
                     72: static QObject *qmp_output_last(QmpOutputVisitor *qov)
                     73: {
                     74:     QStackEntry *e = QTAILQ_FIRST(&qov->stack);
                     75:     return e->value;
                     76: }
                     77: 
                     78: static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
                     79:                                QObject *value)
                     80: {
                     81:     QObject *cur;
                     82: 
                     83:     if (QTAILQ_EMPTY(&qov->stack)) {
                     84:         qmp_output_push_obj(qov, value);
                     85:         return;
                     86:     }
                     87: 
                     88:     cur = qmp_output_last(qov);
                     89: 
                     90:     switch (qobject_type(cur)) {
                     91:     case QTYPE_QDICT:
                     92:         qdict_put_obj(qobject_to_qdict(cur), name, value);
                     93:         break;
                     94:     case QTYPE_QLIST:
                     95:         qlist_append_obj(qobject_to_qlist(cur), value);
                     96:         break;
                     97:     default:
                     98:         qobject_decref(qmp_output_pop(qov));
                     99:         qmp_output_push_obj(qov, value);
                    100:         break;
                    101:     }
                    102: }
                    103: 
                    104: static void qmp_output_start_struct(Visitor *v, void **obj, const char *kind,
                    105:                                     const char *name, size_t unused,
                    106:                                     Error **errp)
                    107: {
                    108:     QmpOutputVisitor *qov = to_qov(v);
                    109:     QDict *dict = qdict_new();
                    110: 
                    111:     qmp_output_add(qov, name, dict);
                    112:     qmp_output_push(qov, dict);
                    113: }
                    114: 
                    115: static void qmp_output_end_struct(Visitor *v, Error **errp)
                    116: {
                    117:     QmpOutputVisitor *qov = to_qov(v);
                    118:     qmp_output_pop(qov);
                    119: }
                    120: 
                    121: static void qmp_output_start_list(Visitor *v, const char *name, Error **errp)
                    122: {
                    123:     QmpOutputVisitor *qov = to_qov(v);
                    124:     QList *list = qlist_new();
                    125: 
                    126:     qmp_output_add(qov, name, list);
                    127:     qmp_output_push(qov, list);
                    128: }
                    129: 
1.1.1.2   root      130: static GenericList *qmp_output_next_list(Visitor *v, GenericList **listp,
1.1       root      131:                                          Error **errp)
                    132: {
1.1.1.2   root      133:     GenericList *list = *listp;
                    134:     QmpOutputVisitor *qov = to_qov(v);
                    135:     QStackEntry *e = QTAILQ_FIRST(&qov->stack);
                    136: 
                    137:     assert(e);
                    138:     if (e->is_list_head) {
                    139:         e->is_list_head = false;
                    140:         return list;
                    141:     }
                    142: 
                    143:     return list ? list->next : NULL;
1.1       root      144: }
                    145: 
                    146: static void qmp_output_end_list(Visitor *v, Error **errp)
                    147: {
                    148:     QmpOutputVisitor *qov = to_qov(v);
                    149:     qmp_output_pop(qov);
                    150: }
                    151: 
                    152: static void qmp_output_type_int(Visitor *v, int64_t *obj, const char *name,
                    153:                                 Error **errp)
                    154: {
                    155:     QmpOutputVisitor *qov = to_qov(v);
                    156:     qmp_output_add(qov, name, qint_from_int(*obj));
                    157: }
                    158: 
                    159: static void qmp_output_type_bool(Visitor *v, bool *obj, const char *name,
                    160:                                  Error **errp)
                    161: {
                    162:     QmpOutputVisitor *qov = to_qov(v);
                    163:     qmp_output_add(qov, name, qbool_from_int(*obj));
                    164: }
                    165: 
                    166: static void qmp_output_type_str(Visitor *v, char **obj, const char *name,
                    167:                                 Error **errp)
                    168: {
                    169:     QmpOutputVisitor *qov = to_qov(v);
                    170:     if (*obj) {
                    171:         qmp_output_add(qov, name, qstring_from_str(*obj));
                    172:     } else {
                    173:         qmp_output_add(qov, name, qstring_from_str(""));
                    174:     }
                    175: }
                    176: 
                    177: static void qmp_output_type_number(Visitor *v, double *obj, const char *name,
                    178:                                    Error **errp)
                    179: {
                    180:     QmpOutputVisitor *qov = to_qov(v);
                    181:     qmp_output_add(qov, name, qfloat_from_double(*obj));
                    182: }
                    183: 
                    184: QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
                    185: {
                    186:     QObject *obj = qmp_output_first(qov);
                    187:     if (obj) {
                    188:         qobject_incref(obj);
                    189:     }
                    190:     return obj;
                    191: }
                    192: 
                    193: Visitor *qmp_output_get_visitor(QmpOutputVisitor *v)
                    194: {
                    195:     return &v->visitor;
                    196: }
                    197: 
                    198: void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
                    199: {
                    200:     QStackEntry *e, *tmp;
                    201: 
1.1.1.3 ! root      202:     /* The bottom QStackEntry, if any, owns the root QObject. See the
        !           203:      * qmp_output_push_obj() invocations in qmp_output_add_obj(). */
        !           204:     QObject *root = QTAILQ_EMPTY(&v->stack) ? NULL : qmp_output_first(v);
        !           205: 
1.1       root      206:     QTAILQ_FOREACH_SAFE(e, &v->stack, node, tmp) {
                    207:         QTAILQ_REMOVE(&v->stack, e, node);
1.1.1.2   root      208:         g_free(e);
1.1       root      209:     }
                    210: 
1.1.1.3 ! root      211:     qobject_decref(root);
1.1.1.2   root      212:     g_free(v);
1.1       root      213: }
                    214: 
                    215: QmpOutputVisitor *qmp_output_visitor_new(void)
                    216: {
                    217:     QmpOutputVisitor *v;
                    218: 
1.1.1.2   root      219:     v = g_malloc0(sizeof(*v));
1.1       root      220: 
                    221:     v->visitor.start_struct = qmp_output_start_struct;
                    222:     v->visitor.end_struct = qmp_output_end_struct;
                    223:     v->visitor.start_list = qmp_output_start_list;
                    224:     v->visitor.next_list = qmp_output_next_list;
                    225:     v->visitor.end_list = qmp_output_end_list;
1.1.1.3 ! root      226:     v->visitor.type_enum = output_type_enum;
1.1       root      227:     v->visitor.type_int = qmp_output_type_int;
                    228:     v->visitor.type_bool = qmp_output_type_bool;
                    229:     v->visitor.type_str = qmp_output_type_str;
                    230:     v->visitor.type_number = qmp_output_type_number;
                    231: 
                    232:     QTAILQ_INIT(&v->stack);
                    233: 
                    234:     return v;
                    235: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.