--- a/qthighway/xqservice/src/xqservicechannel.cpp Tue Aug 31 16:02:37 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, version 2.1 of the License.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with this program. If not,
-* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
-*
-* Description:
-*
-*/
-
-#include "xqservicelog.h"
-
-#include "xqservicechannel.h"
-
-#include "xqservicethreaddata.h"
-#include "xqserviceipcclient.h"
-
-#include <xqserviceutil.h>
-#include <xqsharablefile.h>
-
-
-
-/*!
- \class XQServiceChannel
- \inpublicgroup QtBaseModule
- \ingroup qws
-
- \brief The XQServiceChannel class provides communication capabilities
- between clients.
-
- XQSERVICE is a many-to-many communication protocol for transferring
- messages on various channels. A channel is identified by a name,
- and anyone who wants to can listen to it. The XQSERVICE protocol allows
- clients to communicate both within the same address space and
- between different processes, but it is currently only available
- for \l {Qt for Embedded Linux} (on X11 and Windows we are exploring the use
- of existing standards such as DCOP and COM).
-
- Typically, XQServiceChannel is either used to send messages to a
- channel using the provided static functions, or to listen to the
- traffic on a channel by deriving from the class to take advantage
- of the provided functionality for receiving messages.
-
- XQServiceChannel provides a couple of static functions which are usable
- without an object: The send() function, which sends the given
- message and data on the specified channel, and the isRegistered()
- function which queries the server for the existence of the given
- channel.
-
- In addition, the XQServiceChannel class provides the channel() function
- which returns the name of the object's channel, the virtual
- receive() function which allows subclasses to process data
- received from their channel, and the received() signal which is
- emitted with the given message and data when a XQServiceChannel
- subclass receives a message from its channel.
-
- \sa XQServiceServer, {Running Qt for Embedded Linux Applications}
-*/
-
-/*!
- Constructs a XQService channel with the given \a parent, and registers it
- with the server using the given \a channel name.
- \param channel Channel name.
- \param isServer
- \param parent Parent of this object.
- \sa isRegistered(), channel()
-*/
-
-XQServiceChannel::XQServiceChannel(const QString& channel, bool isServer, QObject *parent)
- : QObject(parent)
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::XQServiceChannel");
- XQSERVICE_DEBUG_PRINT("channel: %s, isServer: %d", qPrintable(channel), isServer );
- d = new XQServiceChannelPrivate(this, channel, isServer);
- d->ref.ref();
-
- XQServiceThreadData *td = XQService::serviceThreadData();
-
- // do we need a new channel list ?
- XQServiceClientMap::Iterator it = td->clientMap.find(channel);
- if (it != td->clientMap.end()) {
- XQSERVICE_DEBUG_PRINT("Channel exits");
- it.value().append(XQServiceChannelPrivatePointer(d));
- return;
- }
- XQSERVICE_DEBUG_PRINT("New channel");
- it = td->clientMap.insert(channel, QList<XQServiceChannelPrivatePointer>());
- it.value().append(XQServiceChannelPrivatePointer(d));
-}
-
-/*!
- Destroys the client's end of the channel and notifies the server
- that the client has closed its connection. The server will keep
- the channel open until the last registered client detaches.
-
- \sa XQServiceChannel()
-*/
-
-XQServiceChannel::~XQServiceChannel()
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::~XQServiceChannel");
- XQServiceThreadData *td = XQService::serviceThreadData();
-
- XQServiceClientMap::Iterator it = td->clientMap.find(d->channel);
- Q_ASSERT(it != td->clientMap.end());
- it.value().removeAll(XQServiceChannelPrivatePointer(d));
- // still any clients connected locally ?
- if (it.value().isEmpty()) {
- if (td->hasClientConnection(d->channel))
- td->closeClientConnection(d->channel);
- td->clientMap.remove(d->channel);
- }
-
- // Dereference the private data structure. It may stay around
- // for a little while longer if it is in use by sendLocally().
- d->object = 0;
- if (!d->ref.deref())
- delete d;
-}
-
-bool XQServiceChannel::connectChannel()
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::connectChannel");
- bool ret = true;
-
- XQServiceThreadData *td = XQService::serviceThreadData();
-
- if (!td->hasClientConnection(d->channel)) {
- XQSERVICE_DEBUG_PRINT("Create new client connection (1)");
- ret = td->createClientConnection(d->channel,d->server);
- }
- return ret;
-}
-
-/*!
- Returns the name of the channel.
-
- \sa XQServiceChannel()
-*/
-
-QString XQServiceChannel::channel() const
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::channel");
- XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(d->channel));
- return d->channel;
-}
-
-/*!
- \fn void XQServiceChannel::receive(const QString& message, const QByteArray &data)
-
- This virtual function allows subclasses of XQServiceChannel to process
- the given \a message and \a data received from their channel. The default
- implementation emits the received() signal.
-
- Note that the format of the given \a data has to be well defined
- in order to extract the information it contains. In addition, it
- is recommended to use the DCOP convention. This is not a
- requirement, but you must ensure that the sender and receiver
- agree on the argument types.
-
- Example:
-
- \code
- void MyClass::receive(const QString &message, const QByteArray &data)
- {
- QDataStream in(data);
- if (message == "execute(QString,QString)") {
- QString cmd;
- QString arg;
- in >> cmd >> arg;
- ...
- } else if (message == "delete(QString)") {
- QString fileName;
- in >> fileName;
- ...
- } else {
- ...
- }
- }
- \endcode
-
- This example assumes that the \c message is a DCOP-style function
- signature and the \c data contains the function's arguments.
-
- \sa send()
- */
-QVariant XQServiceChannel::receive(const QString& msg, const QByteArray &data, const XQSharableFile &sf )
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::receive");
- XQSERVICE_DEBUG_PRINT("msg: %s, data: %s", qPrintable(msg), data.constData());
- emit received(msg, data,sf);
- return QVariant();
-}
-
-void XQServiceChannel::commandReceive(const XQServiceCommand cmd)
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::commandReceive %d", cmd);
- emit commandReceived(cmd);
-}
-
-/*!
- \fn void XQServiceChannel::received(const QString& message, const QByteArray &data)
-
- This signal is emitted with the given \a message and \a data whenever the
- receive() function gets incoming data.
-
- \sa receive()
-*/
-
-/*!
- \fn bool XQServiceChannel::send(const QString& channel, const QString& message,
- const QByteArray &data)
-
- Sends the given \a message on the specified \a channel with the
- given \a data. The message will be distributed to all clients
- subscribed to the channel. Returns true if the message is sent
- successfully; otherwise returns false.
-
- It is recommended to use the DCOP convention. This is not a
- requirement, but you must ensure that the sender and receiver
- agree on the argument types.
-
- Note that QDataStream provides a convenient way to fill the byte
- array with auxiliary data.
-
- Example:
-
- \code
- QByteArray data;
- QDataStream out(&data, QIODevice::WriteOnly);
- out << QString("cat") << QString("file.txt");
- XQServiceChannel::send("System/Shell", "execute(QString,QString)", data);
- \endcode
-
- Here the channel is \c "System/Shell". The \c message is an
- arbitrary string, but in the example we've used the DCOP
- convention of passing a function signature. Such a signature is
- formatted as \c "functionname(types)" where \c types is a list of
- zero or more comma-separated type names, with no whitespace, no
- consts and no pointer or reference marks, i.e. no "*" or "&".
-
- \sa receive()
-*/
-
-bool XQServiceChannel::send(const QString& channel, const QString& msg,
- const QByteArray &data, QVariant &retValue,
- bool sync, XQServiceRequestCompletedAsync* rc)
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::send(1). No user data");
- // Delegate to actual send.
- // No user data argument present in this version
- return send(channel,msg,data,retValue,sync,rc,NULL);
-}
-
-
-
-bool XQServiceChannel::send(const QString& channel, const QString& msg,
- const QByteArray &data, QVariant &retValue,
- bool sync, XQServiceRequestCompletedAsync* rc,
- const void* userData)
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::send(2) start");
- XQSERVICE_DEBUG_PRINT("\t channel: %s, msg: %s", qPrintable(channel), qPrintable(msg));
- XQSERVICE_DEBUG_PRINT("\t data: %s, sync: %d", data.constData(), sync);
- bool ret=true;
-
- if (!XQService::serviceThreadData()->hasClientConnection(channel)) {
- XQSERVICE_DEBUG_PRINT("\t Create new client connection (2)");
- ret = XQService::serviceThreadData()->createClientConnection(channel,false,sync,rc, userData);
- XQSERVICE_DEBUG_PRINT("\t creation succeeded: %d", ret);
- }
- if (ret) {
- XQSERVICE_DEBUG_PRINT("\t ret = true");
- XQServiceIpcClient *cl = XQService::serviceThreadData()->clientConnection(channel);
- QByteArray retData ;
- ret = cl ? cl->send(channel, msg, data, retData) : false;
- if (sync) {
- retValue = XQServiceThreadData::deserializeRetData(retData);
- }
- }
- XQSERVICE_DEBUG_PRINT("\t ret: %d", ret);
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::send(2) end");
- return ret;
-}
-
-
-bool XQServiceChannel::cancelPendingSend(const QString& channel)
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::cancelPendingSend start");
- XQSERVICE_DEBUG_PRINT("\t channel: %s", qPrintable(channel));
- bool ret=true;
-
- if (ret) {
- XQServiceIpcClient *cl = XQService::serviceThreadData()->clientConnection(channel);
- XQSERVICE_DEBUG_PRINT("\t XQService::serviceThreadData()->clientConnection(channel): %d", cl);
- XQSERVICE_DEBUG_PRINT("\t cl->cancelPendingSend(%s)", qPrintable(channel));
- ret = cl ? cl->cancelPendingSend(channel) : false;
- }
-
- XQSERVICE_DEBUG_PRINT("\t ret: %d", ret);
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::cancelPendingSend end");
- return ret;
-}
-
-/*!
- \internal
- Client side: distribute received event to the XQService instance managing the
- channel.
-*/
-QVariant XQServiceChannel::sendLocally(const QString& ch, const QString& msg,
- const QByteArray &data, const XQSharableFile &sf )
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::sendLocally");
- XQSERVICE_DEBUG_PRINT("channel: %s, msg: %s", qPrintable(ch), qPrintable(msg));
- XQSERVICE_DEBUG_PRINT("data: %s", data.constData());
- QVariant ret;
-
- // feed local clients with received data
- XQServiceThreadData *td = XQService::serviceThreadData();
- QList<XQServiceChannelPrivatePointer> clients = td->clientMap[ch];
- for (int i = 0; i < clients.size(); ++i) {
- XQServiceChannelPrivate *channel = clients.at(i).data();
- if (channel->object)
- ret = channel->object->receive(msg, data,sf );
- }
-
-#ifdef XQSERVICE_DEBUG
- QString s = ret.toString();
- int len=s.length();
- XQSERVICE_DEBUG_PRINT("sendLocally ret: type=%s,len=%d,value(max.1024)=%s",
- ret.typeName(),len,qPrintable(s.left(1024)));
-#endif
- return ret ;
-}
-
-int XQServiceChannel::latestError()
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::latestError");
- return XQService::serviceThreadData()->latestError();
-}
-
-void XQServiceChannel::sendCommand(const QString& ch,const XQServiceCommand cmd)
-{
- XQSERVICE_DEBUG_PRINT("XQServiceChannel::sendCommand");
- XQSERVICE_DEBUG_PRINT("channel: %s, cmd: %d", qPrintable(ch), cmd);
- // feed local clients with received data
- XQServiceThreadData *td = XQService::serviceThreadData();
- QList<XQServiceChannelPrivatePointer> clients = td->clientMap[ch];
- for (int i = 0; i < clients.size(); ++i) {
- XQServiceChannelPrivate *channel = clients.at(i).data();
- if (channel->object)
- channel->object->commandReceive(cmd);
- }
-}
-