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

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

unix.superglobalmegacorp.com

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