Annotation of qemu/qapi/qmp-input-visitor.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Input Visitor
        !             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-input-visitor.h"
        !            15: #include "qemu-queue.h"
        !            16: #include "qemu-common.h"
        !            17: #include "qemu-objects.h"
        !            18: #include "qerror.h"
        !            19: 
        !            20: #define QIV_STACK_SIZE 1024
        !            21: 
        !            22: typedef struct StackObject
        !            23: {
        !            24:     const QObject *obj;
        !            25:     const  QListEntry *entry;
        !            26: } StackObject;
        !            27: 
        !            28: struct QmpInputVisitor
        !            29: {
        !            30:     Visitor visitor;
        !            31:     QObject *obj;
        !            32:     StackObject stack[QIV_STACK_SIZE];
        !            33:     int nb_stack;
        !            34: };
        !            35: 
        !            36: static QmpInputVisitor *to_qiv(Visitor *v)
        !            37: {
        !            38:     return container_of(v, QmpInputVisitor, visitor);
        !            39: }
        !            40: 
        !            41: static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
        !            42:                                            const char *name)
        !            43: {
        !            44:     const QObject *qobj;
        !            45: 
        !            46:     if (qiv->nb_stack == 0) {
        !            47:         qobj = qiv->obj;
        !            48:     } else {
        !            49:         qobj = qiv->stack[qiv->nb_stack - 1].obj;
        !            50:     }
        !            51: 
        !            52:     if (name && qobject_type(qobj) == QTYPE_QDICT) {
        !            53:         return qdict_get(qobject_to_qdict(qobj), name);
        !            54:     } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
        !            55:         return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
        !            56:     }
        !            57: 
        !            58:     return qobj;
        !            59: }
        !            60: 
        !            61: static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp)
        !            62: {
        !            63:     qiv->stack[qiv->nb_stack].obj = obj;
        !            64:     if (qobject_type(obj) == QTYPE_QLIST) {
        !            65:         qiv->stack[qiv->nb_stack].entry = qlist_first(qobject_to_qlist(obj));
        !            66:     }
        !            67:     qiv->nb_stack++;
        !            68: 
        !            69:     if (qiv->nb_stack >= QIV_STACK_SIZE) {
        !            70:         error_set(errp, QERR_BUFFER_OVERRUN);
        !            71:         return;
        !            72:     }
        !            73: }
        !            74: 
        !            75: static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
        !            76: {
        !            77:     qiv->nb_stack--;
        !            78:     if (qiv->nb_stack < 0) {
        !            79:         error_set(errp, QERR_BUFFER_OVERRUN);
        !            80:         return;
        !            81:     }
        !            82: }
        !            83: 
        !            84: static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind,
        !            85:                                    const char *name, size_t size, Error **errp)
        !            86: {
        !            87:     QmpInputVisitor *qiv = to_qiv(v);
        !            88:     const QObject *qobj = qmp_input_get_object(qiv, name);
        !            89: 
        !            90:     if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {
        !            91:         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
        !            92:                   "QDict");
        !            93:         return;
        !            94:     }
        !            95: 
        !            96:     qmp_input_push(qiv, qobj, errp);
        !            97:     if (error_is_set(errp)) {
        !            98:         return;
        !            99:     }
        !           100: 
        !           101:     if (obj) {
        !           102:         *obj = qemu_mallocz(size);
        !           103:     }
        !           104: }
        !           105: 
        !           106: static void qmp_input_end_struct(Visitor *v, Error **errp)
        !           107: {
        !           108:     QmpInputVisitor *qiv = to_qiv(v);
        !           109: 
        !           110:     qmp_input_pop(qiv, errp);
        !           111: }
        !           112: 
        !           113: static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
        !           114: {
        !           115:     QmpInputVisitor *qiv = to_qiv(v);
        !           116:     const QObject *qobj = qmp_input_get_object(qiv, name);
        !           117: 
        !           118:     if (!qobj || qobject_type(qobj) != QTYPE_QLIST) {
        !           119:         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
        !           120:                   "list");
        !           121:         return;
        !           122:     }
        !           123: 
        !           124:     qmp_input_push(qiv, qobj, errp);
        !           125: }
        !           126: 
        !           127: static GenericList *qmp_input_next_list(Visitor *v, GenericList **list,
        !           128:                                         Error **errp)
        !           129: {
        !           130:     QmpInputVisitor *qiv = to_qiv(v);
        !           131:     GenericList *entry;
        !           132:     StackObject *so = &qiv->stack[qiv->nb_stack - 1];
        !           133: 
        !           134:     if (so->entry == NULL) {
        !           135:         return NULL;
        !           136:     }
        !           137: 
        !           138:     entry = qemu_mallocz(sizeof(*entry));
        !           139:     if (*list) {
        !           140:         so->entry = qlist_next(so->entry);
        !           141:         if (so->entry == NULL) {
        !           142:             qemu_free(entry);
        !           143:             return NULL;
        !           144:         }
        !           145:         (*list)->next = entry;
        !           146:     }
        !           147:     *list = entry;
        !           148: 
        !           149: 
        !           150:     return entry;
        !           151: }
        !           152: 
        !           153: static void qmp_input_end_list(Visitor *v, Error **errp)
        !           154: {
        !           155:     QmpInputVisitor *qiv = to_qiv(v);
        !           156: 
        !           157:     qmp_input_pop(qiv, errp);
        !           158: }
        !           159: 
        !           160: static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name,
        !           161:                                Error **errp)
        !           162: {
        !           163:     QmpInputVisitor *qiv = to_qiv(v);
        !           164:     const QObject *qobj = qmp_input_get_object(qiv, name);
        !           165: 
        !           166:     if (!qobj || qobject_type(qobj) != QTYPE_QINT) {
        !           167:         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
        !           168:                   "integer");
        !           169:         return;
        !           170:     }
        !           171: 
        !           172:     *obj = qint_get_int(qobject_to_qint(qobj));
        !           173: }
        !           174: 
        !           175: static void qmp_input_type_bool(Visitor *v, bool *obj, const char *name,
        !           176:                                 Error **errp)
        !           177: {
        !           178:     QmpInputVisitor *qiv = to_qiv(v);
        !           179:     const QObject *qobj = qmp_input_get_object(qiv, name);
        !           180: 
        !           181:     if (!qobj || qobject_type(qobj) != QTYPE_QBOOL) {
        !           182:         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
        !           183:                   "boolean");
        !           184:         return;
        !           185:     }
        !           186: 
        !           187:     *obj = qbool_get_int(qobject_to_qbool(qobj));
        !           188: }
        !           189: 
        !           190: static void qmp_input_type_str(Visitor *v, char **obj, const char *name,
        !           191:                                Error **errp)
        !           192: {
        !           193:     QmpInputVisitor *qiv = to_qiv(v);
        !           194:     const QObject *qobj = qmp_input_get_object(qiv, name);
        !           195: 
        !           196:     if (!qobj || qobject_type(qobj) != QTYPE_QSTRING) {
        !           197:         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
        !           198:                   "string");
        !           199:         return;
        !           200:     }
        !           201: 
        !           202:     *obj = qemu_strdup(qstring_get_str(qobject_to_qstring(qobj)));
        !           203: }
        !           204: 
        !           205: static void qmp_input_type_number(Visitor *v, double *obj, const char *name,
        !           206:                                   Error **errp)
        !           207: {
        !           208:     QmpInputVisitor *qiv = to_qiv(v);
        !           209:     const QObject *qobj = qmp_input_get_object(qiv, name);
        !           210: 
        !           211:     if (!qobj || qobject_type(qobj) != QTYPE_QFLOAT) {
        !           212:         error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
        !           213:                   "double");
        !           214:         return;
        !           215:     }
        !           216: 
        !           217:     *obj = qfloat_get_double(qobject_to_qfloat(qobj));
        !           218: }
        !           219: 
        !           220: static void qmp_input_type_enum(Visitor *v, int *obj, const char *strings[],
        !           221:                                 const char *kind, const char *name,
        !           222:                                 Error **errp)
        !           223: {
        !           224:     int64_t value = 0;
        !           225:     char *enum_str;
        !           226: 
        !           227:     assert(strings);
        !           228: 
        !           229:     qmp_input_type_str(v, &enum_str, name, errp);
        !           230:     if (error_is_set(errp)) {
        !           231:         return;
        !           232:     }
        !           233: 
        !           234:     while (strings[value] != NULL) {
        !           235:         if (strcmp(strings[value], enum_str) == 0) {
        !           236:             break;
        !           237:         }
        !           238:         value++;
        !           239:     }
        !           240: 
        !           241:     if (strings[value] == NULL) {
        !           242:         error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");
        !           243:         return;
        !           244:     }
        !           245: 
        !           246:     *obj = value;
        !           247: }
        !           248: 
        !           249: static void qmp_input_start_optional(Visitor *v, bool *present,
        !           250:                                      const char *name, Error **errp)
        !           251: {
        !           252:     QmpInputVisitor *qiv = to_qiv(v);
        !           253:     const QObject *qobj = qmp_input_get_object(qiv, name);
        !           254: 
        !           255:     if (!qobj) {
        !           256:         *present = false;
        !           257:         return;
        !           258:     }
        !           259: 
        !           260:     *present = true;
        !           261: }
        !           262: 
        !           263: static void qmp_input_end_optional(Visitor *v, Error **errp)
        !           264: {
        !           265: }
        !           266: 
        !           267: Visitor *qmp_input_get_visitor(QmpInputVisitor *v)
        !           268: {
        !           269:     return &v->visitor;
        !           270: }
        !           271: 
        !           272: void qmp_input_visitor_cleanup(QmpInputVisitor *v)
        !           273: {
        !           274:     qobject_decref(v->obj);
        !           275:     qemu_free(v);
        !           276: }
        !           277: 
        !           278: QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
        !           279: {
        !           280:     QmpInputVisitor *v;
        !           281: 
        !           282:     v = qemu_mallocz(sizeof(*v));
        !           283: 
        !           284:     v->visitor.start_struct = qmp_input_start_struct;
        !           285:     v->visitor.end_struct = qmp_input_end_struct;
        !           286:     v->visitor.start_list = qmp_input_start_list;
        !           287:     v->visitor.next_list = qmp_input_next_list;
        !           288:     v->visitor.end_list = qmp_input_end_list;
        !           289:     v->visitor.type_enum = qmp_input_type_enum;
        !           290:     v->visitor.type_int = qmp_input_type_int;
        !           291:     v->visitor.type_bool = qmp_input_type_bool;
        !           292:     v->visitor.type_str = qmp_input_type_str;
        !           293:     v->visitor.type_number = qmp_input_type_number;
        !           294:     v->visitor.start_optional = qmp_input_start_optional;
        !           295:     v->visitor.end_optional = qmp_input_end_optional;
        !           296: 
        !           297:     v->obj = obj;
        !           298:     qobject_incref(v->obj);
        !           299: 
        !           300:     return v;
        !           301: }

unix.superglobalmegacorp.com

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