diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h new file mode 100644 index 0000000000..280db5064a --- /dev/null +++ b/include/qapi/qmp/qlit.h @@ -0,0 +1,49 @@ +/* + * Copyright IBM, Corp. 2009 + * Copyright (c) 2013, 2015, 2017 Red Hat Inc. + * + * Authors: + * Anthony Liguori + * Markus Armbruster + * Marc-André Lureau + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ +#ifndef QLIT_H +#define QLIT_H + +#include "qapi-types.h" +#include "qobject.h" + +typedef struct LiteralQDictEntry LiteralQDictEntry; +typedef struct LiteralQObject LiteralQObject; + +struct LiteralQObject { + int type; + union { + int64_t qnum; + const char *qstr; + LiteralQDictEntry *qdict; + LiteralQObject *qlist; + } value; +}; + +struct LiteralQDictEntry { + const char *key; + LiteralQObject value; +}; + +#define QLIT_QNUM(val) \ + (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} +#define QLIT_QSTR(val) \ + (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} +#define QLIT_QDICT(val) \ + (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} +#define QLIT_QLIST(val) \ + (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} + +int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); + +#endif /* QLIT_H */ diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs index fc8885c9a4..002d25873a 100644 --- a/qobject/Makefile.objs +++ b/qobject/Makefile.objs @@ -1,2 +1,2 @@ -util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o +util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o qlit.o util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o diff --git a/qobject/qlit.c b/qobject/qlit.c new file mode 100644 index 0000000000..5917c3584e --- /dev/null +++ b/qobject/qlit.c @@ -0,0 +1,89 @@ +/* + * QLit literal qobject + * + * Copyright IBM, Corp. 2009 + * Copyright (c) 2013, 2015, 2017 Red Hat Inc. + * + * Authors: + * Anthony Liguori + * Markus Armbruster + * Marc-André Lureau + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "qapi/qmp/qlit.h" +#include "qapi/qmp/types.h" + +typedef struct QListCompareHelper { + int index; + LiteralQObject *objs; + int result; +} QListCompareHelper; + +static void compare_helper(QObject *obj, void *opaque) +{ + QListCompareHelper *helper = opaque; + + if (helper->result == 0) { + return; + } + + if (helper->objs[helper->index].type == QTYPE_NONE) { + helper->result = 0; + return; + } + + helper->result = + compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); +} + +int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) +{ + int64_t val; + + if (!rhs || lhs->type != qobject_type(rhs)) { + return 0; + } + + switch (lhs->type) { + case QTYPE_QNUM: + g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); + return lhs->value.qnum == val; + case QTYPE_QSTRING: + return (strcmp(lhs->value.qstr, + qstring_get_str(qobject_to_qstring(rhs))) == 0); + case QTYPE_QDICT: { + int i; + + for (i = 0; lhs->value.qdict[i].key; i++) { + QObject *obj = qdict_get(qobject_to_qdict(rhs), + lhs->value.qdict[i].key); + + if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { + return 0; + } + } + + return 1; + } + case QTYPE_QLIST: { + QListCompareHelper helper; + + helper.index = 0; + helper.objs = lhs->value.qlist; + helper.result = 1; + + qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); + + return helper.result; + } + default: + break; + } + + return 0; +} diff --git a/tests/check-qjson.c b/tests/check-qjson.c index a3a97b0d99..525f79e60b 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -16,6 +16,7 @@ #include "qapi/error.h" #include "qapi/qmp/types.h" #include "qapi/qmp/qjson.h" +#include "qapi/qmp/qlit.h" #include "qemu-common.h" static void escaped_string(void) @@ -1059,101 +1060,6 @@ static void keyword_literal(void) QDECREF(null); } -typedef struct LiteralQDictEntry LiteralQDictEntry; -typedef struct LiteralQObject LiteralQObject; - -struct LiteralQObject -{ - int type; - union { - int64_t qnum; - const char *qstr; - LiteralQDictEntry *qdict; - LiteralQObject *qlist; - } value; -}; - -struct LiteralQDictEntry -{ - const char *key; - LiteralQObject value; -}; - -#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} -#define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} -#define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} -#define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} - -typedef struct QListCompareHelper -{ - int index; - LiteralQObject *objs; - int result; -} QListCompareHelper; - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); - -static void compare_helper(QObject *obj, void *opaque) -{ - QListCompareHelper *helper = opaque; - - if (helper->result == 0) { - return; - } - - if (helper->objs[helper->index].type == QTYPE_NONE) { - helper->result = 0; - return; - } - - helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); -} - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) -{ - int64_t val; - - if (!rhs || lhs->type != qobject_type(rhs)) { - return 0; - } - - switch (lhs->type) { - case QTYPE_QNUM: - g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); - return lhs->value.qnum == val; - case QTYPE_QSTRING: - return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0); - case QTYPE_QDICT: { - int i; - - for (i = 0; lhs->value.qdict[i].key; i++) { - QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key); - - if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { - return 0; - } - } - - return 1; - } - case QTYPE_QLIST: { - QListCompareHelper helper; - - helper.index = 0; - helper.objs = lhs->value.qlist; - helper.result = 1; - - qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); - - return helper.result; - } - default: - break; - } - - return 0; -} - static void simple_dict(void) { int i;