1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtSystems module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
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** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34#include "qserviceinterfacedescriptor_p.h"
35#ifndef QT_NO_DATASTREAM
36#include <qdatastream.h>
37#endif
38
39#include <QDebug>
40#include <QStringList>
41
42QT_BEGIN_NAMESPACE
43
44/*!
45 \class QServiceInterfaceDescriptor
46 \ingroup servicefw
47 \inmodule QtServiceFramework
48 \brief The QServiceInterfaceDescriptor class identifies a service implementation.
49
50 A service can implement multiple interfaces and each interface can have multiple implementations.
51 The QServiceInterfaceDescriptor class enscapsulates this information, as illustrated
52 by the diagram below.
53
54 \image qserviceinterfacedescriptor.png Service-Interface-Implementation
55
56 The major version tag indicates the interface version and the minor version tag identifies the implementation
57 version. Subsequent versions of the same interface must be binary compatible to previous versions
58 of the same interface.
59
60 In the above example service A and B implement the interface \e com.nokia.qt.x.
61 In fact Service A provides two different implementations for the very same interface.
62 This is indicated by the changed minor version number. Although Service B is
63 using the same interface it's implementation actually utilizes the second version of
64 the interface \e com.nokia.qt.x. Binary compatibility guarantees that clients
65 who know version 1 can utilize version 2. If an existing interface has to be changed
66 in a non-compatible way a new interface (name) is required.
67
68 \section1 Namespaces
69
70 A QServiceInterfaceDescriptor (the quadruble of service name,
71 interface name, interface version and implementation version) uniquely
72 identifies a service implementation on a device. Interface names follow
73 the java namespace convention.
74
75 The namespace \e com.nokia.qt.* is reserved for future Qt development.
76
77 \sa QServiceFilter, QServiceManager
78*/
79
80/*!
81 \enum QServiceInterfaceDescriptor::Attribute
82
83 This enum describes the possible attribute types which can be attached
84 to a QServiceInterfaceDescriptor.
85
86 \value Capabilities The capabilities attribute is a QStringList and
87 describes the capabilities that a service client
88 would require to use the service if capability
89 checks are enforced.
90 \value Location This attribute points to either the location
91 where the plug-in providing this service is stored or
92 where the name of the service IPC path is found.
93 If the service is plug-in based the location is the
94 name and/or path of the plugin. If the service is
95 IPC based the location is the name of the socket address.
96 \value ServiceDescription This attribute provides a general description for
97 the service.
98 \value InterfaceDescription This attribute provides a description for the interface
99 implementation.
100 \value ServiceType This attribute specifies the QService::Type that the
101 service is being provided.
102*/
103
104/*!
105 Creates a new QServiceInterfaceDescriptor.
106*/
107QServiceInterfaceDescriptor::QServiceInterfaceDescriptor()
108 : d(0)
109{
110}
111
112/*!
113 Destroys the QServiceInterfaceDescriptor object.
114*/
115QServiceInterfaceDescriptor::~QServiceInterfaceDescriptor()
116{
117 if (d)
118 delete d;
119}
120
121/*!
122 Creates a copy of QServiceInterfaceDescriptor contained in \a other.
123*/
124QServiceInterfaceDescriptor::QServiceInterfaceDescriptor(const QServiceInterfaceDescriptor& other)
125 : d(0)
126{
127 (*this) = other; //use assignment operator
128}
129
130/*!
131 \fn QServiceInterfaceDescriptor& QServiceInterfaceDescriptor::operator=(const QServiceInterfaceDescriptor& other)
132
133 Copies the content of the QServiceInterfaceDescriptor object contained
134 in \a other into this one.
135*/
136QServiceInterfaceDescriptor& QServiceInterfaceDescriptor::operator=(const QServiceInterfaceDescriptor& other)
137{
138 if (&other == this)
139 return *this;
140
141 if ( !other.isValid() ) {
142 if (d)
143 delete d;
144 d = 0;
145 return *this;
146 }
147
148 if (!d)
149 d = new QServiceInterfaceDescriptorPrivate;
150
151 (*d) = *(other.d);
152 return *this;
153}
154
155/*!
156 \fn bool QServiceInterfaceDescriptor::operator==(const QServiceInterfaceDescriptor& other) const
157
158 Compares a QServiceInterfaceDescriptor to \a other. Returns true if they
159 are equal and false otherwise.
160*/
161bool QServiceInterfaceDescriptor::operator==(const QServiceInterfaceDescriptor& other) const
162{
163 if (isValid() ^ other.isValid())
164 return false;
165
166 if (!d)
167 return true;
168
169 if ((*d) == *(other.d))
170 return true;
171 return false;
172}
173
174/*!
175 \fn bool QServiceInterfaceDescriptor::operator!=(const QServiceInterfaceDescriptor& other) const
176
177 Compares a QServiceInterfaceDescriptor to \a other. Returns true
178 if they are not equal and false otherwise.
179*/
180
181/*!
182 \fn bool QServiceInterfaceDescriptor::isValid() const
183
184 Returns true if this descriptor is valid; otherwise returns false.
185*/
186bool QServiceInterfaceDescriptor::isValid() const
187{
188 return d ? true : false;
189}
190
191/*!
192 \fn bool QServiceInterfaceDescriptor::scope() const
193
194 Returns true if this implementation is provided for all users on the system.
195
196 \sa QService::Scope
197*/
198QService::Scope QServiceInterfaceDescriptor::scope() const
199{
200 return d ? d->scope : QService::UserScope;
201}
202
203/*!
204 \fn QString QServiceInterfaceDescriptor::serviceName() const
205
206 Returns the name of service that provides this implementation.
207*/
208QString QServiceInterfaceDescriptor::serviceName() const
209{
210 return d ? d->serviceName : QString();
211}
212
213/*!
214 \fn QString QServiceInterfaceDescriptor::interfaceName() const
215
216 Returns the name of the interface that is implemented.
217*/
218QString QServiceInterfaceDescriptor::interfaceName() const
219{
220 return d ? d->interfaceName : QString();
221}
222
223/*!
224 \fn int QServiceInterfaceDescriptor::majorVersion() const
225
226 Returns the version of the interface.
227
228 Subsequent versions of an interface are binary compatible
229 to previous versions of the same interface. If an interface
230 is broken it must use a new interface name.
231*/
232int QServiceInterfaceDescriptor::majorVersion() const
233{
234 return d ? d->major : -1;
235}
236
237/*!
238 \fn int QServiceInterfaceDescriptor::minorVersion() const
239
240 Returns the version of the implementation.
241*/
242int QServiceInterfaceDescriptor::minorVersion() const
243{
244 return d ? d->minor : -1;
245}
246
247/*!
248 \fn QVariant QServiceInterfaceDescriptor::attribute(QServiceInterfaceDescriptor::Attribute which) const
249
250 Returns the value for the attribute \a which; otherwise returns
251 an invalid QVariant.
252*/
253QVariant QServiceInterfaceDescriptor::attribute(QServiceInterfaceDescriptor::Attribute which) const
254{
255 if (d)
256 return d->attributes.value(akey: which);
257 return QVariant();
258}
259
260/*!
261 \fn QString QServiceInterfaceDescriptor::customAttribute(const QString& which) const
262
263 Returns the value for the custom attribute \a which; otherwise
264 returns a null string.
265*/
266QString QServiceInterfaceDescriptor::customAttribute(const QString& which) const
267{
268 if (d)
269 return d->customAttributes[which];
270 return QString();
271}
272
273/*!
274 Returns a list of custom attributes attached to the service.
275 */
276QStringList QServiceInterfaceDescriptor::customAttributes() const
277{
278 if (d)
279 return d->customAttributes.keys();
280 return QStringList();
281}
282
283#ifndef QT_NO_DEBUG_STREAM
284QDebug operator<<(QDebug dbg, const QServiceInterfaceDescriptor &desc)
285{
286 if (desc.isValid()) {
287 QString serviceInterface = QString(QLatin1String("%1 %2.%3")).arg(a: desc.interfaceName())
288 .arg(a: desc.majorVersion() < 0 ? '?' : desc.majorVersion())
289 .arg(a: desc.minorVersion() < 0 ? '?' : desc.minorVersion());
290 dbg.nospace() << "QServiceInterfaceDescriptor(";
291 dbg.nospace() << "service=" << desc.serviceName() << ", ";
292 dbg.nospace() << "interface=" << serviceInterface;
293 dbg.nospace() << ")";
294 } else {
295 dbg.nospace() << "QServiceInterfaceDescriptor(invalid)";
296 }
297 return dbg.space();
298}
299#endif
300
301#ifndef QT_NO_DATASTREAM
302
303QDataStream &operator<<(QDataStream &out, const QServiceInterfaceDescriptor::Attribute &k)
304{
305 out << qint8(k);
306 return out;
307}
308
309QDataStream &operator>>(QDataStream &in, QServiceInterfaceDescriptor::Attribute &k)
310{
311 quint8 key;
312 in >> key;
313 k = (QServiceInterfaceDescriptor::Attribute)key;
314 return in;
315}
316/*!
317 \fn QDataStream &operator<<(QDataStream &out, const QServiceInterfaceDescriptor &dc)
318 \relates QServiceInterfaceDescriptor
319
320 Writes service interface descriptor \a dc to the stream \a out and returns a reference
321 to the stream.
322*/
323
324QDataStream &operator<<(QDataStream &out, const QServiceInterfaceDescriptor &dc)
325{
326 const quint32 magicNumber = 0x77AFAFA;
327 const quint16 majorVersion = 1;
328 const quint16 minorVersion = 0;
329 const qint8 valid = dc.isValid();
330 out << magicNumber << majorVersion << minorVersion;
331 out << valid;
332 if (valid) {
333 out << dc.d->serviceName;
334 out << dc.d->interfaceName;
335 out << dc.d->major;
336 out << dc.d->minor;
337 out << dc.d->attributes;
338 out << dc.d->customAttributes;
339 out << (qint8)dc.d->scope;
340 }
341 return out;
342}
343
344/*!
345 \fn QDataStream &operator>>(QDataStream &in, QServiceInterfaceDescriptor &dc)
346 \relates QServiceInterfaceDescriptor
347
348 Reads a service interface descriptor into \a dc from the stream \a in and returns a
349 reference to the stream.
350*/
351QDataStream &operator>>(QDataStream &in, QServiceInterfaceDescriptor &dc)
352{
353 const quint32 magicNumber = 0x77AFAFA;
354 quint32 storedMagicNumber;
355 in >> storedMagicNumber;
356 if (storedMagicNumber != magicNumber) {
357 qWarning() << "Datastream doesn't provide searialized QServiceInterfaceDescriptor";
358 return in;
359 }
360
361 const quint16 currentMajorVersion = 1;
362 quint16 majorVersion = 0;
363 quint16 minorVersion = 0;
364
365 in >> majorVersion >> minorVersion;
366 if (majorVersion != currentMajorVersion) {
367 qWarning() << "Unknown serialization format for QServiceInterfaceDescriptor.";
368 return in;
369 }
370 //Allow all minor versions.
371
372 qint8 valid;
373 in >> valid;
374 if (valid) {
375 if (!dc.isValid())
376 dc.d = new QServiceInterfaceDescriptorPrivate;
377 in >> dc.d->serviceName;
378 in >> dc.d->interfaceName;
379 in >> dc.d->major;
380 in >> dc.d->minor;
381 in >> dc.d->attributes;
382 in >> dc.d->customAttributes;
383 in >> valid;
384 dc.d->scope = (QService::Scope) valid;
385 } else { //input stream contains invalid descriptor
386 //use assignment operator
387 dc = QServiceInterfaceDescriptor();
388 }
389
390 return in;
391}
392#endif //QT_NO_DATASTREAM
393
394
395
396QT_END_NAMESPACE
397
398

source code of qtsystems/src/serviceframework/qserviceinterfacedescriptor.cpp