1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://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 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qdbusintrospection_p.h"
41 #include "qdbusxmlparser_p.h"
42 
43 #ifndef QT_NO_DBUS
44 
45 QT_BEGIN_NAMESPACE
46 
47 /*!
48     \class QDBusIntrospection
49     \inmodule QtDBus
50     \brief Information about introspected objects and interfaces on D-Bus.
51     \internal
52 
53     This class provides structures and methods for parsing the XML introspection data for D-Bus.
54     Normally, you don't have to use the methods provided here: QDBusInterface and QDBusObject will
55     do that for you.
56 
57     But they may prove useful if the XML data was obtained through other means (like parsing a file).
58 */
59 
60 /*!
61     \class QDBusIntrospection::Argument
62     \inmodule QtDBus
63     \brief One argument to a D-Bus method or signal.
64 
65     This struct represents one argument passed to a method or received from a method or signal in
66     D-Bus. The struct does not contain information on the direction (input or output).
67 */
68 
69 /*!
70     \variable QDBusIntrospection::Argument::type
71     The argument type.
72 */
73 
74 /*!
75     \variable QDBusIntrospection::Argument::name
76     The argument name. The argument name is optional, so this may be a null QString.
77 */
78 
79 /*!
80     \fn QDBusIntrospection::Argument::operator==(const Argument &other) const
81     Compares this object against \a other and return true if they are the same.
82 */
83 
84 /*!
85     \class QDBusIntrospection::Method
86     \inmodule QtDBus
87     \brief Information about one method.
88 
89     This struct represents one method discovered through introspection. A method is composed of
90     its \a name, its input arguments, its output arguments, and, optionally, annotations. There are no
91     "in-out" arguments.
92 */
93 
94 /*!
95     \variable QDBusIntrospection::Method::name
96     The method's name.
97 */
98 
99 /*!
100     \variable QDBusIntrospection::Method::inputArgs
101     A list of the method's input arguments.
102 */
103 
104 /*!
105     \variable QDBusIntrospection::Method::outputArgs
106     A list of the method's output arguments (i.e., return values).
107 */
108 
109 /*!
110     \variable QDBusIntrospection::Method::annotations
111     The annotations associated with the method. Each annotation is a pair of strings, where the key
112     is of the same format as a D-Bus interface name. The value is arbitrary.
113 */
114 
115 /*!
116     \fn QDBusIntrospection::Method::operator==(const Method &other) const
117     Compares this object against \a other and return true if they are the same.
118 */
119 
120 /*!
121     \class QDBusIntrospection::Signal
122     \inmodule QtDBus
123     \brief Information about one signal.
124 
125     This struct represents one signal discovered through introspection. A signal is composed of
126     its \a name, its output arguments, and, optionally, annotations.
127 */
128 
129 /*!
130     \variable QDBusIntrospection::Signal::name
131     The signal's name.
132 */
133 
134 /*!
135     \variable QDBusIntrospection::Signal::outputArgs
136     A list of the signal's arguments.
137 */
138 
139 /*!
140     \variable QDBusIntrospection::Signal::annotations
141     The annotations associated with the signal. Each annotation is a pair of strings, where the key
142     is of the same format as a D-Bus interface name. The value is arbitrary.
143 */
144 
145 /*!
146     \fn QDBusIntrospection::Signal::operator==(const Signal& other) const
147     Compares this object against \a other and return true if they are the same.
148 */
149 
150 /*!
151     \class QDBusIntrospection::Property
152     \inmodule QtDBus
153     \brief Information about one property.
154 
155     This struct represents one property discovered through introspection. A property is composed of
156     its \a name, its \a type, its \a access rights, and, optionally, annotations.
157 */
158 
159 /*!
160     \variable QDBusIntrospection::Property::name
161     The property's name.
162 */
163 
164 /*!
165     \variable QDBusIntrospection::Property::type
166     The property's type.
167 */
168 
169 /*!
170     \enum QDBusIntrospection::Property::Access
171     The possible access rights for a property:
172     \value Read
173     \value Write
174     \value ReadWrite
175 */
176 
177 /*!
178     \variable QDBusIntrospection::Property::access
179     The property's access rights.
180 */
181 
182 /*!
183     \variable QDBusIntrospection::Property::annotations
184     The annotations associated with the property. Each annotation is a pair of strings, where the key
185     is of the same format as a D-Bus interface name. The value is arbitrary.
186 */
187 
188 /*!
189     \fn QDBusIntrospection::Property::operator==(const Property &other) const
190     Compares this object against \a other and return true if they are the same.
191 */
192 
193 /*!
194     \class QDBusIntrospection::Interface
195     \inmodule QtDBus
196     \brief Information about one interface on the bus.
197 
198     Each interface on D-Bus has a unique \a name, identifying where that interface was defined.
199     Interfaces may have annotations, methods, signals and properties, but none are mandatory.
200 */
201 
202 /*!
203     \variable QDBusIntrospection::Interface::name
204     The interface's name.
205 */
206 
207 /*!
208     \variable QDBusIntrospection::Interface::introspection
209     The XML document fragment describing this interface.
210 
211     If parsed again through parseInterface, the object returned should have the same contents as
212     this object.
213 */
214 
215 /*!
216     \variable QDBusIntrospection::Interface::annotations
217     The annotations associated with the interface. Each annotation is a pair of strings, where the key
218     is of the same format as a D-Bus interface name. The value is arbitrary.
219 */
220 
221 /*!
222     \variable QDBusIntrospection::Interface::methods
223     The methods available in this interface. Note that method names are not unique (i.e., methods
224     can be overloaded with multiple arguments types).
225 */
226 
227 /*!
228     \variable QDBusIntrospection::Interface::signals_
229     The signals available in this interface. Note that signal names are not unique (i.e., signals
230     can be overloaded with multiple argument types).
231 
232     This member is called "signals_" because "signals" is a reserved keyword in Qt.
233 */
234 
235 /*!
236     \variable QDBusIntrospection::Interface::properties
237     The properties available in this interface. Property names are unique.
238 */
239 
240 /*!
241     \fn QDBusIntrospection::Interface::operator==(const Interface &other) const
242     Compares this object against \a other and return true if they are the same.
243 
244     Note that two interfaces are considered to be the same if they have the same name. The internal
245     structures in the objects are not compared.
246 */
247 
248 /*!
249     \class QDBusIntrospection::Object
250     \inmodule QtDBus
251     \brief Information about one object on the bus.
252 
253     An object on the D-Bus bus is represented by its service and path on the service but, unlike
254     interfaces, objects are mutable. That is, their contents can change with time. Therefore,
255     while the (service, path) pair uniquely identifies an object, the information contained in
256     this struct may no longer represent the object.
257 
258     An object can contain interfaces and child (sub) objects.
259 */
260 
261 /*!
262     \variable QDBusIntrospection::Object::service
263     The object's service name.
264 
265     \sa parseObject()
266 */
267 
268 /*!
269     \variable QDBusIntrospection::Object::path
270     The object's path on the service. This is an absolute path.
271 
272     \sa parseObject()
273 */
274 
275 /*!
276     \variable QDBusIntrospection::Object::interfaces
277     The list of interface names in this object.
278 */
279 
280 /*!
281     \variable QDBusIntrospection::Object::childObjects
282     The list of child object names in this object. Note that this is a relative name, not an
283     absolute path. To obtain the absolute path, concatenate with \l
284     {QDBusIntrospection::Object::path}{path}.
285 */
286 
287 /*!
288     \typedef QDBusIntrospection::Annotations
289     Contains a QMap of an annotation pair. The annotation's name is stored in the QMap key and
290     must be unique. The annotation's value is stored in the QMap's value and is arbitrary.
291 */
292 
293 /*!
294     \typedef QDBusIntrospection::Arguments
295     Contains a list of arguments to either a Method or a Signal. The arguments' order is important.
296 */
297 
298 /*!
299     \typedef QDBusIntrospection::Methods
300     Contains a QMap of methods and their names. The method's name is stored in the map's key and
301     is not necessarily unique. The order in which multiple methods with the same name are stored
302     in this map is undefined.
303 */
304 
305 /*!
306     \typedef QDBusIntrospection::Signals
307     Contains a QMap of signals and their names. The signal's name is stored in the map's key and
308     is not necessarily unique. The order in which multiple signals with the same name are stored
309     in this map is undefined.
310 */
311 
312 /*!
313     \typedef QDBusIntrospection::Properties
314     Contains a QMap of properties and their names. Each property must have a unique name.
315 */
316 
317 /*!
318     \typedef QDBusIntrospection::Interfaces
319     Contains a QMap of interfaces and their names. Each interface has a unique name.
320 */
321 
322 /*!
323     \typedef QDBusIntrospection::Objects
324     Contains a QMap of objects and their paths relative to their immediate parent.
325 */
326 
327 /*!
328     Parses the XML document fragment (given by \a xml) containing one interface.
329 
330     The first element tag in this XML data must be either \<node\> or \<interface\>. If it is
331     \<node\>, then the \<interface\> tag must be a child tag of the \<node\> one.
332 
333     If there are multiple interfaces in this XML data, it is undefined which one will be
334     returned.
335 */
336 QDBusIntrospection::Interface
parseInterface(const QString & xml)337 QDBusIntrospection::parseInterface(const QString &xml)
338 {
339     // be lazy
340     Interfaces ifs = parseInterfaces(xml);
341     if (ifs.isEmpty())
342         return Interface();
343 
344     // return the first in map order (probably alphabetical order)
345     return *ifs.constBegin().value();
346 }
347 
348 /*!
349     Parses the XML document fragment (given by \a xml) containing several interfaces.
350 
351     If the first element tag in this document fragment is \<node\>, the interfaces parsed will
352     be those found as child elements of the \<node\> tag.
353 */
354 QDBusIntrospection::Interfaces
parseInterfaces(const QString & xml)355 QDBusIntrospection::parseInterfaces(const QString &xml)
356 {
357     QString null;
358     QDBusXmlParser parser(null, null, xml);
359     return parser.interfaces();
360 }
361 
362 /*!
363     Parses the XML document fragment (given by \a xml) containing one object, found at the service
364     \a service and path \a path.
365 
366     The first element tag in this document must be \<node\>. If that tag does not contain
367     a name attribute, the \a path argument will be used to determine the path of this
368     object node.
369 
370     This function does not parse the interfaces contained in the node, nor sub-object's contents.
371     It will only list their names.
372 */
373 QDBusIntrospection::Object
parseObject(const QString & xml,const QString & service,const QString & path)374 QDBusIntrospection::parseObject(const QString &xml, const QString &service, const QString &path)
375 {
376     QDBusXmlParser parser(service, path, xml);
377     QSharedDataPointer<QDBusIntrospection::Object> retval = parser.object();
378     if (!retval)
379         return QDBusIntrospection::Object();
380     return *retval;
381 }
382 
383 QT_END_NAMESPACE
384 
385 #endif // QT_NO_DBUS
386