qtmobility/src/publishsubscribe/qvaluespace.cpp
changeset 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     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