Qt 4.8
qdbusdemarshaller.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDBus module 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qdbusargument_p.h"
43 #include "qdbusconnection.h"
44 #include <stdlib.h>
45 
47 
48 template <typename T>
49 static inline T qIterGet(DBusMessageIter *it)
50 {
51  // Use a union of expected and largest type q_dbus_message_iter_get_basic
52  // will return to ensure reading the wrong basic type does not result in
53  // stack overwrite
54  union {
55  // The value to be extracted
56  T t;
57  // Largest type that q_dbus_message_iter_get_basic will return
58  // according to dbus_message_iter_get_basic API documentation
59  dbus_uint64_t maxValue;
60  // A pointer to ensure no stack overwrite in case there is a platform
61  // where sizeof(void*) > sizeof(dbus_uint64_t)
62  void* ptr;
63  } value;
64 
65  // Initialize the value in case a narrower type is extracted to it.
66  // Note that the result of extracting a narrower type in place of a wider
67  // one and vice-versa will be platform-dependent.
68  value.t = T();
69 
70  q_dbus_message_iter_get_basic(it, &value);
71  q_dbus_message_iter_next(it);
72  return value.t;
73 }
74 
76 {
77 }
78 
80 {
81  char *sig = q_dbus_message_iter_get_signature(&iterator);
82  QString retval = QString::fromUtf8(sig);
83  q_dbus_free(sig);
84 
85  return retval;
86 }
87 
89 {
90  return qIterGet<uchar>(&iterator);
91 }
92 
94 {
95  return bool(qIterGet<dbus_bool_t>(&iterator));
96 }
97 
99 {
100  return qIterGet<dbus_uint16_t>(&iterator);
101 }
102 
104 {
105  return qIterGet<dbus_int16_t>(&iterator);
106 }
107 
109 {
110  return qIterGet<dbus_int32_t>(&iterator);
111 }
112 
114 {
115  return qIterGet<dbus_uint32_t>(&iterator);
116 }
117 
119 {
120  return qIterGet<qlonglong>(&iterator);
121 }
122 
124 {
125  return qIterGet<qulonglong>(&iterator);
126 }
127 
129 {
130  return qIterGet<double>(&iterator);
131 }
132 
134 {
135  return QString::fromUtf8(qIterGet<char *>(&iterator));
136 }
137 
139 {
141  return toStringUnchecked();
142  else
143  return QString();
144 }
145 
147  {
148  return QDBusObjectPath(QString::fromUtf8(qIterGet<char *>(&iterator)));
149  }
150 
152 {
154  return toObjectPathUnchecked();
155  else
156  return QDBusObjectPath();
157 }
158 
160  {
161  return QDBusSignature(QString::fromUtf8(qIterGet<char *>(&iterator)));
162  }
163 
165 {
167  return toSignatureUnchecked();
168  else
169  return QDBusSignature();
170 }
171 
173 {
175  fd.giveFileDescriptor(qIterGet<dbus_int32_t>(&iterator));
176  return fd;
177 }
178 
180 {
182  sub.message = q_dbus_message_ref(message);
183  q_dbus_message_iter_recurse(&iterator, &sub.iterator);
184  q_dbus_message_iter_next(&iterator);
185 
186  return QDBusVariant( sub.toVariantInternal() );
187 }
188 
190 {
191  switch (q_dbus_message_iter_get_arg_type(&iterator)) {
192  case DBUS_TYPE_BYTE:
193  case DBUS_TYPE_INT16:
194  case DBUS_TYPE_UINT16:
195  case DBUS_TYPE_INT32:
196  case DBUS_TYPE_UINT32:
197  case DBUS_TYPE_INT64:
198  case DBUS_TYPE_UINT64:
199  case DBUS_TYPE_BOOLEAN:
200  case DBUS_TYPE_DOUBLE:
201  case DBUS_TYPE_STRING:
202  case DBUS_TYPE_OBJECT_PATH:
203  case DBUS_TYPE_SIGNATURE:
205 
206  case DBUS_TYPE_VARIANT:
208 
209  case DBUS_TYPE_ARRAY:
210  switch (q_dbus_message_iter_get_element_type(&iterator)) {
211  case DBUS_TYPE_BYTE:
212  case DBUS_TYPE_STRING:
213  // QByteArray and QStringList
215  case DBUS_TYPE_DICT_ENTRY:
216  return QDBusArgument::MapType;
217  default:
219  }
220 
221  case DBUS_TYPE_STRUCT:
223  case DBUS_TYPE_DICT_ENTRY:
225 
226  case DBUS_TYPE_UNIX_FD:
229 
230  case DBUS_TYPE_INVALID:
232 
233 // default:
234 // qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
235 // q_dbus_message_iter_get_arg_type(&iterator),
236 // q_dbus_message_iter_get_arg_type(&iterator));
237  }
239 }
240 
242 {
243  switch (q_dbus_message_iter_get_arg_type(&iterator)) {
244  case DBUS_TYPE_BYTE:
245  return QVariant::fromValue(toByte());
246  case DBUS_TYPE_INT16:
247  return QVariant::fromValue(toShort());
248  case DBUS_TYPE_UINT16:
249  return QVariant::fromValue(toUShort());
250  case DBUS_TYPE_INT32:
251  return toInt();
252  case DBUS_TYPE_UINT32:
253  return toUInt();
254  case DBUS_TYPE_DOUBLE:
255  return toDouble();
256  case DBUS_TYPE_BOOLEAN:
257  return toBool();
258  case DBUS_TYPE_INT64:
259  return toLongLong();
260  case DBUS_TYPE_UINT64:
261  return toULongLong();
262  case DBUS_TYPE_STRING:
263  return toStringUnchecked();
264  case DBUS_TYPE_OBJECT_PATH:
266  case DBUS_TYPE_SIGNATURE:
268  case DBUS_TYPE_VARIANT:
269  return QVariant::fromValue(toVariant());
270 
271  case DBUS_TYPE_ARRAY:
272  switch (q_dbus_message_iter_get_element_type(&iterator)) {
273  case DBUS_TYPE_BYTE:
274  // QByteArray
275  return toByteArrayUnchecked();
276  case DBUS_TYPE_STRING:
277  return toStringListUnchecked();
278  case DBUS_TYPE_DICT_ENTRY:
279  return QVariant::fromValue(duplicate());
280 
281  default:
282  return QVariant::fromValue(duplicate());
283  }
284 
285  case DBUS_TYPE_STRUCT:
286  return QVariant::fromValue(duplicate());
287 
288  case DBUS_TYPE_UNIX_FD:
291  // fall through
292 
293  default:
294 // qWarning("QDBusDemarshaller: Found unknown D-Bus type %d '%c'",
295 // q_dbus_message_iter_get_arg_type(&iterator),
296 // q_dbus_message_iter_get_arg_type(&iterator));
297  char *ptr = 0;
298  ptr += q_dbus_message_iter_get_arg_type(&iterator);
299  q_dbus_message_iter_next(&iterator);
300 
301  // I hope you never dereference this pointer!
302  return QVariant::fromValue<void *>(ptr);
303  break;
304  };
305 }
306 
308 {
309  const int type = q_dbus_message_iter_get_arg_type(&iterator);
310  switch (type) {
311  case DBUS_TYPE_STRING: //FALLTHROUGH
312  case DBUS_TYPE_OBJECT_PATH: //FALLTHROUGH
313  case DBUS_TYPE_SIGNATURE:
314  return true;
315  default:
316  return false;
317  }
318 }
319 
321 {
322  QStringList list;
323 
325  q_dbus_message_iter_recurse(&iterator, &sub.iterator);
326  q_dbus_message_iter_next(&iterator);
327  while (!sub.atEnd())
328  list.append(sub.toStringUnchecked());
329 
330  return list;
331 }
332 
334 {
335  if (q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_ARRAY
336  && q_dbus_message_iter_get_element_type(&iterator) == DBUS_TYPE_STRING)
337  return toStringListUnchecked();
338  else
339  return QStringList();
340 }
341 
343 {
344  DBusMessageIter sub;
345  q_dbus_message_iter_recurse(&iterator, &sub);
346  q_dbus_message_iter_next(&iterator);
347  int len;
348  char* data;
349  q_dbus_message_iter_get_fixed_array(&sub,&data,&len);
350  return QByteArray(data,len);
351 }
352 
354 {
355  if (q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_ARRAY
356  && q_dbus_message_iter_get_element_type(&iterator) == DBUS_TYPE_BYTE) {
357  return toByteArrayUnchecked();
358  }
359  return QByteArray();
360 }
361 
363 {
364  // dbus_message_iter_has_next is broken if the list has one single element
365  return q_dbus_message_iter_get_arg_type(&iterator) == DBUS_TYPE_INVALID;
366 }
367 
369 {
370  return beginCommon();
371 }
372 
374 {
375  return beginCommon();
376 }
377 
379 {
380  return beginCommon();
381 }
382 
384 {
385  return beginCommon();
386 }
387 
389 {
391  d->parent = this;
392  d->message = q_dbus_message_ref(message);
393 
394  // recurse
395  q_dbus_message_iter_recurse(&iterator, &d->iterator);
396  q_dbus_message_iter_next(&iterator);
397  return d;
398 }
399 
401 {
402  return endCommon();
403 }
404 
406 {
407  return endCommon();
408 }
409 
411 {
412  return endCommon();
413 }
414 
416 {
417  return endCommon();
418 }
419 
421 {
422  QDBusDemarshaller *retval = parent;
423  delete this;
424  return retval;
425 }
426 
428 {
430  d->iterator = iterator;
431  d->message = q_dbus_message_ref(message);
432 
433  q_dbus_message_iter_next(&iterator);
435 }
436 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
QDBusSignature toSignatureUnchecked()
DBusMessage * message
static QDBusArgumentPrivate * d(QDBusArgument &q)
QDBusArgument::ElementType currentType()
int type
Definition: qmetatype.cpp:239
QStringList toStringListUnchecked()
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QVariant qVariantFromValue(const T &)
Definition: qvariant.h:451
QDBusDemarshaller * endStructure()
#define it(className, varName)
The QDBusArgument class is used to marshall and demarshall D-Bus arguments.
Definition: qdbusargument.h:69
static QDBusArgument create(QDBusArgumentPrivate *d)
QDBusDemarshaller * endMapEntry()
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
The QDBusSignature class enables the programmer to identify the SIGNATURE type provided by the D-Bus ...
QDBusDemarshaller * parent
#define DBUS_TYPE_UNIX_FD
QDBusDemarshaller * beginMap()
The QString class provides a Unicode character string.
Definition: qstring.h:83
QDBusObjectPath toObjectPathUnchecked()
QDBusDemarshaller * endArray()
The QDBusUnixFileDescriptor class holds one Unix file descriptor.
unsigned char uchar
Definition: qglobal.h:994
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QDBusArgument duplicate()
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QDBusDemarshaller * endCommon()
QStringList toStringList()
QByteArray toByteArrayUnchecked()
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
const T * ptr(const T &t)
QDBusDemarshaller * beginStructure()
static QVariant fromValue(const T &value)
Returns a QVariant containing a copy of value.
Definition: qvariant.h:336
QDBusSignature toSignature()
ElementType
This enum describes the type of element held by the argument.
Definition: qdbusargument.h:72
QDBusVariant toVariant()
QDBusDemarshaller * endMap()
unsigned short ushort
Definition: qglobal.h:995
The QDBusObjectPath class enables the programmer to identify the OBJECT_PATH type provided by the D-B...
DBusMessageIter iterator
QDBusUnixFileDescriptor toUnixFileDescriptor()
void giveFileDescriptor(int fileDescriptor)
Sets the Unix file descriptor to fileDescriptor without copying.
static T qIterGet(DBusMessageIter *it)
QDBusObjectPath toObjectPath()
quint64 qulonglong
Definition: qglobal.h:952
QDBusDemarshaller(int flags)
QDBusDemarshaller * beginArray()
qint64 qlonglong
Definition: qglobal.h:951
The QDBusVariant class enables the programmer to identify the variant type provided by the D-Bus type...
QDBusDemarshaller * beginMapEntry()
QDBusDemarshaller * beginCommon()