on 39bacfa help sign in
unity8/plugins/Unity/variantutils.cpp
158 lines 5.8 kB history raw
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
4 * Authors:
5 * Pawel Stolowski <pawel.stolowski@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
20#include "variantutils.h"
22/* Returns floating ref */
23GVariant* GVariantFromQVariant(const QVariant &var)
25 GVariant *gv = nullptr;
27 switch (var.type()) {
28 case QVariant::String:
29 gv = g_variant_new_string(var.toString().toUtf8());
30 break;
31 case QVariant::UInt:
32 gv = g_variant_new_uint32(var.toUInt());
33 break;
34 case QVariant::Int:
35 gv = g_variant_new_int32(var.toInt());
36 break;
37 case QVariant::LongLong:
38 gv = g_variant_new_int64(var.toLongLong());
39 break;
40 case QVariant::ULongLong:
41 gv = g_variant_new_uint64(var.toULongLong());
42 break;
43 case QVariant::Double:
44 gv = g_variant_new_double(var.toDouble());
45 break;
46 case QVariant::Bool:
47 gv = g_variant_new_boolean(var.toBool());
48 break;
49 case QVariant::Hash: {
50 const auto hash = var.toHash();
51 GVariant **children = new GVariant*[hash.size()];
52 int cnt = 0;
53 QHash<QString, QVariant>::const_iterator it = hash.constBegin();
54 while (it != hash.constEnd()) {
55 GVariant *key = g_variant_new_string(it.key().toUtf8());
56 children[cnt++] = g_variant_new_dict_entry(key, g_variant_new_variant(GVariantFromQVariant(it.value())));
57 ++it;
58 }
59 gv = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, hash.size());
60 delete [] children;
61 break;
62 }
63 default:
64 break;
65 }
66 return gv;
69// implementation of this conversion taken from libdee-qt private utility function.
70QVariant QVariantFromGVariant(GVariant *value)
72 /* We need to special-case a{sv} here as G_VARIANT_CLASS_ARRAY handles simple arrays;
73 we need to create QVariantHash, not a list */
74 if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARDICT)) {
75 const gsize nChildren = g_variant_n_children(value);
76 QVariantHash hash;
77 for (gsize i = 0; i < nChildren; ++i)
78 {
79 GVariant* dict_entry = g_variant_get_child_value(value, i);
81 gchar* dict_key;
82 GVariant *dict_var;
83 g_variant_get(dict_entry, "{&sv}", &dict_key, &dict_var);
84 hash.insert(QString::fromUtf8(dict_key), QVariantFromGVariant(dict_var));
85 g_variant_unref(dict_var);
86 g_variant_unref(dict_entry);
87 }
88 return hash;
89 }
91 switch (g_variant_classify(value)) {
92 case G_VARIANT_CLASS_BOOLEAN:
93 return QVariant((bool) g_variant_get_boolean(value));
94 case G_VARIANT_CLASS_BYTE:
95 return QVariant((uchar) g_variant_get_byte(value));
96 case G_VARIANT_CLASS_INT16:
97 return QVariant((qint16) g_variant_get_int16(value));
98 case G_VARIANT_CLASS_UINT16:
99 return QVariant((quint16) g_variant_get_uint16(value));
100 case G_VARIANT_CLASS_INT32:
101 return QVariant((qint32) g_variant_get_int32(value));
102 case G_VARIANT_CLASS_UINT32:
103 return QVariant((quint32) g_variant_get_uint32(value));
104 case G_VARIANT_CLASS_INT64:
105 return QVariant((qint64) g_variant_get_int64(value));
106 case G_VARIANT_CLASS_UINT64:
107 return QVariant((quint64) g_variant_get_uint64(value));
108 case G_VARIANT_CLASS_DOUBLE:
109 return QVariant(g_variant_get_double(value));
110 case G_VARIANT_CLASS_STRING:
111 return QVariant(QString::fromUtf8(g_variant_get_string(value, NULL)));
112 case G_VARIANT_CLASS_ARRAY:
113 case G_VARIANT_CLASS_TUPLE:
114 {
115 const gsize nChildren = g_variant_n_children(value);
116 QList<QVariant> array;
117 for (gsize i = 0; i < nChildren; ++i)
118 {
119 GVariant* gvariant = g_variant_get_child_value(value, i);
120 array << QVariantFromGVariant(gvariant);
121 g_variant_unref(gvariant);
122 }
123 return array;
124 }
125 default:
126 /* Fallback on an empty QVariant.
127 FIXME: Missing conversion of following GVariant types:
128 - G_VARIANT_CLASS_HANDLE
129 - G_VARIANT_CLASS_OBJECT_PATH
130 - G_VARIANT_CLASS_SIGNATURE
131 - G_VARIANT_CLASS_VARIANT
132 - G_VARIANT_CLASS_MAYBE
133 - G_VARIANT_CLASS_DICT_ENTRY
134 */
135 return QVariant();
136 }
139unity::glib::HintsMap convertToHintsMap(const QHash<QString, QVariant> &val)
141 unity::glib::HintsMap hintsMap;
142 QHash<QString, QVariant>::const_iterator it = val.constBegin();
143 while (it != val.constEnd()) {
144 hintsMap[it.key().toStdString()] = GVariantFromQVariant(it.value());
145 ++it;
146 }
147 return hintsMap;
150unity::glib::HintsMap convertToHintsMap(const QVariant &var)
152 if (var.type() == QVariant::Hash) {
153 unity::glib::HintsMap hintsMap;
154 const auto hash = var.toHash();
155 return convertToHintsMap(hash);
156 }
157 return unity::glib::HintsMap();