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

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

unix.superglobalmegacorp.com

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