Annotation of qemu/qapi/qmp-output-visitor.c, revision 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.