|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qvaluespace.h" |
|
43 #include "qvaluespace_p.h" |
|
44 #include "qvaluespacemanager_p.h" |
|
45 #include "qmallocpool_p.h" |
|
46 #include "qvaluespacepublisher.h" |
|
47 |
|
48 #include <QObject> |
|
49 #include <QMap> |
|
50 #include <QPair> |
|
51 #include <QCoreApplication> |
|
52 #include <QSet> |
|
53 #include <QString> |
|
54 #include <QVarLengthArray> |
|
55 |
|
56 #include <QtCore/qdebug.h> |
|
57 |
|
58 QTM_BEGIN_NAMESPACE |
|
59 |
|
60 /*! |
|
61 \class QAbstractValueSpaceLayer |
|
62 \brief The QAbstractValueSpaceLayer class provides support for adding new logical data layers |
|
63 to the Qt Value Space. |
|
64 \ingroup publishsubscribe |
|
65 |
|
66 To create a new layer in the Value Space subclass this class and reimplement all of the virtual |
|
67 functions. The new layer is installed by either calling QValueSpace::installLayer() or by |
|
68 adding the QVALUESPACE_AUTO_INSTALL_LAYER() macro in your implementation file. |
|
69 */ |
|
70 |
|
71 /*! |
|
72 \macro QVALUESPACE_AUTO_INSTALL_LAYER(className) |
|
73 |
|
74 \relates QAbstractValueSpaceLayer |
|
75 |
|
76 This macro installs new Value Space layer. \a className is the name of the class implementing |
|
77 the new layer. |
|
78 |
|
79 The method \c {className *className::instance()} must exist and return a pointer to an instance |
|
80 of the layer to install. This method will only be invoked \i {after} QApplication has been |
|
81 constructed, making it safe to use any Qt class in your layer's constructor. |
|
82 |
|
83 This macro can only be used once for any given class and it should be used where the |
|
84 implementation is written rather than in a header file. |
|
85 */ |
|
86 |
|
87 /*! |
|
88 \typedef QAbstractValueSpaceLayer::Handle |
|
89 |
|
90 The Handle type is an opaque, pointer sized contextual handle used to represent paths within |
|
91 Value Space layers. Handles are only ever created by QAbstractValueSpaceLayer::item() and are |
|
92 always released by calls to QAbstractValueSpaceLayer::removeHandle(). The special value, |
|
93 \c {InvalidHandle} is reserved to represent an invalid handle. |
|
94 */ |
|
95 |
|
96 /*! |
|
97 \enum QAbstractValueSpaceLayer::Type |
|
98 |
|
99 Value Space layers are initialized in either a "Server" or a "Client" context. There is only |
|
100 a single server in the Value Space architecture, and its layers are always initialized before |
|
101 any clients. This distinction allows layers to implement Client/Server architecture |
|
102 \i {if required}. If not, layers are free to treat Server and Client contexts identically. |
|
103 |
|
104 \value Server The layer is being initialized in the "server" context. |
|
105 \value Client The layer is being initialized in the "client" context. |
|
106 */ |
|
107 |
|
108 /*! |
|
109 \enum QAbstractValueSpaceLayer::Properties |
|
110 |
|
111 To allow for efficient layer implementations, expensive handle operations, currently only |
|
112 monitoring for changes, are enabled and disabled as needed on a per-handle basis. The |
|
113 Properties enumeration is a bitmask representing the different properties that can exist on a |
|
114 handle. |
|
115 |
|
116 \value Publish Enable change notification for the handle. When set, the layer should emit |
|
117 QAbstractValueSpaceLayer::handleChanged() signals when appropriate for the |
|
118 handle. |
|
119 */ |
|
120 |
|
121 /*! |
|
122 \fn QString QAbstractValueSpaceLayer::name() |
|
123 |
|
124 Returns the name of the Value Space layer. This name is only used for diagnostics purposes. |
|
125 */ |
|
126 |
|
127 /*! |
|
128 \fn bool QAbstractValueSpaceLayer::startup(Type type) |
|
129 |
|
130 Called by the Value Space system to initialize each layer. The \a type parameter will be set |
|
131 accordingly, and layer implementors can use this to implement a client/server architecture if |
|
132 desired. |
|
133 |
|
134 Returns true upon success; otherwise returns false. |
|
135 */ |
|
136 |
|
137 /*! |
|
138 \fn QUuid QAbstractValueSpaceLayer::id() |
|
139 |
|
140 Returns a globally unique identifier for the layer. This id is used to break ordering ties. |
|
141 */ |
|
142 |
|
143 /*! |
|
144 \fn unsigned int QAbstractValueSpaceLayer::order() |
|
145 |
|
146 Return the position in the Value Space layer stack that this layer should reside. Higher |
|
147 numbers mean the layer has a higher precedence and its values will "shadow" those below it. |
|
148 If two layers specify the same ordering, the id() value is used to break the tie. |
|
149 */ |
|
150 |
|
151 /*! |
|
152 \fn Handle QAbstractValueSpaceLayer::item(Handle parent, const QString &subPath) |
|
153 |
|
154 Returns a new opaque handle for the requested \a subPath of \a parent. If \a parent is an |
|
155 InvalidHandle, \a subPath is interpreted as an absolute path. |
|
156 |
|
157 The caller should call removeHandle() to free resources used by the handle when it is no longer |
|
158 required. |
|
159 */ |
|
160 |
|
161 /*! |
|
162 \fn void QAbstractValueSpaceLayer::removeHandle(Handle handle) |
|
163 |
|
164 Releases a \a handle previously returned from QAbstractValueSpaceLayer::item(). |
|
165 */ |
|
166 |
|
167 /*! |
|
168 \fn void QAbstractValueSpaceLayer::setProperty(Handle handle, Properties property) |
|
169 |
|
170 Apply the specified \a property mask to \a handle. |
|
171 */ |
|
172 |
|
173 /*! |
|
174 \fn bool QAbstractValueSpaceLayer::value(Handle handle, QVariant *data) |
|
175 |
|
176 Returns the value for a particular \a handle. If a value is available, the layer will set |
|
177 \a data and return true. If no value is available, false is returned. |
|
178 */ |
|
179 |
|
180 /*! |
|
181 \fn bool QAbstractValueSpaceLayer::value(Handle handle, const QString &subPath, QVariant *data) |
|
182 |
|
183 Returns the value for a particular \a subPath of \a handle. If a value is available, the |
|
184 layer will set \a data and return true. If no value is available, false is returned. |
|
185 */ |
|
186 |
|
187 /*! |
|
188 \fn QSet<QString> QAbstractValueSpaceLayer::children(Handle handle) |
|
189 |
|
190 Returns the set of children of \a handle. For example, in a layer providing the following |
|
191 items: |
|
192 |
|
193 \code |
|
194 /Device/Configuration/Applications/FocusedApplication |
|
195 /Device/Configuration/Buttons/PrimaryInput |
|
196 /Device/Configuration/Name |
|
197 \endcode |
|
198 |
|
199 a request for children of "/Device/Configuration" will return |
|
200 { "Applications", "Buttons", "Name" }. |
|
201 */ |
|
202 |
|
203 /*! |
|
204 \fn QValueSpace::LayerOptions QAbstractValueSpaceLayer::layerOptions() const |
|
205 |
|
206 Returns the QValueSpace::LayerOptions describing this layer. |
|
207 |
|
208 \sa QValueSpace::LayerOption |
|
209 */ |
|
210 |
|
211 /*! |
|
212 \fn bool QAbstractValueSpaceLayer::supportsInterestNotification() const |
|
213 |
|
214 Returns true if the layer supports interest notifications; otherwise returns false. |
|
215 */ |
|
216 |
|
217 /*! |
|
218 \fn bool QAbstractValueSpaceLayer::notifyInterest(Handle handle, bool interested) |
|
219 |
|
220 Registers or unregisters that the caller is interested in \a handle and any subpaths under it. |
|
221 If \a interested is true interest in \a handle is registered; otherwise it is unregistered. |
|
222 |
|
223 The caller should ensure that all calls to this function with \a interested set to true have a |
|
224 matching call with \a interested set to false. |
|
225 |
|
226 Returns true if the notification was successfully sent; otherwise returns false. |
|
227 */ |
|
228 |
|
229 /*! |
|
230 \fn bool QAbstractValueSpaceLayer::setValue(QValueSpacePublisher *creator, Handle handle, |
|
231 const QString &subPath, const QVariant &value) |
|
232 |
|
233 Process calls to QValueSpacePublisher::setValue() by setting the value specified by the |
|
234 \a subPath under \a handle to \a value. Ownership of the Value Space item is assigned to |
|
235 \a creator. |
|
236 |
|
237 Returns true on success; otherwise returns false. |
|
238 */ |
|
239 |
|
240 /*! |
|
241 \fn bool QAbstractValueSpaceLayer::removeValue(QValueSpacePublisher *creator, Handle handle, |
|
242 const QString &subPath) |
|
243 |
|
244 Process calls to QValueSpacePublisher::resetValue() by removing the Value Space item |
|
245 identified by \a handle and \a subPath and created by \a creator. |
|
246 |
|
247 Returns true on success; otherwise returns false. |
|
248 */ |
|
249 |
|
250 /*! |
|
251 \fn bool QAbstractValueSpaceLayer::removeSubTree(QValueSpacePublisher *creator, Handle handle) |
|
252 |
|
253 Process calls to QValueSpacePublisher::~QValueSpacePublisher() by removing the entire sub tree |
|
254 created by \a creator under \a handle. |
|
255 |
|
256 Returns true on success; otherwise returns false. |
|
257 */ |
|
258 |
|
259 /*! |
|
260 \fn void QAbstractValueSpaceLayer::addWatch(QValueSpacePublisher *creator, Handle handle) |
|
261 |
|
262 Registers \a creator for change notifications to values under \a handle. |
|
263 |
|
264 \sa removeWatches() |
|
265 */ |
|
266 |
|
267 /*! |
|
268 \fn void QAbstractValueSpaceLayer::removeWatches(QValueSpacePublisher *creator, Handle parent) |
|
269 |
|
270 Removes all registered change notifications for \a creator under \a parent. |
|
271 |
|
272 \sa addWatch() |
|
273 */ |
|
274 |
|
275 /*! |
|
276 \fn void QAbstractValueSpaceLayer::sync() |
|
277 |
|
278 Flushes all pending changes made by calls to setValue(), removeValue() and removeSubTree(). |
|
279 */ |
|
280 |
|
281 /*! |
|
282 Emits the QValueSpacePublisher::interestChanged() signal on \a publisher with \a path |
|
283 and \a interested. |
|
284 */ |
|
285 void QAbstractValueSpaceLayer::emitInterestChanged(QValueSpacePublisher *publisher, |
|
286 const QString &path, |
|
287 bool interested) |
|
288 { |
|
289 emit publisher->interestChanged(path, interested); |
|
290 } |
|
291 |
|
292 /*! |
|
293 \fn void QAbstractValueSpaceLayer::handleChanged(quintptr handle) |
|
294 |
|
295 Emitted whenever the \a handle's value, or any sub value, changes. |
|
296 */ |
|
297 |
|
298 |
|
299 /*! |
|
300 \namespace QValueSpace |
|
301 \brief The QValueSpace namespace contains miscellaneous identifiers used throughtout the |
|
302 Publish and Subscribe API. |
|
303 \ingroup publishsubscribe |
|
304 */ |
|
305 |
|
306 /*! |
|
307 \enum QValueSpace::LayerOption |
|
308 |
|
309 This enum describes the behaviour of the Value Space layer. In addition this enum is used as |
|
310 a filter when constructing a QValueSpacePublisher or QValueSpaceSubscriber. |
|
311 |
|
312 \value UnspecifiedLayer Used as a filter to specify that any layer should be used. |
|
313 \value PermanentLayer Indicates that the layer uses a permanent backing store. When used |
|
314 as a filter only layers that use a permanent backing store will be |
|
315 used. |
|
316 \br |
|
317 Values stored in a layer with this option will persist with in the |
|
318 layer after the QValueSpacePublisher that published them is |
|
319 destroyed. Whether the value persists in the layer after the |
|
320 server or device is restarted is system dependent. |
|
321 \br |
|
322 This option and the TransientLayer option are mutually |
|
323 exclusive. |
|
324 \value TransientLayer Indicates that the layer does not use a permanent backing store. |
|
325 When used as a filter only layers that do not use permanent backing |
|
326 stores will be used. |
|
327 \br |
|
328 Values stored in a layer with this option will be removed when the |
|
329 QValueSpacePublisher that published them is destroyed. |
|
330 \br |
|
331 This option and the PermanentLayer option are mutually exclusive. |
|
332 \value WritableLayer Indicates that the layer can update its contents. When used as a |
|
333 filter only layers that are writable will be used. |
|
334 \br |
|
335 Applications can use QValueSpacePublisher to publish values to |
|
336 layers that have this option. |
|
337 \br |
|
338 This option and the ReadOnlyLayer option are mutually exclusive. |
|
339 \value ReadOnlyLayer Indicates that the layer cannot update its contents. When used as |
|
340 a filter only layers that are read-only will be used. |
|
341 \br |
|
342 Applications can not publish values to layers with this option. |
|
343 \br |
|
344 This option and the WritableLayer option are mutually exclusive. |
|
345 */ |
|
346 |
|
347 /*! |
|
348 \typedef QValueSpace::LayerCreateFunc |
|
349 \internal |
|
350 |
|
351 Support type used by the QVALUESPACE_AUTO_INSTALL_LAYER() macro. |
|
352 */ |
|
353 |
|
354 /*! |
|
355 \class QValueSpace::AutoInstall |
|
356 \internal |
|
357 |
|
358 Support class used by the QVALUESPACE_AUTO_INSTALL_LAYER() macro. |
|
359 */ |
|
360 |
|
361 /*! |
|
362 \fn QValueSpace::AutoInstall::AutoInstall(LayerCreateFunc func) |
|
363 |
|
364 Installs the Value Space layer at static construction time by calling the layer creation |
|
365 function \a func. |
|
366 */ |
|
367 |
|
368 /*! |
|
369 Initialize the Value Space manager as the server. This method only needs to be called by the |
|
370 process acting as the server and should be called before any process in the system uses a value |
|
371 space class. |
|
372 */ |
|
373 void QValueSpace::initValueSpaceServer() |
|
374 { |
|
375 QValueSpaceManager::instance()->initServer(); |
|
376 } |
|
377 |
|
378 /*! |
|
379 Used by Value Space layer implementations to install themselves into the system. \a layer |
|
380 should be a pointer to the layer to install. |
|
381 |
|
382 \sa QVALUESPACE_AUTO_INSTALL_LAYER() |
|
383 */ |
|
384 void QValueSpace::installLayer(QAbstractValueSpaceLayer *layer) |
|
385 { |
|
386 QValueSpaceManager::instance()->install(layer); |
|
387 } |
|
388 |
|
389 /*! |
|
390 \internal |
|
391 |
|
392 Called by the QVALUESPACE_AUTO_INSTALL_LAYER() macro to install the layer at static |
|
393 initialization time. |
|
394 */ |
|
395 void QValueSpace::installLayer(LayerCreateFunc func) |
|
396 { |
|
397 QValueSpaceManager::instance()->install(func); |
|
398 } |
|
399 |
|
400 /*! |
|
401 \macro QVALUESPACE_SHAREDMEMORY_LAYER |
|
402 \relates QValueSpace |
|
403 |
|
404 The UUID of the Shared Memory layer as a QUuid. The actual UUID value is |
|
405 {d81199c1-6f60-4432-934e-0ce4d37ef252}. |
|
406 |
|
407 This value can be passed to the constructor of QValueSpacePublisher or QValueSpaceSubscriber to |
|
408 force the constructed object to only access the Shared Memory layer. |
|
409 |
|
410 You can test if the Shared Memory layer is available by checking if the list returned by |
|
411 QValueSpace::availableLayers() contains this value. |
|
412 */ |
|
413 |
|
414 /*! |
|
415 \macro QVALUESPACE_VOLATILEREGISTRY_LAYER |
|
416 \relates QValueSpace |
|
417 |
|
418 The UUID of the Volatile Registry layer as a QUuid. The actual UUID value is |
|
419 {8ceb5811-4968-470f-8fc2-264767e0bbd9}. |
|
420 |
|
421 This value can be passed to the constructor of QValueSpacePublisher or QValueSpaceSubscriber to |
|
422 force the constructed object to only access the Volatile Registry layer. |
|
423 |
|
424 You can test if the Volatile Registry layer is available by checking if the list returned by |
|
425 QValueSpace::availableLayers() contains this value. The Volatile Registry layer is only |
|
426 available on Windows platforms. |
|
427 */ |
|
428 |
|
429 /*! |
|
430 \macro QVALUESPACE_NONVOLATILEREGISTRY_LAYER |
|
431 \relates QValueSpace |
|
432 |
|
433 The UUID of the Non-Volatile Registry layer as a QUuid. The actual UUID value is |
|
434 {8e29561c-a0f0-4e89-ba56-080664abc017}. |
|
435 |
|
436 This value can be passed to the constructor of QValueSpacePublisher or QValueSpaceSubscriber to |
|
437 force the constructed object to only access the Non-Volatile Registry layer. |
|
438 |
|
439 You can test if the Non-Volatile Registry layer is available by checking if the list returned |
|
440 by QValueSpace::availableLayers() contains this value. The Non-Volatile Registry layer is only |
|
441 available on Windows platforms. |
|
442 */ |
|
443 |
|
444 /*! |
|
445 \macro QVALUESPACE_CONTEXTKIT_LAYER |
|
446 \relates QValueSpace |
|
447 |
|
448 The UUID of the ContextKit layer as a QUuid. The actual UUID values is |
|
449 {2c769b9e-d949-4cd1-848f-d32241fe07ff}. |
|
450 |
|
451 This value can be passed to the constructor of QValueSpacePublisher or QValueSpaceSubscriber to |
|
452 force the constructed object to only access the ContextKit layer. |
|
453 |
|
454 You can test if the ContextKit layer is available by checking if the list returned by |
|
455 QValueSpace::availableLayers() contains this value. |
|
456 */ |
|
457 |
|
458 /*! |
|
459 \macro QVALUESPACE_SYMBIAN_SETTINGS_LAYER |
|
460 \relates QValueSpace |
|
461 |
|
462 The UUID of the Symbian Settings layer as a QUuid. The actual UUID value is |
|
463 {40d7b059-66ac-442f-b222-9c8ab98b9c2d}. |
|
464 |
|
465 This value can be passed to the constructor of QValueSpacePublisher or QValueSpaceSubscriber to |
|
466 force the constructed object to only access the Symbian Settings layer. |
|
467 |
|
468 You can test if the Symbian Settings layer is available by checking if the list returned by |
|
469 QValueSpace::availableLayers() contains this value. |
|
470 */ |
|
471 |
|
472 /*! |
|
473 Returns a list of QUuids of all of the available layers. |
|
474 */ |
|
475 QList<QUuid> QValueSpace::availableLayers() |
|
476 { |
|
477 QList<QAbstractValueSpaceLayer *> layers = QValueSpaceManager::instance()->getLayers(); |
|
478 |
|
479 QList<QUuid> uuids; |
|
480 |
|
481 for (int i = 0; i < layers.count(); ++i) |
|
482 uuids.append(layers.at(i)->id()); |
|
483 |
|
484 return uuids; |
|
485 } |
|
486 |
|
487 /*! |
|
488 \internal |
|
489 \ingroup publishsubscribe |
|
490 |
|
491 Returns \a path with all duplicate '/' characters removed. |
|
492 */ |
|
493 QString qCanonicalPath(const QString &path) |
|
494 { |
|
495 QString result; |
|
496 result.resize(path.length()); |
|
497 const QChar *from = path.constData(); |
|
498 const QChar *fromend = from + path.length(); |
|
499 int outc=0; |
|
500 QChar *to = result.data(); |
|
501 do { |
|
502 to[outc++] = QLatin1Char('/'); |
|
503 while (from!=fromend && *from == QLatin1Char('/')) |
|
504 ++from; |
|
505 while (from!=fromend && *from != QLatin1Char('/')) |
|
506 to[outc++] = *from++; |
|
507 } while (from != fromend); |
|
508 if (outc > 1 && to[outc-1] == QLatin1Char('/')) |
|
509 --outc; |
|
510 result.resize(outc); |
|
511 return result; |
|
512 } |
|
513 |
|
514 #include "moc_qvaluespace_p.cpp" |
|
515 |
|
516 QTM_END_NAMESPACE |