Qt 4.8
qdbusmisc.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 <string.h>
43 
44 #include <QtCore/qcoreapplication.h>
45 #include <QtCore/qvariant.h>
46 #include <QtCore/qmetaobject.h>
47 
48 #include "qdbusutil_p.h"
49 #include "qdbusconnection_p.h"
50 #include "qdbusmetatype_p.h"
51 #include "qdbusabstractadaptor_p.h" // for QCLASSINFO_DBUS_*
52 
53 #ifndef QT_NO_DBUS
54 
56 
57 bool qDBusCheckAsyncTag(const char *tag)
58 {
59  static const char noReplyTag[] = "Q_NOREPLY";
60  if (!tag || !*tag)
61  return false;
62 
63  const char *p = strstr(tag, noReplyTag);
64  if (p != NULL &&
65  (p == tag || *(p-1) == ' ') &&
66  (p[sizeof noReplyTag - 1] == '\0' || p[sizeof noReplyTag - 1] == ' '))
67  return true;
68 
69  return false;
70 }
71 
72 int qDBusNameToTypeId(const char *name)
73 {
74  int id = static_cast<int>( QVariant::nameToType(name) );
75  if (id == QVariant::UserType)
76  id = QMetaType::type(name);
77  return id;
78 }
79 
81 {
82  QString interface;
83 
85  if (idx >= mo->classInfoOffset()) {
86  interface = QLatin1String(mo->classInfo(idx).value());
87  } else {
88  interface = QLatin1String(mo->className());
89  interface.replace(QLatin1String("::"), QLatin1String("."));
90 
91  if (interface.startsWith(QLatin1String("QDBus"))) {
92  interface.prepend(QLatin1String("org.qtproject.QtDBus."));
93  } else if (interface.startsWith(QLatin1Char('Q')) &&
94  interface.length() >= 2 && interface.at(1).isUpper()) {
95  // assume it's Qt
96  interface.prepend(QLatin1String("org.qtproject.Qt."));
97  } else if (!QCoreApplication::instance()||
98  QCoreApplication::instance()->applicationName().isEmpty()) {
99  interface.prepend(QLatin1String("local."));
100  } else {
101  interface.prepend(QLatin1Char('.')).prepend(QCoreApplication::instance()->applicationName());
102  QStringList domainName =
105  if (domainName.isEmpty())
106  interface.prepend(QLatin1String("local."));
107  else
108  for (int i = 0; i < domainName.count(); ++i)
109  interface.prepend(QLatin1Char('.')).prepend(domainName.at(i));
110  }
111  }
112 
113  return interface;
114 }
115 
116 bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name)
117 {
118  const QMetaObject *mo = obj->metaObject();
119  for ( ; mo != &QObject::staticMetaObject; mo = mo->superClass())
120  if (interface_name == qDBusInterfaceFromMetaObject(mo))
121  return true;
122  return false;
123 }
124 
125 // calculates the metatypes for the method
126 // the slot must have the parameters in the following form:
127 // - zero or more value or const-ref parameters of any kind
128 // - zero or one const ref of QDBusMessage
129 // - zero or more non-const ref parameters
130 // No parameter may be a template.
131 // this function returns -1 if the parameters don't match the above form
132 // this function returns the number of *input* parameters, including the QDBusMessage one if any
133 // this function does not check the return type, so metaTypes[0] is always 0 and always present
134 // metaTypes.count() >= retval + 1 in all cases
135 //
136 // sig must be the normalised signature for the method
138 {
140 
141  QList<QByteArray> parameterTypes = mm.parameterTypes();
142  metaTypes.clear();
143 
144  metaTypes.append(0); // return type
145  int inputCount = 0;
146  bool seenMessage = false;
148  QList<QByteArray>::ConstIterator end = parameterTypes.constEnd();
149  for ( ; it != end; ++it) {
150  const QByteArray &type = *it;
151  if (type.endsWith('*')) {
152  //qWarning("Could not parse the method '%s'", mm.signature());
153  // pointer?
154  return -1;
155  }
156 
157  if (type.endsWith('&')) {
158  QByteArray basictype = type;
159  basictype.truncate(type.length() - 1);
160 
161  int id = qDBusNameToTypeId(basictype);
162  if (id == 0) {
163  //qWarning("Could not parse the method '%s'", mm.signature());
164  // invalid type in method parameter list
165  return -1;
166  } else if (QDBusMetaType::typeToSignature(id) == 0)
167  return -1;
168 
169  metaTypes.append( id );
170  seenMessage = true; // it cannot appear anymore anyways
171  continue;
172  }
173 
174  if (seenMessage) { // && !type.endsWith('&')
175  //qWarning("Could not parse the method '%s'", mm.signature());
176  // non-output parameters after message or after output params
177  return -1; // not allowed
178  }
179 
180  int id = qDBusNameToTypeId(type);
181  if (id == 0) {
182  //qWarning("Could not parse the method '%s'", mm.signature());
183  // invalid type in method parameter list
184  return -1;
185  }
186 
187  if (id == QDBusMetaTypeId::message)
188  seenMessage = true;
189  else if (QDBusMetaType::typeToSignature(id) == 0)
190  return -1;
191 
192  metaTypes.append(id);
193  ++inputCount;
194  }
195 
196  return inputCount;
197 }
198 
200 
201 #endif // QT_NO_DBUS
QString qDBusInterfaceFromMetaObject(const QMetaObject *mo)
Definition: qdbusmisc.cpp:80
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
int type
Definition: qmetatype.cpp:239
void truncate(int pos)
Truncates the byte array at index position pos.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name)
Definition: qdbusmisc.cpp:116
#define it(className, varName)
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QString & prepend(QChar c)
Definition: qstring.h:261
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
Definition: qobject.h:128
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
QString organizationDomain
the Internet domain of the organization that wrote this application
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool qDBusCheckAsyncTag(const char *tag)
Definition: qdbusmisc.cpp:57
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
static const char * typeToSignature(int type)
Returns the D-Bus signature equivalent to the supplied meta type id type.
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool isEmpty(const char *str)
static int message
const char * name
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define QCLASSINFO_DBUS_INTERFACE
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
static void init()
void clear()
Removes all items from the list.
Definition: qlist.h:764
static int type(const char *typeName)
Returns a handle to the type called typeName, or 0 if there is no such type.
Definition: qmetatype.cpp:607
const QMetaObject * superClass() const
Returns the meta-object of the superclass, or 0 if there is no such object.
Definition: qobjectdefs.h:494
bool isUpper() const
Returns true if the character is an uppercase letter, i.
Definition: qchar.h:273
int length() const
Same as size().
Definition: qbytearray.h:356
QList< QByteArray > parameterTypes() const
Returns a list of parameter types.
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
int classInfoOffset() const
Returns the class information offset for this class; i.e.
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
static Type nameToType(const char *name)
Converts the string representation of the storage type given in name, to its enum representation...
Definition: qvariant.cpp:2026
static const KeyPair *const end
int indexOfClassInfo(const char *name) const
Finds class information item name and returns its index; otherwise returns -1.
int qDBusParametersForMethod(const QMetaMethod &mm, QList< int > &metaTypes)
Definition: qdbusmisc.cpp:137
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
The QMetaMethod class provides meta-data about a member function.
Definition: qmetaobject.h:56
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
int qDBusNameToTypeId(const char *name)
Definition: qdbusmisc.cpp:72
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272