Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 1 | /* |
| 2 | * QLit literal qobject |
| 3 | * |
| 4 | * Copyright IBM, Corp. 2009 |
| 5 | * Copyright (c) 2013, 2015, 2017 Red Hat Inc. |
| 6 | * |
| 7 | * Authors: |
| 8 | * Anthony Liguori <aliguori@us.ibm.com> |
| 9 | * Markus Armbruster <armbru@redhat.com> |
| 10 | * Marc-André Lureau <marcandre.lureau@redhat.com> |
| 11 | * |
| 12 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. |
| 13 | * See the COPYING.LIB file in the top-level directory. |
| 14 | */ |
| 15 | |
| 16 | #include "qemu/osdep.h" |
| 17 | |
| 18 | #include "qapi/qmp/qlit.h" |
Markus Armbruster | 6b67395 | 2018-02-01 12:18:35 +0100 | [diff] [blame] | 19 | #include "qapi/qmp/qbool.h" |
Markus Armbruster | 47e6b29 | 2018-02-01 12:18:38 +0100 | [diff] [blame] | 20 | #include "qapi/qmp/qlist.h" |
Markus Armbruster | 15280c3 | 2018-02-01 12:18:36 +0100 | [diff] [blame] | 21 | #include "qapi/qmp/qnum.h" |
Markus Armbruster | 6b67395 | 2018-02-01 12:18:35 +0100 | [diff] [blame] | 22 | #include "qapi/qmp/qdict.h" |
| 23 | #include "qapi/qmp/qstring.h" |
Marc-André Lureau | 3cf42b8 | 2018-03-05 18:29:50 +0100 | [diff] [blame] | 24 | #include "qapi/qmp/qnull.h" |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 25 | |
Marc-André Lureau | 6da8a7a | 2017-08-25 12:59:10 +0200 | [diff] [blame] | 26 | static bool qlit_equal_qdict(const QLitObject *lhs, const QDict *qdict) |
| 27 | { |
| 28 | int i; |
| 29 | |
| 30 | for (i = 0; lhs->value.qdict[i].key; i++) { |
| 31 | QObject *obj = qdict_get(qdict, lhs->value.qdict[i].key); |
| 32 | |
| 33 | if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) { |
| 34 | return false; |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | /* Note: the literal qdict must not contain duplicates, this is |
| 39 | * considered a programming error and it isn't checked here. */ |
| 40 | if (qdict_size(qdict) != i) { |
| 41 | return false; |
| 42 | } |
| 43 | |
| 44 | return true; |
| 45 | } |
| 46 | |
Marc-André Lureau | cbb6540 | 2017-08-25 12:59:11 +0200 | [diff] [blame] | 47 | static bool qlit_equal_qlist(const QLitObject *lhs, const QList *qlist) |
| 48 | { |
| 49 | QListEntry *e; |
| 50 | int i = 0; |
| 51 | |
| 52 | QLIST_FOREACH_ENTRY(qlist, e) { |
| 53 | QObject *obj = qlist_entry_obj(e); |
| 54 | |
| 55 | if (!qlit_equal_qobject(&lhs->value.qlist[i], obj)) { |
| 56 | return false; |
| 57 | } |
| 58 | i++; |
| 59 | } |
| 60 | |
| 61 | return !e && lhs->value.qlist[i].type == QTYPE_NONE; |
| 62 | } |
| 63 | |
Marc-André Lureau | e2346a1 | 2017-08-25 12:59:06 +0200 | [diff] [blame] | 64 | bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs) |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 65 | { |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 66 | if (!rhs || lhs->type != qobject_type(rhs)) { |
Marc-André Lureau | d9eba57 | 2017-08-25 12:59:05 +0200 | [diff] [blame] | 67 | return false; |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | switch (lhs->type) { |
Marc-André Lureau | 6c6084c | 2017-08-25 12:59:07 +0200 | [diff] [blame] | 71 | case QTYPE_QBOOL: |
Max Reitz | 7dc847e | 2018-02-24 16:40:29 +0100 | [diff] [blame] | 72 | return lhs->value.qbool == qbool_get_bool(qobject_to(QBool, rhs)); |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 73 | case QTYPE_QNUM: |
Max Reitz | 7dc847e | 2018-02-24 16:40:29 +0100 | [diff] [blame] | 74 | return lhs->value.qnum == qnum_get_int(qobject_to(QNum, rhs)); |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 75 | case QTYPE_QSTRING: |
| 76 | return (strcmp(lhs->value.qstr, |
Max Reitz | 7dc847e | 2018-02-24 16:40:29 +0100 | [diff] [blame] | 77 | qstring_get_str(qobject_to(QString, rhs))) == 0); |
Marc-André Lureau | 6da8a7a | 2017-08-25 12:59:10 +0200 | [diff] [blame] | 78 | case QTYPE_QDICT: |
Max Reitz | 7dc847e | 2018-02-24 16:40:29 +0100 | [diff] [blame] | 79 | return qlit_equal_qdict(lhs, qobject_to(QDict, rhs)); |
Marc-André Lureau | cbb6540 | 2017-08-25 12:59:11 +0200 | [diff] [blame] | 80 | case QTYPE_QLIST: |
Max Reitz | 7dc847e | 2018-02-24 16:40:29 +0100 | [diff] [blame] | 81 | return qlit_equal_qlist(lhs, qobject_to(QList, rhs)); |
Marc-André Lureau | 6c6084c | 2017-08-25 12:59:07 +0200 | [diff] [blame] | 82 | case QTYPE_QNULL: |
| 83 | return true; |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 84 | default: |
| 85 | break; |
| 86 | } |
| 87 | |
Marc-André Lureau | d9eba57 | 2017-08-25 12:59:05 +0200 | [diff] [blame] | 88 | return false; |
Marc-André Lureau | 28035bc | 2017-08-25 12:59:01 +0200 | [diff] [blame] | 89 | } |
Marc-André Lureau | 3cf42b8 | 2018-03-05 18:29:50 +0100 | [diff] [blame] | 90 | |
| 91 | QObject *qobject_from_qlit(const QLitObject *qlit) |
| 92 | { |
| 93 | switch (qlit->type) { |
| 94 | case QTYPE_QNULL: |
| 95 | return QOBJECT(qnull()); |
| 96 | case QTYPE_QNUM: |
| 97 | return QOBJECT(qnum_from_int(qlit->value.qnum)); |
| 98 | case QTYPE_QSTRING: |
| 99 | return QOBJECT(qstring_from_str(qlit->value.qstr)); |
| 100 | case QTYPE_QDICT: { |
| 101 | QDict *qdict = qdict_new(); |
| 102 | QLitDictEntry *e; |
| 103 | |
| 104 | for (e = qlit->value.qdict; e->key; e++) { |
| 105 | qdict_put_obj(qdict, e->key, qobject_from_qlit(&e->value)); |
| 106 | } |
| 107 | return QOBJECT(qdict); |
| 108 | } |
| 109 | case QTYPE_QLIST: { |
| 110 | QList *qlist = qlist_new(); |
| 111 | QLitObject *e; |
| 112 | |
| 113 | for (e = qlit->value.qlist; e->type != QTYPE_NONE; e++) { |
| 114 | qlist_append_obj(qlist, qobject_from_qlit(e)); |
| 115 | } |
| 116 | return QOBJECT(qlist); |
| 117 | } |
| 118 | case QTYPE_QBOOL: |
| 119 | return QOBJECT(qbool_from_bool(qlit->value.qbool)); |
| 120 | default: |
| 121 | assert(0); |
| 122 | } |
| 123 | |
| 124 | return NULL; |
| 125 | } |