1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 
43 #include <stdlib.h>
44 #include <string.h>
45 #include <conn_settings.h>
46 
47 #include "iapconf.h"
48 
49 #define QSTRING_TO_CONST_CSTR(str) \
50     str.toUtf8().constData()
51 
52 namespace Maemo {
53 
54 class IAPConfPrivate {
55 public:
56     ConnSettings *settings;
57 
58     ConnSettingsValue *variantToValue(const QVariant &variant);
59     QVariant valueToVariant(ConnSettingsValue *value);
60 };
61 
variantToValue(const QVariant & variant)62 ConnSettingsValue *IAPConfPrivate::variantToValue(const QVariant &variant)
63 {
64     // Convert variant to ConnSettingsValue
65     ConnSettingsValue *value = conn_settings_value_new();
66     if (value == 0) {
67         qWarning("IAPConf: Unable to create new ConnSettingsValue");
68         return 0;
69     }
70 
71     switch(variant.type()) {
72 
73     case QVariant::Invalid:
74         value->type = CONN_SETTINGS_VALUE_INVALID;
75         break;
76 
77     case QVariant::String: {
78         char *valueStr = strdup(QSTRING_TO_CONST_CSTR(variant.toString()));
79         value->type = CONN_SETTINGS_VALUE_STRING;
80         value->value.string_val = valueStr;
81         break;
82     }
83 
84     case QVariant::Int:
85         value->type = CONN_SETTINGS_VALUE_INT;
86         value->value.int_val = variant.toInt();
87         break;
88 
89     case QMetaType::Float:
90     case QVariant::Double:
91         value->type = CONN_SETTINGS_VALUE_DOUBLE;
92         value->value.double_val = variant.toDouble();
93         break;
94 
95     case QVariant::Bool:
96         value->type = CONN_SETTINGS_VALUE_BOOL;
97         value->value.bool_val = variant.toBool() ? 1 : 0;
98         break;
99 
100     case QVariant::ByteArray: {
101         QByteArray array = variant.toByteArray();
102         value->type = CONN_SETTINGS_VALUE_BYTE_ARRAY;
103         value->value.byte_array.len = array.size();
104         value->value.byte_array.val = (unsigned char *)malloc(array.size());
105         memcpy(value->value.byte_array.val, array.constData(), array.size());
106         break;
107     }
108 
109     case QVariant::List: {
110         QVariantList list = variant.toList();
111         ConnSettingsValue **list_val = (ConnSettingsValue **)malloc(
112             (list.size() + 1) * sizeof(ConnSettingsValue *));
113 
114         for (int idx = 0; idx < list.size(); idx++) {
115             list_val[idx] = variantToValue(list.at(idx));
116         }
117         list_val[list.size()] = 0;
118 
119         value->type = CONN_SETTINGS_VALUE_LIST;
120         value->value.list_val = list_val;
121         break;
122     }
123 
124     default:
125         qWarning("IAPConf: Can not handle QVariant of type %d",
126                  variant.type());
127         conn_settings_value_destroy(value);
128         return 0;
129     }
130 
131     return value;
132 }
133 
valueToVariant(ConnSettingsValue * value)134 QVariant IAPConfPrivate::valueToVariant(ConnSettingsValue *value)
135 {
136     if (value == 0 || value->type == CONN_SETTINGS_VALUE_INVALID) {
137         return QVariant();
138     }
139 
140     switch(value->type) {
141 
142     case CONN_SETTINGS_VALUE_BOOL:
143         return QVariant(value->value.bool_val ? true : false);
144 
145     case CONN_SETTINGS_VALUE_STRING:
146         return QVariant(QString::fromUtf8(value->value.string_val));
147 
148     case CONN_SETTINGS_VALUE_DOUBLE:
149         return QVariant(value->value.double_val);
150 
151     case CONN_SETTINGS_VALUE_INT:
152         return QVariant(value->value.int_val);
153 
154     case CONN_SETTINGS_VALUE_LIST: {
155         // At least with GConf backend connsettings returns byte array as list
156         // of ints, first check for that case
157         if (value->value.list_val && value->value.list_val[0]) {
158             bool canBeConvertedToByteArray = true;
159             for (int idx = 0; value->value.list_val[idx]; idx++) {
160                 ConnSettingsValue *val = value->value.list_val[idx];
161                 if (val->type != CONN_SETTINGS_VALUE_INT
162                      || val->value.int_val > 255
163                      || val->value.int_val < 0) {
164                     canBeConvertedToByteArray = false;
165                     break;
166                 }
167             }
168 
169             if (canBeConvertedToByteArray) {
170                 QByteArray array;
171                 for (int idx = 0; value->value.list_val[idx]; idx++) {
172                     array.append(value->value.list_val[idx]->value.int_val);
173                 }
174                 return array;
175             }
176 
177 	    // Create normal list
178 	    QVariantList list;
179 	    for (int idx = 0; value->value.list_val[idx]; idx++) {
180 	      list.append(valueToVariant(value->value.list_val[idx]));
181 	    }
182 	    return list;
183         }
184     }
185 
186     case CONN_SETTINGS_VALUE_BYTE_ARRAY:
187         return QByteArray::fromRawData((char *)value->value.byte_array.val,
188                                        value->value.byte_array.len);
189 
190     default:
191         return QVariant();
192     }
193 }
194 
195 // Public class implementation
196 
IAPConf(const QString & iap_id)197 IAPConf::IAPConf(const QString &iap_id)
198     : d_ptr(new IAPConfPrivate)
199 {
200     d_ptr->settings = conn_settings_open(CONN_SETTINGS_CONNECTION,
201                                          QSTRING_TO_CONST_CSTR(iap_id));
202     if (d_ptr->settings == 0) {
203         qWarning("IAPConf: Unable to open ConnSettings for %s",
204                  QSTRING_TO_CONST_CSTR(iap_id));
205     }
206 }
207 
~IAPConf()208 IAPConf::~IAPConf()
209 {
210     conn_settings_close(d_ptr->settings);
211     delete d_ptr;
212 }
213 
214 
value(const QString & key) const215 QVariant IAPConf::value(const QString& key) const
216 {
217     ConnSettingsValue *val = conn_settings_get(d_ptr->settings,
218                                                QSTRING_TO_CONST_CSTR(key));
219 
220     QVariant variant = d_ptr->valueToVariant(val);
221     conn_settings_value_destroy(val);
222     return variant;
223 }
224 
225 
getAll(QList<QString> & all_iaps,bool return_path)226 void IAPConf::getAll(QList<QString> &all_iaps, bool return_path)
227 {
228     Q_UNUSED(return_path); // We don't use return path currently
229 
230     // Go through all available connections and add them to the list
231     char **ids = conn_settings_list_ids(CONN_SETTINGS_CONNECTION);
232     if (ids == 0) {
233         // No ids found - nothing to do
234         return;
235     }
236 
237     for (int idx = 0; ids[idx]; idx++) {
238         all_iaps.append(QString(ids[idx]));
239         free(ids[idx]);
240     }
241     free(ids);
242 }
243 
244 
245 } // namespace Maemo
246