Qt 4.8
qdbusmetatype.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 "qdbusmetatype.h"
43 
44 #include <string.h>
45 #include "qdbus_symbols_p.h"
46 
47 #include <qbytearray.h>
48 #include <qglobal.h>
49 #include <qreadwritelock.h>
50 #include <qvector.h>
51 
52 #include "qdbusmessage.h"
54 #include "qdbusutil_p.h"
55 #include "qdbusmetatype_p.h"
56 #include "qdbusargument_p.h"
57 
58 #ifndef QT_NO_DBUS
59 
60 #ifndef DBUS_TYPE_UNIX_FD
61 # define DBUS_TYPE_UNIX_FD int('h')
62 # define DBUS_TYPE_UNIX_FD_AS_STRING "h"
63 #endif
64 
73 
75 
77 {
78 public:
80  { }
81 
82  // Suggestion:
83  // change 'signature' to char* and make QDBusCustomTypeInfo a Movable type
87 };
88 
89 template<typename T>
90 inline static void registerHelper(T * = 0)
91 {
92  void (*mf)(QDBusArgument &, const T *) = qDBusMarshallHelper<T>;
93  void (*df)(const QDBusArgument &, T *) = qDBusDemarshallHelper<T>;
95  reinterpret_cast<QDBusMetaType::MarshallFunction>(mf),
96  reinterpret_cast<QDBusMetaType::DemarshallFunction>(df));
97 }
98 
106 
108 {
109  static volatile bool initialized = false;
110 
111  // reentrancy is not a problem since everything else is locked on their own
112  // set the guard variable at the end
113  if (!initialized) {
114  // register our types with QtCore
115  message = qRegisterMetaType<QDBusMessage>("QDBusMessage");
116  argument = qRegisterMetaType<QDBusArgument>("QDBusArgument");
117  variant = qRegisterMetaType<QDBusVariant>("QDBusVariant");
118  objectpath = qRegisterMetaType<QDBusObjectPath>("QDBusObjectPath");
119  signature = qRegisterMetaType<QDBusSignature>("QDBusSignature");
120  error = qRegisterMetaType<QDBusError>("QDBusError");
121  unixfd = qRegisterMetaType<QDBusUnixFileDescriptor>("QDBusUnixFileDescriptor");
122 
123 #ifndef QDBUS_NO_SPECIALTYPES
124  // and register QtCore's with us
125  registerHelper<QDate>();
126  registerHelper<QTime>();
127  registerHelper<QDateTime>();
128  registerHelper<QRect>();
129  registerHelper<QRectF>();
130  registerHelper<QSize>();
131  registerHelper<QSizeF>();
132  registerHelper<QPoint>();
133  registerHelper<QPointF>();
134  registerHelper<QLine>();
135  registerHelper<QLineF>();
136  registerHelper<QVariantList>();
137  registerHelper<QVariantMap>();
138  registerHelper<QVariantHash>();
139 
140  qDBusRegisterMetaType<QList<bool> >();
141  qDBusRegisterMetaType<QList<short> >();
142  qDBusRegisterMetaType<QList<ushort> >();
143  qDBusRegisterMetaType<QList<int> >();
144  qDBusRegisterMetaType<QList<uint> >();
145  qDBusRegisterMetaType<QList<qlonglong> >();
146  qDBusRegisterMetaType<QList<qulonglong> >();
147  qDBusRegisterMetaType<QList<double> >();
148  qDBusRegisterMetaType<QList<QDBusObjectPath> >();
149  qDBusRegisterMetaType<QList<QDBusSignature> >();
150  qDBusRegisterMetaType<QList<QDBusUnixFileDescriptor> >();
151 #endif
152 
153  initialized = true;
154  }
155 }
156 
158 Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
159 
160 
230 void QDBusMetaType::registerMarshallOperators(int id, MarshallFunction mf,
231  DemarshallFunction df)
232 {
233  QByteArray var;
235  if (id < 0 || !mf || !df || !ct)
236  return; // error!
237 
238  QWriteLocker locker(customTypesLock());
239  if (id >= ct->size())
240  ct->resize(id + 1);
241  QDBusCustomTypeInfo &info = (*ct)[id];
242  info.marshall = mf;
243  info.demarshall = df;
244 }
245 
255 bool QDBusMetaType::marshall(QDBusArgument &arg, int id, const void *data)
256 {
258 
259  MarshallFunction mf;
260  {
261  QReadLocker locker(customTypesLock());
263  if (id >= ct->size())
264  return false; // non-existent
265 
266  const QDBusCustomTypeInfo &info = (*ct).at(id);
267  if (!info.marshall) {
268  mf = 0; // make gcc happy
269  return false;
270  } else
271  mf = info.marshall;
272  }
273 
274  mf(arg, data);
275  return true;
276 }
277 
287 bool QDBusMetaType::demarshall(const QDBusArgument &arg, int id, void *data)
288 {
290 
291  DemarshallFunction df;
292  {
293  QReadLocker locker(customTypesLock());
295  if (id >= ct->size())
296  return false; // non-existent
297 
298  const QDBusCustomTypeInfo &info = (*ct).at(id);
299  if (!info.demarshall) {
300  df = 0; // make gcc happy
301  return false;
302  } else
303  df = info.demarshall;
304  }
305 
306  QDBusArgument copy = arg;
307  df(copy, data);
308  return true;
309 }
310 
324 {
325  if (!signature)
326  return QVariant::Invalid;
327 
329  switch (signature[0])
330  {
331  case DBUS_TYPE_BOOLEAN:
332  return QVariant::Bool;
333 
334  case DBUS_TYPE_BYTE:
335  return QMetaType::UChar;
336 
337  case DBUS_TYPE_INT16:
338  return QMetaType::Short;
339 
340  case DBUS_TYPE_UINT16:
341  return QMetaType::UShort;
342 
343  case DBUS_TYPE_INT32:
344  return QVariant::Int;
345 
346  case DBUS_TYPE_UINT32:
347  return QVariant::UInt;
348 
349  case DBUS_TYPE_INT64:
350  return QVariant::LongLong;
351 
352  case DBUS_TYPE_UINT64:
353  return QVariant::ULongLong;
354 
355  case DBUS_TYPE_DOUBLE:
356  return QVariant::Double;
357 
358  case DBUS_TYPE_STRING:
359  return QVariant::String;
360 
361  case DBUS_TYPE_OBJECT_PATH:
363 
364  case DBUS_TYPE_SIGNATURE:
366 
367  case DBUS_TYPE_UNIX_FD:
369 
370  case DBUS_TYPE_VARIANT:
372 
373  case DBUS_TYPE_ARRAY: // special case
374  switch (signature[1]) {
375  case DBUS_TYPE_BYTE:
376  return QVariant::ByteArray;
377 
378  case DBUS_TYPE_STRING:
379  return QVariant::StringList;
380 
381  case DBUS_TYPE_VARIANT:
382  return QVariant::List;
383 
384  case DBUS_TYPE_OBJECT_PATH:
385  return qMetaTypeId<QList<QDBusObjectPath> >();
386 
387  case DBUS_TYPE_SIGNATURE:
388  return qMetaTypeId<QList<QDBusSignature> >();
389 
390  }
391  // fall through
392  default:
393  return QVariant::Invalid;
394  }
395 }
396 
412 {
413  // check if it's a static type
414  switch (type)
415  {
416  case QMetaType::UChar:
417  return DBUS_TYPE_BYTE_AS_STRING;
418 
419  case QVariant::Bool:
420  return DBUS_TYPE_BOOLEAN_AS_STRING;
421 
422  case QMetaType::Short:
423  return DBUS_TYPE_INT16_AS_STRING;
424 
425  case QMetaType::UShort:
426  return DBUS_TYPE_UINT16_AS_STRING;
427 
428  case QVariant::Int:
429  return DBUS_TYPE_INT32_AS_STRING;
430 
431  case QVariant::UInt:
432  return DBUS_TYPE_UINT32_AS_STRING;
433 
434  case QVariant::LongLong:
435  return DBUS_TYPE_INT64_AS_STRING;
436 
437  case QVariant::ULongLong:
438  return DBUS_TYPE_UINT64_AS_STRING;
439 
440  case QVariant::Double:
441  return DBUS_TYPE_DOUBLE_AS_STRING;
442 
443  case QVariant::String:
444  return DBUS_TYPE_STRING_AS_STRING;
445 
447  return DBUS_TYPE_ARRAY_AS_STRING
448  DBUS_TYPE_STRING_AS_STRING; // as
449 
450  case QVariant::ByteArray:
451  return DBUS_TYPE_ARRAY_AS_STRING
452  DBUS_TYPE_BYTE_AS_STRING; // ay
453  }
454 
456  if (type == QDBusMetaTypeId::variant)
457  return DBUS_TYPE_VARIANT_AS_STRING;
458  else if (type == QDBusMetaTypeId::objectpath)
459  return DBUS_TYPE_OBJECT_PATH_AS_STRING;
460  else if (type == QDBusMetaTypeId::signature)
461  return DBUS_TYPE_SIGNATURE_AS_STRING;
462  else if (type == QDBusMetaTypeId::unixfd)
464 
465  // try the database
467  {
468  QReadLocker locker(customTypesLock());
469  if (type >= ct->size())
470  return 0; // type not registered with us
471 
472  const QDBusCustomTypeInfo &info = (*ct).at(type);
473 
474  if (!info.signature.isNull())
475  return info.signature;
476 
477  if (!info.marshall)
478  return 0; // type not registered with us
479  }
480 
481  // call to user code to construct the signature type
483  {
484  // createSignature will never return a null QByteArray
485  // if there was an error, it'll return ""
487 
488  // re-acquire lock
489  QWriteLocker locker(customTypesLock());
490  info = &(*ct)[type];
491  info->signature = signature;
492  }
493  return info->signature;
494 }
495 
497 
498 #endif // QT_NO_DBUS
const QStringList & customTypes
int type
Definition: qmetatype.cpp:239
static int signatureToType(const char *signature)
static mach_timebase_info_data_t info
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void(* DemarshallFunction)(const QDBusArgument &, void *)
Definition: qdbusmetatype.h:60
The QDBusArgument class is used to marshall and demarshall D-Bus arguments.
Definition: qdbusargument.h:69
#define error(msg)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static int variant
#define DBUS_TYPE_UNIX_FD
static int objectpath
QDBusMetaType::DemarshallFunction demarshall
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
static const char * typeToSignature(int type)
Returns the D-Bus signature equivalent to the supplied meta type id type.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool demarshall(const QDBusArgument &, int id, void *data)
Executes the demarshalling of type id (whose data will be placed in data) from the D-Bus marshalling ...
static int message
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
static const char * data(const QByteArray &arr)
static void init()
The QReadLocker class is a convenience class that simplifies locking and unlocking read-write locks f...
bool isNull() const
Returns true if this byte array is null; otherwise returns false.
static int unixfd
The QWriteLocker class is a convenience class that simplifies locking and unlocking read-write locks ...
#define Q_DECLARE_METATYPE(TYPE)
This macro makes the type Type known to QMetaType as long as it provides a public default constructor...
Definition: qmetatype.h:265
static void registerMarshallOperators(int typeId, MarshallFunction, DemarshallFunction)
Registers the marshalling and demarshalling functions for meta type id.
static void registerHelper(T *=0)
Meta-type registration system for the QtDBus module.
Definition: qdbusmetatype.h:56
The QReadWriteLock class provides read-write locking.
#define DBUS_TYPE_UNIX_FD_AS_STRING
if(void) toggleToolbarShown
void(* MarshallFunction)(QDBusArgument &, const void *)
Definition: qdbusmetatype.h:59
static int error
QDBusMetaType::MarshallFunction marshall
static int signature
static QByteArray createSignature(int id)
const char * variant
static bool marshall(QDBusArgument &, int id, const void *data)
Executes the marshalling of type id (whose data is contained in data) to the D-Bus marshalling argume...
static int argument
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137