qthighway/xqservice/src/xqservicerequest.cpp
branchRCL_3
changeset 9 5d007b20cfd0
equal deleted inserted replaced
8:885c2596c964 9:5d007b20cfd0
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * This program is free software: you can redistribute it and/or modify
       
     6 * it under the terms of the GNU Lesser General Public License as published by
       
     7 * the Free Software Foundation, version 2.1 of the License.
       
     8 * 
       
     9 * This program is distributed in the hope that it will be useful,
       
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 * GNU Lesser General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU Lesser General Public License
       
    15 * along with this program.  If not, 
       
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
       
    17 *
       
    18 * Description:                                                         
       
    19 *
       
    20 */
       
    21 
       
    22 #include "xqservicelog.h"
       
    23 
       
    24 #include "xqservicerequest.h"
       
    25 #include "xqservicethreaddata.h"
       
    26 
       
    27 #include "xqservicechannel.h"
       
    28 #include "xqserviceadaptor.h"
       
    29 #include "xqrequestutil.h"
       
    30 #include <QStringList>
       
    31 #include <xqservicemanager.h>
       
    32 
       
    33 /*!
       
    34     \class XQServiceRequest_Private
       
    35     \inpublicgroup QtBaseModule
       
    36 
       
    37     \ingroup ipc
       
    38     \brief Private implementation of the XQServiceRequest.
       
    39 */
       
    40 
       
    41 class XQServiceRequest_Private : public XQServiceRequestCompletedAsync
       
    42 {
       
    43 public:
       
    44     XQServiceRequest_Private(XQServiceRequest* parent)
       
    45         : mSynchronous(true), mParent(parent),mServiceManager(NULL)
       
    46     {    
       
    47         XQSERVICE_DEBUG_PRINT("XQServiceRequest_Private::XQServiceRequest_Private(1)");
       
    48         
       
    49     };
       
    50 
       
    51     XQServiceRequest_Private(const QString& fullServiceName, 
       
    52                              const QString& message, 
       
    53                              const bool &synchronous, 
       
    54                              XQServiceRequest* parent)
       
    55         : mService(fullServiceName), mMessage(message), mSynchronous(synchronous), mParent(parent),mServiceManager(NULL)
       
    56     {    
       
    57         XQSERVICE_DEBUG_PRINT("XQServiceRequest_Private::XQServiceRequest_Private(2)");
       
    58     };
       
    59 
       
    60     XQServiceRequest_Private(const XQAiwInterfaceDescriptor &descriptor, 
       
    61                              const QString& message, 
       
    62                              const bool &synchronous, 
       
    63                             XQServiceRequest* parent)
       
    64             : mMessage(message), mSynchronous(synchronous), mParent(parent),mServiceManager(NULL)
       
    65     {
       
    66         XQSERVICE_DEBUG_PRINT("XQServiceRequest_Private::XQServiceRequest_Private(3)");
       
    67         
       
    68         // Construct service name understood by the QtHighway FW
       
    69         // (The descriptor has been created from the  XML)
       
    70         mService = descriptor.serviceName() + "." + descriptor.interfaceName();
       
    71         XQSERVICE_DEBUG_PRINT("XQServiceRequest_Private(3)::service=%s", qPrintable(mService));
       
    72 
       
    73         // Remember the descriptor
       
    74         mRequestUtil.mDescriptor = descriptor; 
       
    75     };
       
    76     
       
    77     ~XQServiceRequest_Private();
       
    78     // from XQServiceRequestCompletedAsync
       
    79     void requestCompletedAsync(const QVariant &retValue);
       
    80     void requestErrorAsync(int err);
       
    81     
       
    82     QList<QVariant> mArguments;
       
    83     QString mService;
       
    84     QString mMessage;
       
    85     bool mSynchronous;
       
    86     XQServiceRequest* mParent;
       
    87     XQRequestUtil mRequestUtil;
       
    88     XQServiceManager* mServiceManager;
       
    89     QString mUniqueChannelName;
       
    90     
       
    91 };
       
    92 
       
    93 XQServiceRequest_Private::~XQServiceRequest_Private()
       
    94 {
       
    95     XQSERVICE_DEBUG_PRINT("XQServiceRequest_Private::~XQServiceRequest_Private");
       
    96     delete mServiceManager;
       
    97 };
       
    98 
       
    99 void XQServiceRequest_Private::requestCompletedAsync(const QVariant &retValue)
       
   100 {    
       
   101     XQSERVICE_DEBUG_PRINT("XQServiceRequest_Private::requestCompletedAsync");
       
   102     emit mParent->requestCompleted(retValue);
       
   103 }
       
   104 
       
   105 void XQServiceRequest_Private::requestErrorAsync(int err)
       
   106 {    
       
   107     XQSERVICE_DEBUG_PRINT("XQServiceRequest_Private::requestErrorAsync");
       
   108     emit mParent->requestError(err);
       
   109 }
       
   110 
       
   111 /*!
       
   112     \class XQServiceRequest
       
   113     \inpublicgroup QtBaseModule
       
   114 
       
   115     \ingroup ipc
       
   116     \brief Allows applications to request services from other applications.
       
   117     
       
   118     The XQServiceRequest class allows applications to request services from other applications.
       
   119     A XQServiceRequest encapsulates a service name and the message to be sent to that service.
       
   120     
       
   121     \note One should be using XQApplicationManager and the related XQAiwRequest instead of XQServiceRequest.
       
   122           The XQApplicationManager and related classes encapsulate basic, target-architecture approved
       
   123           support for out-of-process Application Interworking, e.g. support for launching URLs
       
   124           (including activity URLs), normal files, sharable files, etc. (whatever needed).
       
   125     
       
   126     \b Examples: \n
       
   127     
       
   128     How to create synchronous request without parameters and return value? 
       
   129     \note The full name (yourservice.Interface) need to be used (with dot (.) between service name and interface name).
       
   130     
       
   131     \code
       
   132         XQServiceRequest request("yourservice.<b>Interface</b>", "functionName1()");
       
   133         bool res = request.send();
       
   134         if  (!res) {
       
   135             int error = request.latestError();
       
   136         }
       
   137     \endcode
       
   138     
       
   139     How to create synchronous request with several parameters and return value?
       
   140     
       
   141     \code
       
   142         QString parameter1("+3581234567890");
       
   143         int parameter2 = 3;
       
   144         XQServiceRequest request("yourservice.<b>Interface</b>", "functionName2(QString, int)");
       
   145         request << parameter1;
       
   146         request << parameter2;
       
   147         int returnvalue;
       
   148         bool res = request.send(returnvalue);
       
   149         if  (!res) {
       
   150             int error = request.latestError();
       
   151         }
       
   152     \endcode
       
   153     
       
   154     How to create asynchronous request without return value?
       
   155     
       
   156     \code
       
   157         QString parameter1("+3581234567890");
       
   158         int parameter2 = 3;
       
   159         XQServiceRequest request("yourservice.Interface", "functionName2(QString, int)", false);
       
   160         request << parameter1;
       
   161         request << parameter2;
       
   162         bool res = request.send();
       
   163         if (!res) {
       
   164             int error = request.latestError();
       
   165         }
       
   166     \endcode
       
   167     
       
   168     How to create asynchronous request with return value?
       
   169     
       
   170     \code
       
   171         QString parameter1("+3581234567890");
       
   172         int parameter2 = 3;
       
   173         XQServiceRequest request("yourservice.Interface", "functionName2(QString, int)", false);
       
   174         request << parameter1;
       
   175         request << parameter2;
       
   176         connect(request, SIGNAL(requestCompleted(QVariant)), this, SLOT(requestCompleted(QVariant)));
       
   177         bool res = request.send();
       
   178         if (!res) {
       
   179             int error = request.latestError();
       
   180         }
       
   181 
       
   182         ...
       
   183 
       
   184         void requestCompleted(const QVariant& value)
       
   185         {
       
   186             int returnvalue = value.toInt();
       
   187         }
       
   188     \endcode
       
   189     
       
   190     How to use declare custom type?
       
   191     
       
   192     Header:
       
   193     \code
       
   194         class CustomType 
       
   195         { 
       
   196         public: 
       
   197             CustomType (){}; 
       
   198             virtual ~CustomType(){};
       
   199 
       
   200             QString mString1; 
       
   201             QString mString2; 
       
   202             QUuid mUid;
       
   203 
       
   204             template <typename Stream> void serialize(Stream &stream) const; 
       
   205             template <typename Stream> void deserialize(Stream &stream); 
       
   206         };
       
   207 
       
   208         Q_DECLARE_USER_METATYPE(CustomType)
       
   209     \endcode
       
   210     
       
   211     Implementation:
       
   212     \code        
       
   213         template <typename Stream> void CustomType::serialize(Stream &s) const 
       
   214             { 
       
   215             s << mString1; 
       
   216             s << mString2; 
       
   217             s << mUid; 
       
   218             }
       
   219 
       
   220         template <typename Stream> void CustomType::deserialize(Stream &s) 
       
   221             { 
       
   222             s >> mString1; 
       
   223             s >> mString2; 
       
   224             s >> mUid; 
       
   225             }
       
   226 
       
   227         Q_IMPLEMENT_USER_METATYPE(CustomType)
       
   228     \endcode
       
   229     
       
   230     How to declare custom type that doesn't need data stream operators?
       
   231     
       
   232     Header:
       
   233     \code
       
   234         typedef QList<CustomType> CustomTypeList;
       
   235 
       
   236         Q_DECLARE_USER_METATYPE_NO_OPERATORS(CustomTypeList)
       
   237     \endcode
       
   238     
       
   239     Implementation:
       
   240     \code
       
   241         Q_IMPLEMENT_USER_METATYPE_NO_OPERATORS(CustomTypeList)
       
   242     \endcode
       
   243 */
       
   244 
       
   245 /*!
       
   246     \fn bool XQServiceRequest::send(T& retValue)
       
   247 
       
   248     Sends the request. If the request is synchronous, then client is blocked
       
   249     until service provider completes the request or request fails for some reason.
       
   250     If the request is asynchronous, then client won't be blocked.
       
   251     \param retValue Defines refence to a value service provider will return after service.
       
   252     \return False if there was no application that could service the request, otherwise true.
       
   253 */
       
   254 
       
   255 /*!
       
   256     \fn XQServiceRequest &XQServiceRequest::operator<< (const T &var)
       
   257 
       
   258     Adds \a var to the list of arguments for this service request.
       
   259     \param var Defines the argument value to add to the list of arguments.
       
   260 */
       
   261 
       
   262 /*!
       
   263     \fn XQServiceRequest &XQServiceRequest::operator<< (const char *var)
       
   264 
       
   265     Adds \a var to the list of arguments for this service request.
       
   266     \param var Defines the argument value to add to the list of arguments.
       
   267 */
       
   268 
       
   269 /*!
       
   270     \fn void XQServiceRequest::requestCompleted(const QVariant& value)
       
   271 
       
   272     This signal is emitted when service provider returns a return value asynchronously back to the client.
       
   273     \param value Result of the request.
       
   274 */
       
   275 
       
   276 /*!
       
   277     \fn void XQServiceRequest::requestError(int err);
       
   278 
       
   279     This signal is emitted when error has happened in request handling.
       
   280     \param err Error code as integer value.
       
   281     \sa XQService::ServiceIPCErrors
       
   282 */
       
   283 
       
   284 /*!
       
   285     \fn void XQServiceRequest::addVariantArg(const QVariant& var)
       
   286 
       
   287     Adds the variant value to the list of arguments, so that the variant's
       
   288     value is serialized in send() rather than the variant itself.
       
   289     \param var Value to be added to the list of arguments.
       
   290 */
       
   291 
       
   292 /*!
       
   293     Construct a null service request.
       
   294     setService() and setMessage() must be called before send(), but the
       
   295     service may be written prior to the calls.
       
   296  */
       
   297 XQServiceRequest::XQServiceRequest()
       
   298 {
       
   299     XQSERVICE_DEBUG_PRINT("XQServiceRequest::XQServiceRequest(1)");
       
   300     mData = new XQServiceRequest_Private(this);
       
   301 }
       
   302 
       
   303 /*!
       
   304     Construct a service request that will send \a message to
       
   305     a \a service when send() is called. The service may be written
       
   306     prior to the calls.
       
   307     \param service Defines the full service name to send message. The full name is:
       
   308                    - The name of the service in the service configuration file
       
   309                    - Character *.* (dot)
       
   310                    - The name of the interface from the service XML.
       
   311     \param message Defines the message to send to the service provider i.e. it is
       
   312                  the signature of the service provider function to be called.
       
   313     \param synchronous Defines should message be sent synchronously or asynchronously.
       
   314                      By default message is sent synchronously.
       
   315 */
       
   316 XQServiceRequest::XQServiceRequest(const QString& service, const QString& message, const bool &synchronous)
       
   317 {
       
   318     XQSERVICE_DEBUG_PRINT("XQServiceRequest::XQServiceRequest(2)");
       
   319     XQSERVICE_DEBUG_PRINT("service: %s, message: %s, synchronous: %d", qPrintable(service), qPrintable(message), synchronous);
       
   320     mData = new XQServiceRequest_Private(service,message,synchronous,this);
       
   321 }
       
   322 
       
   323 /*!
       
   324     Copy constructor. Any data previously written to the \a orig
       
   325     service will be in the copy.
       
   326     \param orig XQServiceRequest from which data will be copied to this object.
       
   327 */
       
   328 XQServiceRequest::XQServiceRequest(const XQServiceRequest& orig)
       
   329 {
       
   330     XQSERVICE_DEBUG_PRINT("XQServiceRequest::XQServiceRequest(3)");
       
   331     mData = new XQServiceRequest_Private(orig.mData->mService,orig.mData->mMessage,orig.mData->mSynchronous,this);
       
   332     mData->mArguments = orig.mData->mArguments;
       
   333 }
       
   334 
       
   335 /*!
       
   336     Construct a service request by service descriptor which contains exact details of the service and interface.
       
   337     The service may be written prior to the calls.
       
   338     \param descriptor Defines details of the service and it's interface.
       
   339     \param message Message to be sent when send() is called.
       
   340     \param synchronous Defines should message be sent synchronously or asynchronously.
       
   341                        By default message is sent synchronously.
       
   342 */
       
   343 XQServiceRequest::XQServiceRequest(const XQAiwInterfaceDescriptor &descriptor, const QString& message, const bool &synchronous)
       
   344 {
       
   345     XQSERVICE_DEBUG_PRINT("XQServiceRequest::XQServiceRequest(2)");
       
   346     XQSERVICE_DEBUG_PRINT("service: %s, interface %s, message: %s, synchronous: %d",
       
   347                           qPrintable(descriptor.serviceName()), qPrintable(descriptor.interfaceName()),
       
   348                           qPrintable(message), synchronous);
       
   349     mData = new XQServiceRequest_Private(descriptor,message,synchronous,this);
       
   350 }
       
   351 
       
   352 /*!
       
   353     Assignment operator.
       
   354     Any data previously written to the \a orig
       
   355     service will be in the copy.
       
   356 */
       
   357 XQServiceRequest& XQServiceRequest::operator=(const XQServiceRequest& orig)
       
   358 {
       
   359     XQSERVICE_DEBUG_PRINT("XQServiceRequest::operator=");
       
   360     if( &orig == this )
       
   361         return *this;
       
   362 
       
   363     mData->mService = orig.mData->mService;
       
   364     mData->mMessage = orig.mData->mMessage;
       
   365     mData->mArguments = orig.mData->mArguments;
       
   366     mData->mRequestUtil = orig.mData->mRequestUtil;
       
   367 
       
   368     return *this;
       
   369 }
       
   370 
       
   371 /*!
       
   372     Destroys the service request. Unlike QtopiaIpcEnvelope, the
       
   373     request is not automatically sent.
       
   374 */
       
   375 XQServiceRequest::~XQServiceRequest()
       
   376 {
       
   377     XQSERVICE_DEBUG_PRINT("XQServiceRequest::~XQServiceRequest %s", qPrintable(mData->mUniqueChannelName));
       
   378     XQServiceAdaptor::cancelPendingSend(mData->mUniqueChannelName);
       
   379     delete mData;
       
   380 }
       
   381 
       
   382 /*!
       
   383     Checks if request is NULL.
       
   384     \return True if either the service() or message() is not set.
       
   385     \sa service(), message()
       
   386  */
       
   387 bool XQServiceRequest::isNull() const
       
   388 {
       
   389     XQSERVICE_DEBUG_PRINT("XQServiceRequest::isNull");
       
   390     bool ret = mData->mService.isEmpty() || mData->mService.isNull() || mData->mMessage.isNull();
       
   391 	XQSERVICE_DEBUG_PRINT("mData->mService.isEmpty() = %d", mData->mService.isEmpty());
       
   392 	XQSERVICE_DEBUG_PRINT("mData->mService.isNull() = %d", mData->mService.isNull());
       
   393 	XQSERVICE_DEBUG_PRINT("mData->mMessage.isNull() = %d", mData->mMessage.isNull());
       
   394 	XQSERVICE_DEBUG_PRINT("return %d", ret);
       
   395 	return ret;
       
   396 }
       
   397 
       
   398 /*!
       
   399     Checks if request is synchronous or asynchronous.
       
   400     \return True if request is synchronous, false if request is asynchronous.
       
   401     \sa setSynchronous()
       
   402  */
       
   403 bool XQServiceRequest::isSynchronous() const
       
   404 {
       
   405     XQSERVICE_DEBUG_PRINT("XQServiceRequest::isSynchronous");
       
   406     return mData->mSynchronous;
       
   407 }
       
   408 
       
   409 /*!
       
   410     Sets request to be synchronous or asynchronous.
       
   411     \param synchronous If set to true, request will be synchronous.
       
   412                        If set to false, request will be asynchronous.
       
   413     \sa isSynchronous()
       
   414  */
       
   415 void XQServiceRequest::setSynchronous(const bool& synchronous)
       
   416 {
       
   417     XQSERVICE_DEBUG_PRINT("XQServiceRequest::setSynchronous");
       
   418     mData->mSynchronous = synchronous;
       
   419 }
       
   420 /*!
       
   421     Sends the request. If the request is synchronous, then client is blocked
       
   422     until service provider completes the request or request fails for some reason.
       
   423     If the request is asynchronous, then client won't be blocked. If the request
       
   424     is asynchronous and clients wants to receive a return value from the service
       
   425     provider, then clients should connect to the requestCompleted() signal.
       
   426     \return False if there was no application that could service the request, otherwise true.
       
   427 */
       
   428 bool XQServiceRequest::send()
       
   429 {
       
   430     XQSERVICE_DEBUG_PRINT("XQServiceRequest::send(1)");
       
   431     QVariant retValue;
       
   432     return send(retValue);
       
   433 }
       
   434 
       
   435 /*!
       
   436     Sends the request. If the request is synchronous, then client is blocked
       
   437     until service provider completes the request or request fails for some reason.
       
   438     If the request is asynchronous, then client won't be blocked.
       
   439     \param retData Defines refence to a value service provider will return after service.
       
   440     \return False if there was no application that could service the request, otherwise true.
       
   441 */
       
   442 bool XQServiceRequest::send(QVariant& retData)
       
   443 {
       
   444     XQSERVICE_DEBUG_PRINT("XQServiceRequest::send(2)");
       
   445     if (isNull())
       
   446     {
       
   447         XQSERVICE_DEBUG_PRINT("XQServiceRequest::send error: null request");
       
   448         XQService::serviceThreadData()->setLatestError(XQService::EArgumentError);
       
   449         return false;
       
   450     }
       
   451     
       
   452     // Handle sharable file argument(s), if any
       
   453     if (!handleSharableFileArgs())
       
   454     {
       
   455         XQSERVICE_DEBUG_PRINT("XQServiceRequest::send error:invalid sharable file");
       
   456         XQService::serviceThreadData()->setLatestError(XQService::EArgumentError);
       
   457         return false;
       
   458     }
       
   459     
       
   460     mData->mRequestUtil.setSynchronous(mData->mSynchronous); // Ensure option is set !
       
   461     mData->mRequestUtil.mOperation = mData->mMessage;  // Save the operation name for startup
       
   462     
       
   463     // !!!
       
   464     // Add the info as extra argument to the request
       
   465     // This shall be removed by the server
       
   466     // !!!
       
   467     addArg(qVariantFromValue(mData->mRequestUtil.mInfo));
       
   468        
       
   469     // Pass always the util instance onwards as user data.
       
   470     // It can be utilized by the XQServiceManager::startServer
       
   471     // e.g. to optimize startup of a service server
       
   472 
       
   473     // Create unique channel name to separate multiple client requests to same channel name.
       
   474     quint32 handle = (unsigned int)mData;
       
   475     mData->mUniqueChannelName = QString("%1:").arg(handle) + mData->mService;
       
   476     XQSERVICE_DEBUG_PRINT("XQServiceRequest::send(2):uniqueChannel=%s", qPrintable(mData->mUniqueChannelName));
       
   477     return XQServiceAdaptor::send(mData->mUniqueChannelName,  message(), mData->mArguments, retData, mData->mSynchronous,mData,
       
   478                                  (const void *)&mData->mRequestUtil);
       
   479 }
       
   480 /*!
       
   481     Sets the full name of the service to which the request will be sent.
       
   482     \param fullServiceName Full name of the service to send message to. See
       
   483                            XQServiceRequest(const QString& service, const QString& message, const bool &synchronous)
       
   484                            for the full name definition.
       
   485     \sa service()
       
   486  */
       
   487 void XQServiceRequest::setService(const QString& fullServiceName)
       
   488 {
       
   489     XQSERVICE_DEBUG_PRINT("XQServiceRequest::setService");
       
   490     XQSERVICE_DEBUG_PRINT("service: %s", qPrintable(fullServiceName));
       
   491     mData->mService = fullServiceName;
       
   492     mData->mArguments.clear();
       
   493     mData->mRequestUtil.mDescriptor = XQAiwInterfaceDescriptor(); // Invalid descriptor
       
   494 }
       
   495 
       
   496 /*!
       
   497     Gets the service name to which this request will be sent.
       
   498     \return Full service name to which request will be sent.
       
   499     \sa setService()
       
   500 */
       
   501 QString XQServiceRequest::service() const
       
   502 {
       
   503     XQSERVICE_DEBUG_PRINT("XQServiceRequest::service");
       
   504     XQSERVICE_DEBUG_PRINT("service: %s", qPrintable(mData->mService));
       
   505     return mData->mService;
       
   506 }
       
   507 
       
   508 /*!
       
   509     Sets the \a message to be sent to the service.
       
   510     \param message Defines the message to send to a service provider. The message
       
   511                    is a valid Qt slot signature published by the service provider.
       
   512                    For example, "view(QString)".
       
   513     \sa message()
       
   514 */
       
   515 void XQServiceRequest::setMessage(const QString& message)
       
   516 {
       
   517     XQSERVICE_DEBUG_PRINT("XQServiceRequest::setMessage");
       
   518     XQSERVICE_DEBUG_PRINT("message: %s", qPrintable(message));
       
   519     mData->mMessage = message;
       
   520     mData->mArguments.clear();
       
   521 }
       
   522 
       
   523 /*!
       
   524     Gets the message set for the request.
       
   525     \return Message of the request as QString.
       
   526     \sa setMessage()
       
   527 */
       
   528 QString XQServiceRequest::message() const
       
   529 { 
       
   530     XQSERVICE_DEBUG_PRINT("XQServiceRequest::message");
       
   531     XQSERVICE_DEBUG_PRINT("message: %s", qPrintable(mData->mMessage));
       
   532     return mData->mMessage;
       
   533 }
       
   534 
       
   535 /*!
       
   536     Gets the complete list of arguments for this service request.
       
   537     \return List of arguments set to the request.
       
   538     \sa setArguments()
       
   539 */
       
   540 const QList<QVariant> &XQServiceRequest::arguments() const 
       
   541 {
       
   542     XQSERVICE_DEBUG_PRINT("XQServiceRequest::arguments");
       
   543     return mData->mArguments; 
       
   544 }
       
   545 
       
   546 /*!
       
   547     Sets \a arguments for this service request.
       
   548     \param arguments Complete list of arguments for this service request
       
   549                      i.e. the values to be transferred to service provider
       
   550                      function to be called.
       
   551     \sa arguments()
       
   552 */
       
   553 void XQServiceRequest::setArguments(const QList<QVariant> &arguments)
       
   554 {
       
   555     XQSERVICE_DEBUG_PRINT("XQServiceRequest::setArguments");
       
   556     mData->mArguments = arguments;
       
   557 }
       
   558 
       
   559 /*!
       
   560     Gets the latest error that happened in the request execution.
       
   561     \return The latest error that happened in the request execution.
       
   562             Errors are defined in xqserviceglobal.h. 
       
   563     \sa XQService::ServiceIPCErrors.
       
   564 */
       
   565 int XQServiceRequest::latestError()
       
   566     {
       
   567     XQSERVICE_DEBUG_PRINT("XQServiceRequest::latestError");
       
   568     return XQServiceAdaptor::latestError();
       
   569     }
       
   570 
       
   571 /*!
       
   572     Sets additional options for the request, like embedding or start to background.
       
   573     \param info Additional info to be set to the request.
       
   574     \sa info()
       
   575 */
       
   576 void XQServiceRequest::setInfo(const XQRequestInfo &info)
       
   577 {
       
   578     XQSERVICE_DEBUG_PRINT("XQServiceRequest::setInfo");
       
   579     mData->mRequestUtil.mInfo = info;
       
   580 }
       
   581 
       
   582 /*!
       
   583     Gets current info set for the request.
       
   584     \return Info data set to the request.
       
   585     \sa setInfo()
       
   586 */
       
   587 XQRequestInfo XQServiceRequest::info() const
       
   588 {
       
   589     XQSERVICE_DEBUG_PRINT("XQServiceRequest::info");
       
   590     return mData->mRequestUtil.mInfo;
       
   591 }
       
   592 
       
   593 /*!
       
   594     \internal
       
   595     Adds the variant \a var to the list of arguments, so that the variant's
       
   596     value is serialized in send() rather than the variant itself.
       
   597 */
       
   598 void XQServiceRequest::addArg(const QVariant& v)
       
   599 {
       
   600     XQSERVICE_DEBUG_PRINT("XQServiceRequest::addArg %s,%d", v.typeName());
       
   601     XQSERVICE_DEBUG_PRINT("v: %s", qPrintable(v.toString()));
       
   602     mData->mArguments.append(v);
       
   603 }
       
   604 
       
   605 /*!
       
   606     \internal
       
   607     Picks the XQSharableFile argument, if any, into the request util
       
   608     This way scan parameter is listed only once.
       
   609 */
       
   610 bool XQServiceRequest::handleSharableFileArgs()
       
   611 {
       
   612     XQSERVICE_DEBUG_PRINT("XQServiceRequest::handleSharableFile");
       
   613 
       
   614     bool ret = true;
       
   615     mData->mRequestUtil.mSharableFileArgs.clear();
       
   616     
       
   617     for(int i=0; i < mData->mArguments.size(); i++)
       
   618     {
       
   619         if (QString(mData->mArguments[i].typeName()) == QString("XQSharableFile"))
       
   620         {
       
   621             XQSERVICE_DEBUG_PRINT("XQServiceRequest::sharable file detected");
       
   622             // Pick up the sharable file(s) to utility so that no need to scan any more later
       
   623             XQSharableFile file = mData->mArguments[i].value<XQSharableFile>();
       
   624             if (!file.isValid())
       
   625             {
       
   626                 // No point to pass invalid file handle onwards
       
   627                 XQSERVICE_DEBUG_PRINT("\t Invalid sharable file");
       
   628                 ret = false;
       
   629                 break;
       
   630             }
       
   631             if (mData->mRequestUtil.mSharableFileArgs.count() > 0)
       
   632             {
       
   633                 XQSERVICE_DEBUG_PRINT("\t Too many sharable files");
       
   634                 ret = false;
       
   635                 break;
       
   636             }
       
   637             mData->mRequestUtil.mSharableFileArgs.append(file);
       
   638             XQSERVICE_DEBUG_PRINT("XQServiceRequest::sharable file added");
       
   639         }
       
   640     }
       
   641 
       
   642     if (!ret)
       
   643     {
       
   644         mData->mRequestUtil.mSharableFileArgs.clear();
       
   645     }
       
   646 
       
   647     return ret;
       
   648 }
       
   649 
       
   650 
       
   651 /*!
       
   652     Serializes all the arguments from the service request.
       
   653     \param action Defines the request having arguments to be serialized.
       
   654     \return Serialized arguments in byte array.
       
   655 */
       
   656 QByteArray XQServiceRequest::serializeArguments(const XQServiceRequest &action)
       
   657 {
       
   658     XQSERVICE_DEBUG_PRINT("XQServiceRequest::serializeArguments");
       
   659     QByteArray ret;
       
   660     QBuffer *buffer = new QBuffer(&ret);
       
   661     buffer->open(QIODevice::WriteOnly);
       
   662     QDataStream stream(buffer);
       
   663     stream << action.mData->mArguments;
       
   664 
       
   665     delete buffer;
       
   666     return ret;
       
   667 }
       
   668 /*!
       
   669     Deserializes all the arguments from the byte array to service request.
       
   670     \param action Defines the request where arguments are deserialized.
       
   671     \param data Defines the byte array of serialized arguments.
       
   672 */
       
   673 void XQServiceRequest::deserializeArguments(XQServiceRequest &action,
       
   674         const QByteArray &data)
       
   675 {
       
   676     XQSERVICE_DEBUG_PRINT("XQServiceRequest::deserializeArguments");
       
   677     QDataStream stream(data);
       
   678     stream >> action.mData->mArguments;
       
   679 }
       
   680 
       
   681 /*!
       
   682     Serializes this request to the stream.
       
   683     \param stream Defines stream this request is serialized to.
       
   684 */
       
   685 template <typename Stream> void XQServiceRequest::serialize(Stream &stream) const
       
   686 {
       
   687     XQSERVICE_DEBUG_PRINT("XQServiceRequest::serialize");
       
   688     stream << mData->mArguments;
       
   689     stream << mData->mService;
       
   690     stream << mData->mMessage;
       
   691     stream << mData->mSynchronous;
       
   692 }
       
   693 
       
   694 /*!
       
   695     Deserializes this request from the stream.
       
   696     \param stream Defines the stream this request is deserialized from.
       
   697 */
       
   698 template <typename Stream> void XQServiceRequest::deserialize(Stream &stream)
       
   699 {
       
   700     XQSERVICE_DEBUG_PRINT("XQServiceRequest::deserialize");
       
   701     stream >> mData->mArguments;
       
   702     stream >> mData->mService;
       
   703     stream >> mData->mMessage;
       
   704     stream >> mData->mSynchronous;
       
   705 }
       
   706 
       
   707 Q_IMPLEMENT_USER_METATYPE(XQServiceRequest)