[2] | 1 | /****************************************************************************
|
---|
| 2 | ** $Id: qnetworkprotocol.cpp 8 2005-11-16 19:36:46Z dmik $
|
---|
| 3 | **
|
---|
| 4 | ** Implementation of QNetworkProtocol class
|
---|
| 5 | **
|
---|
| 6 | ** Created : 950429
|
---|
| 7 | **
|
---|
| 8 | ** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
|
---|
| 9 | **
|
---|
| 10 | ** This file is part of the kernel module of the Qt GUI Toolkit.
|
---|
| 11 | **
|
---|
| 12 | ** This file may be distributed under the terms of the Q Public License
|
---|
| 13 | ** as defined by Trolltech AS of Norway and appearing in the file
|
---|
| 14 | ** LICENSE.QPL included in the packaging of this file.
|
---|
| 15 | **
|
---|
| 16 | ** This file may be distributed and/or modified under the terms of the
|
---|
| 17 | ** GNU General Public License version 2 as published by the Free Software
|
---|
| 18 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
| 19 | ** packaging of this file.
|
---|
| 20 | **
|
---|
| 21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
|
---|
| 22 | ** licenses may use this file in accordance with the Qt Commercial License
|
---|
| 23 | ** Agreement provided with the Software.
|
---|
| 24 | **
|
---|
| 25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
---|
| 26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
---|
| 27 | **
|
---|
| 28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
---|
| 29 | ** information about Qt Commercial License Agreements.
|
---|
| 30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information.
|
---|
| 31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
---|
| 32 | **
|
---|
| 33 | ** Contact info@trolltech.com if any conditions of this licensing are
|
---|
| 34 | ** not clear to you.
|
---|
| 35 | **
|
---|
| 36 | **********************************************************************/
|
---|
| 37 |
|
---|
| 38 | #include "qnetworkprotocol.h"
|
---|
| 39 |
|
---|
| 40 | #ifndef QT_NO_NETWORKPROTOCOL
|
---|
| 41 |
|
---|
| 42 | #include "qlocalfs.h"
|
---|
| 43 | #include "qurloperator.h"
|
---|
| 44 | #include "qtimer.h"
|
---|
| 45 | #include "qmap.h"
|
---|
| 46 | #include "qptrqueue.h"
|
---|
| 47 |
|
---|
| 48 | //#define QNETWORKPROTOCOL_DEBUG
|
---|
| 49 | #define NETWORK_OP_DELAY 1000
|
---|
| 50 |
|
---|
| 51 | extern Q_EXPORT QNetworkProtocolDict *qNetworkProtocolRegister;
|
---|
| 52 |
|
---|
| 53 | QNetworkProtocolDict *qNetworkProtocolRegister = 0;
|
---|
| 54 |
|
---|
| 55 | class QNetworkProtocolPrivate
|
---|
| 56 | {
|
---|
| 57 | public:
|
---|
| 58 | QNetworkProtocolPrivate( QNetworkProtocol *p )
|
---|
| 59 | {
|
---|
| 60 | url = 0;
|
---|
| 61 | opInProgress = 0;
|
---|
| 62 | opStartTimer = new QTimer( p );
|
---|
| 63 | removeTimer = new QTimer( p );
|
---|
| 64 | operationQueue.setAutoDelete( FALSE );
|
---|
| 65 | autoDelete = FALSE;
|
---|
| 66 | removeInterval = 10000;
|
---|
| 67 | oldOps.setAutoDelete( FALSE );
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | ~QNetworkProtocolPrivate()
|
---|
| 71 | {
|
---|
| 72 | removeTimer->stop();
|
---|
| 73 | if ( opInProgress ) {
|
---|
| 74 | if ( opInProgress == operationQueue.head() )
|
---|
| 75 | operationQueue.dequeue();
|
---|
| 76 | opInProgress->free();
|
---|
| 77 | }
|
---|
| 78 | while ( operationQueue.head() ) {
|
---|
| 79 | operationQueue.head()->free();
|
---|
| 80 | operationQueue.dequeue();
|
---|
| 81 | }
|
---|
| 82 | while ( oldOps.first() ) {
|
---|
| 83 | oldOps.first()->free();
|
---|
| 84 | oldOps.removeFirst();
|
---|
| 85 | }
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | QUrlOperator *url;
|
---|
| 89 | QPtrQueue< QNetworkOperation > operationQueue;
|
---|
| 90 | QNetworkOperation *opInProgress;
|
---|
| 91 | QTimer *opStartTimer, *removeTimer;
|
---|
| 92 | int removeInterval;
|
---|
| 93 | bool autoDelete;
|
---|
| 94 | QPtrList< QNetworkOperation > oldOps;
|
---|
| 95 | };
|
---|
| 96 |
|
---|
| 97 | /*!
|
---|
| 98 | \class QNetworkProtocol qnetworkprotocol.h
|
---|
| 99 | \brief The QNetworkProtocol class provides a common API for network protocols.
|
---|
| 100 | \if defined(commercial)
|
---|
| 101 | It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
|
---|
| 102 | \endif
|
---|
| 103 |
|
---|
| 104 | \module network
|
---|
| 105 | \ingroup io
|
---|
| 106 | \module network
|
---|
| 107 | \mainclass
|
---|
| 108 |
|
---|
| 109 | This is a base class which should be used for network protocols
|
---|
| 110 | implementations that can then be used in Qt (e.g. in the file
|
---|
| 111 | dialog) together with the QUrlOperator.
|
---|
| 112 |
|
---|
| 113 | The easiest way to implement a new network protocol is to
|
---|
| 114 | reimplement the operation*() methods, e.g. operationGet(), etc.
|
---|
| 115 | Only the supported operations should be reimplemented. To specify
|
---|
| 116 | which operations are supported, also reimplement
|
---|
| 117 | supportedOperations() and return an int that is OR'd together
|
---|
| 118 | using the supported operations from the \l
|
---|
| 119 | QNetworkProtocol::Operation enum.
|
---|
| 120 |
|
---|
| 121 | When you implement a network protocol this way, it is important to
|
---|
| 122 | emit the correct signals. Also, always emit the finished() signal
|
---|
| 123 | when an operation is done (on success \e and on failure). Qt
|
---|
| 124 | relies on correctly emitted finished() signals.
|
---|
| 125 |
|
---|
| 126 | For a detailed description of the Qt Network Architecture and how
|
---|
| 127 | to implement and use network protocols in Qt, see the \link
|
---|
| 128 | network.html Qt Network Documentation\endlink.
|
---|
| 129 | */
|
---|
| 130 |
|
---|
| 131 | /*!
|
---|
| 132 | \fn void QNetworkProtocol::newChildren( const QValueList<QUrlInfo> &i, QNetworkOperation *op )
|
---|
| 133 |
|
---|
| 134 | This signal is emitted after listChildren() was called and new
|
---|
| 135 | children (files) have been read from the list of files. \a i holds
|
---|
| 136 | the information about the new children. \a op is the pointer to
|
---|
| 137 | the operation object which contains all the information about the
|
---|
| 138 | operation, including the state, etc.
|
---|
| 139 |
|
---|
| 140 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 141 | enough to let the QUrlOperator, which is used by the network
|
---|
| 142 | protocol, emit its corresponding signal.
|
---|
| 143 |
|
---|
| 144 | When implementing your own network protocol and reading children,
|
---|
| 145 | you usually don't read one child at once, but rather a list of
|
---|
| 146 | them. That's why this signal takes a list of QUrlInfo objects. If
|
---|
| 147 | you prefer to read just one child at a time you can use the
|
---|
| 148 | convenience signal newChild(), which takes a single QUrlInfo
|
---|
| 149 | object.
|
---|
| 150 | */
|
---|
| 151 |
|
---|
| 152 | /*!
|
---|
| 153 | \fn void QNetworkProtocol::newChild( const QUrlInfo &i, QNetworkOperation *op )
|
---|
| 154 |
|
---|
| 155 | This signal is emitted if a new child (file) has been read.
|
---|
| 156 | QNetworkProtocol automatically connects it to a slot which creates
|
---|
| 157 | a list of QUrlInfo objects (with just one QUrlInfo \a i) and emits
|
---|
| 158 | the newChildren() signal with this list. \a op is the pointer to
|
---|
| 159 | the operation object which contains all the information about the
|
---|
| 160 | operation that has finished, including the state, etc.
|
---|
| 161 |
|
---|
| 162 | This is just a convenience signal useful for implementing your own
|
---|
| 163 | network protocol. In all other cases connect to the newChildren()
|
---|
| 164 | signal with its list of QUrlInfo objects.
|
---|
| 165 | */
|
---|
| 166 |
|
---|
| 167 | /*!
|
---|
| 168 | \fn void QNetworkProtocol::finished( QNetworkOperation *op )
|
---|
| 169 |
|
---|
| 170 | This signal is emitted when an operation finishes. This signal is
|
---|
| 171 | always emitted, for both success and failure. \a op is the pointer
|
---|
| 172 | to the operation object which contains all the information about
|
---|
| 173 | the operation, including the state, etc. Check the state and error
|
---|
| 174 | code of the operation object to determine whether or not the
|
---|
| 175 | operation was successful.
|
---|
| 176 |
|
---|
| 177 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 178 | enough to let the QUrlOperator, which is used by the network
|
---|
| 179 | protocol, emit its corresponding signal.
|
---|
| 180 | */
|
---|
| 181 |
|
---|
| 182 | /*!
|
---|
| 183 | \fn void QNetworkProtocol::start( QNetworkOperation *op )
|
---|
| 184 |
|
---|
| 185 | Some operations (such as listChildren()) emit this signal when
|
---|
| 186 | they start processing the operation. \a op is the pointer to the
|
---|
| 187 | operation object which contains all the information about the
|
---|
| 188 | operation, including the state, etc.
|
---|
| 189 |
|
---|
| 190 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 191 | enough to let the QUrlOperator, which is used by the network
|
---|
| 192 | protocol, emit its corresponding signal.
|
---|
| 193 | */
|
---|
| 194 |
|
---|
| 195 | /*!
|
---|
| 196 | \fn void QNetworkProtocol::createdDirectory( const QUrlInfo &i, QNetworkOperation *op )
|
---|
| 197 |
|
---|
| 198 | This signal is emitted when mkdir() has been succesful and the
|
---|
| 199 | directory has been created. \a i holds the information about the
|
---|
| 200 | new directory. \a op is the pointer to the operation object which
|
---|
| 201 | contains all the information about the operation, including the
|
---|
| 202 | state, etc. Using op->arg( 0 ), you can get the file name of the
|
---|
| 203 | new directory.
|
---|
| 204 |
|
---|
| 205 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 206 | enough to let the QUrlOperator, which is used by the network
|
---|
| 207 | protocol, emit its corresponding signal.
|
---|
| 208 | */
|
---|
| 209 |
|
---|
| 210 | /*!
|
---|
| 211 | \fn void QNetworkProtocol::removed( QNetworkOperation *op )
|
---|
| 212 |
|
---|
| 213 | This signal is emitted when remove() has been succesful and the
|
---|
| 214 | file has been removed. \a op holds the file name of the removed
|
---|
| 215 | file in the first argument, accessible with op->arg( 0 ). \a op is
|
---|
| 216 | the pointer to the operation object which contains all the
|
---|
| 217 | information about the operation, including the state, etc.
|
---|
| 218 |
|
---|
| 219 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 220 | enough to let the QUrlOperator, which is used by the network
|
---|
| 221 | protocol, emit its corresponding signal.
|
---|
| 222 | */
|
---|
| 223 |
|
---|
| 224 | /*!
|
---|
| 225 | \fn void QNetworkProtocol::itemChanged( QNetworkOperation *op )
|
---|
| 226 |
|
---|
| 227 | This signal is emitted whenever a file which is a child of this
|
---|
| 228 | URL has been changed, e.g. by successfully calling rename(). \a op
|
---|
| 229 | holds the original and the new file names in the first and second
|
---|
| 230 | arguments, accessible with op->arg( 0 ) and op->arg( 1 )
|
---|
| 231 | respectively. \a op is the pointer to the operation object which
|
---|
| 232 | contains all the information about the operation, including the
|
---|
| 233 | state, etc.
|
---|
| 234 |
|
---|
| 235 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 236 | enough to let the QUrlOperator, which is used by the network
|
---|
| 237 | protocol, emit its corresponding signal.
|
---|
| 238 | */
|
---|
| 239 |
|
---|
| 240 | /*!
|
---|
| 241 | \fn void QNetworkProtocol::data( const QByteArray &data,
|
---|
| 242 | QNetworkOperation *op )
|
---|
| 243 |
|
---|
| 244 | This signal is emitted when new \a data has been received after
|
---|
| 245 | calling get() or put(). \a op holds the name of the file from
|
---|
| 246 | which data is retrieved or uploaded in its first argument, and the
|
---|
| 247 | (raw) data in its second argument. You can get them with
|
---|
| 248 | op->arg( 0 ) and op->rawArg( 1 ). \a op is the pointer to the
|
---|
| 249 | operation object, which contains all the information about the
|
---|
| 250 | operation, including the state, etc.
|
---|
| 251 |
|
---|
| 252 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 253 | enough to let the QUrlOperator (which is used by the network
|
---|
| 254 | protocol) emit its corresponding signal.
|
---|
| 255 | */
|
---|
| 256 |
|
---|
| 257 | /*!
|
---|
| 258 | \fn void QNetworkProtocol::dataTransferProgress( int bytesDone, int bytesTotal, QNetworkOperation *op )
|
---|
| 259 |
|
---|
| 260 | This signal is emitted during the transfer of data (using put() or
|
---|
| 261 | get()). \a bytesDone is how many bytes of \a bytesTotal have been
|
---|
| 262 | transferred. \a bytesTotal may be -1, which means that the total
|
---|
| 263 | number of bytes is not known. \a op is the pointer to the
|
---|
| 264 | operation object which contains all the information about the
|
---|
| 265 | operation, including the state, etc.
|
---|
| 266 |
|
---|
| 267 | When a protocol emits this signal, QNetworkProtocol is smart
|
---|
| 268 | enough to let the QUrlOperator, which is used by the network
|
---|
| 269 | protocol, emit its corresponding signal.
|
---|
| 270 | */
|
---|
| 271 |
|
---|
| 272 | /*!
|
---|
| 273 | \fn void QNetworkProtocol::connectionStateChanged( int state, const QString &data )
|
---|
| 274 |
|
---|
| 275 | This signal is emitted whenever the state of the connection of the
|
---|
| 276 | network protocol is changed. \a state describes the new state,
|
---|
| 277 | which is one of, \c ConHostFound, \c ConConnected or \c ConClosed.
|
---|
| 278 | \a data is a message text.
|
---|
| 279 | */
|
---|
| 280 |
|
---|
| 281 | /*!
|
---|
| 282 | \enum QNetworkProtocol::State
|
---|
| 283 |
|
---|
| 284 | This enum contains the state that a QNetworkOperation can have.
|
---|
| 285 |
|
---|
| 286 | \value StWaiting The operation is in the QNetworkProtocol's queue
|
---|
| 287 | waiting to be prcessed.
|
---|
| 288 |
|
---|
| 289 | \value StInProgress The operation is being processed.
|
---|
| 290 |
|
---|
| 291 | \value StDone The operation has been processed succesfully.
|
---|
| 292 |
|
---|
| 293 | \value StFailed The operation has been processed but an error occurred.
|
---|
| 294 |
|
---|
| 295 | \value StStopped The operation has been processed but has been
|
---|
| 296 | stopped before it finished, and is waiting to be processed.
|
---|
| 297 |
|
---|
| 298 | */
|
---|
| 299 |
|
---|
| 300 | /*!
|
---|
| 301 | \enum QNetworkProtocol::Operation
|
---|
| 302 |
|
---|
| 303 | This enum lists the possible operations that a network protocol
|
---|
| 304 | can support. supportedOperations() returns an int of these that is
|
---|
| 305 | OR'd together. Also, the type() of a QNetworkOperation is always
|
---|
| 306 | one of these values.
|
---|
| 307 |
|
---|
| 308 | \value OpListChildren List the children of a URL, e.g. of a directory.
|
---|
| 309 | \value OpMkDir Create a directory.
|
---|
| 310 | \value OpRemove Remove a child (e.g. a file).
|
---|
| 311 | \value OpRename Rename a child (e.g. a file).
|
---|
| 312 | \value OpGet Get data from a location.
|
---|
| 313 | \value OpPut Put data to a location.
|
---|
| 314 | */
|
---|
| 315 |
|
---|
| 316 | /*!
|
---|
| 317 | \enum QNetworkProtocol::ConnectionState
|
---|
| 318 |
|
---|
| 319 | When the connection state of a network protocol changes it emits
|
---|
| 320 | the signal connectionStateChanged(). The first argument is one of
|
---|
| 321 | the following values:
|
---|
| 322 |
|
---|
| 323 | \value ConHostFound Host has been found.
|
---|
| 324 | \value ConConnected Connection to the host has been established.
|
---|
| 325 | \value ConClosed Connection has been closed.
|
---|
| 326 | */
|
---|
| 327 |
|
---|
| 328 | /*!
|
---|
| 329 | \enum QNetworkProtocol::Error
|
---|
| 330 |
|
---|
| 331 | When an operation fails (finishes unsuccessfully), the
|
---|
| 332 | QNetworkOperation of the operation returns an error code which has
|
---|
| 333 | one of the following values:
|
---|
| 334 |
|
---|
| 335 | \value NoError No error occurred.
|
---|
| 336 |
|
---|
| 337 | \value ErrValid The URL you are operating on is not valid.
|
---|
| 338 |
|
---|
| 339 | \value ErrUnknownProtocol There is no protocol implementation
|
---|
| 340 | available for the protocol of the URL you are operating on (e.g.
|
---|
| 341 | if the protocol is http and no http implementation has been
|
---|
| 342 | registered).
|
---|
| 343 |
|
---|
| 344 | \value ErrUnsupported The operation is not supported by the
|
---|
| 345 | protocol.
|
---|
| 346 |
|
---|
| 347 | \value ErrParse The URL could not be parsed correctly.
|
---|
| 348 |
|
---|
| 349 | \value ErrLoginIncorrect You needed to login but the username
|
---|
| 350 | or password is wrong.
|
---|
| 351 |
|
---|
| 352 | \value ErrHostNotFound The specified host (in the URL) couldn't
|
---|
| 353 | be found.
|
---|
| 354 |
|
---|
| 355 | \value ErrListChildren An error occurred while listing the
|
---|
| 356 | children (files).
|
---|
| 357 |
|
---|
| 358 | \value ErrMkDir An error occurred when creating a directory.
|
---|
| 359 |
|
---|
| 360 | \value ErrRemove An error occurred when removing a child (file).
|
---|
| 361 |
|
---|
| 362 | \value ErrRename An error occurred when renaming a child (file).
|
---|
| 363 |
|
---|
| 364 | \value ErrGet An error occurred while getting (retrieving) data.
|
---|
| 365 |
|
---|
| 366 | \value ErrPut An error occurred while putting (uploading) data.
|
---|
| 367 |
|
---|
| 368 | \value ErrFileNotExisting A file which is needed by the operation
|
---|
| 369 | doesn't exist.
|
---|
| 370 |
|
---|
| 371 | \value ErrPermissionDenied Permission for doing the operation has
|
---|
| 372 | been denied.
|
---|
| 373 |
|
---|
| 374 | You should also use these error codes when implementing custom
|
---|
| 375 | network protocols. If this is not possible, you can define your own
|
---|
| 376 | error codes by using integer values that don't conflict with any
|
---|
| 377 | of these values.
|
---|
| 378 | */
|
---|
| 379 |
|
---|
| 380 | /*!
|
---|
| 381 | Constructor of the network protocol base class. Does some
|
---|
| 382 | initialization and connecting of signals and slots.
|
---|
| 383 | */
|
---|
| 384 |
|
---|
| 385 | QNetworkProtocol::QNetworkProtocol()
|
---|
| 386 | : QObject()
|
---|
| 387 | {
|
---|
| 388 | d = new QNetworkProtocolPrivate( this );
|
---|
| 389 |
|
---|
| 390 | connect( d->opStartTimer, SIGNAL( timeout() ),
|
---|
| 391 | this, SLOT( startOps() ) );
|
---|
| 392 | connect( d->removeTimer, SIGNAL( timeout() ),
|
---|
| 393 | this, SLOT( removeMe() ) );
|
---|
| 394 |
|
---|
| 395 | if ( url() ) {
|
---|
| 396 | connect( this, SIGNAL( data(const QByteArray&,QNetworkOperation*) ),
|
---|
| 397 | url(), SIGNAL( data(const QByteArray&,QNetworkOperation*) ) );
|
---|
| 398 | connect( this, SIGNAL( finished(QNetworkOperation*) ),
|
---|
| 399 | url(), SIGNAL( finished(QNetworkOperation*) ) );
|
---|
| 400 | connect( this, SIGNAL( start(QNetworkOperation*) ),
|
---|
| 401 | url(), SIGNAL( start(QNetworkOperation*) ) );
|
---|
| 402 | connect( this, SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ),
|
---|
| 403 | url(), SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ) );
|
---|
| 404 | connect( this, SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ),
|
---|
| 405 | url(), SLOT( addEntry(const QValueList<QUrlInfo>&) ) );
|
---|
| 406 | connect( this, SIGNAL( createdDirectory(const QUrlInfo&,QNetworkOperation*) ),
|
---|
| 407 | url(), SIGNAL( createdDirectory(const QUrlInfo&,QNetworkOperation*) ) );
|
---|
| 408 | connect( this, SIGNAL( removed(QNetworkOperation*) ),
|
---|
| 409 | url(), SIGNAL( removed(QNetworkOperation*) ) );
|
---|
| 410 | connect( this, SIGNAL( itemChanged(QNetworkOperation*) ),
|
---|
| 411 | url(), SIGNAL( itemChanged(QNetworkOperation*) ) );
|
---|
| 412 | connect( this, SIGNAL( dataTransferProgress(int,int,QNetworkOperation*) ),
|
---|
| 413 | url(), SIGNAL( dataTransferProgress(int,int,QNetworkOperation*) ) );
|
---|
| 414 | connect( this, SIGNAL( connectionStateChanged(int,const QString&) ),
|
---|
| 415 | url(), SIGNAL( connectionStateChanged(int,const QString&) ) );
|
---|
| 416 | }
|
---|
| 417 |
|
---|
| 418 | connect( this, SIGNAL( finished(QNetworkOperation*) ),
|
---|
| 419 | this, SLOT( processNextOperation(QNetworkOperation*) ) );
|
---|
| 420 | connect( this, SIGNAL( newChild(const QUrlInfo&,QNetworkOperation*) ),
|
---|
| 421 | this, SLOT( emitNewChildren(const QUrlInfo&,QNetworkOperation*) ) );
|
---|
| 422 |
|
---|
| 423 | }
|
---|
| 424 |
|
---|
| 425 | /*!
|
---|
| 426 | Destructor.
|
---|
| 427 | */
|
---|
| 428 |
|
---|
| 429 | QNetworkProtocol::~QNetworkProtocol()
|
---|
| 430 | {
|
---|
[8] | 431 | QNetworkOperation *op = d->opInProgress;
|
---|
| 432 | if ( op ) {
|
---|
| 433 | op->setState( StStopped );
|
---|
| 434 | op->setProtocolDetail( tr( "Operation stopped by the user" ) );
|
---|
| 435 | emit finished( op );
|
---|
| 436 | // op->free() will be called by QNetworkOperationPrivate dtor below
|
---|
| 437 | }
|
---|
[2] | 438 | delete d;
|
---|
| 439 | }
|
---|
| 440 |
|
---|
| 441 | /*!
|
---|
| 442 | Sets the QUrlOperator, on which the protocol works, to \a u.
|
---|
| 443 |
|
---|
| 444 | \sa QUrlOperator
|
---|
| 445 | */
|
---|
| 446 |
|
---|
| 447 | void QNetworkProtocol::setUrl( QUrlOperator *u )
|
---|
| 448 | {
|
---|
| 449 | if ( url() ) {
|
---|
| 450 | disconnect( this, SIGNAL( data(const QByteArray&,QNetworkOperation*) ),
|
---|
| 451 | url(), SIGNAL( data(const QByteArray&,QNetworkOperation*) ) );
|
---|
| 452 | disconnect( this, SIGNAL( finished(QNetworkOperation*) ),
|
---|
| 453 | url(), SIGNAL( finished(QNetworkOperation*) ) );
|
---|
| 454 | disconnect( this, SIGNAL( start(QNetworkOperation*) ),
|
---|
| 455 | url(), SIGNAL( start(QNetworkOperation*) ) );
|
---|
| 456 | disconnect( this, SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ),
|
---|
| 457 | url(), SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ) );
|
---|
| 458 | disconnect( this, SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ),
|
---|
| 459 | url(), SLOT( addEntry(const QValueList<QUrlInfo>&) ) );
|
---|
| 460 | disconnect( this, SIGNAL( createdDirectory(const QUrlInfo&,QNetworkOperation*) ),
|
---|
| 461 | url(), SIGNAL( createdDirectory(const QUrlInfo&,QNetworkOperation*) ) );
|
---|
| 462 | disconnect( this, SIGNAL( removed(QNetworkOperation*) ),
|
---|
| 463 | url(), SIGNAL( removed(QNetworkOperation*) ) );
|
---|
| 464 | disconnect( this, SIGNAL( itemChanged(QNetworkOperation*) ),
|
---|
| 465 | url(), SIGNAL( itemChanged(QNetworkOperation*) ) );
|
---|
| 466 | disconnect( this, SIGNAL( dataTransferProgress(int,int,QNetworkOperation*) ),
|
---|
| 467 | url(), SIGNAL( dataTransferProgress(int,int,QNetworkOperation*) ) );
|
---|
| 468 | disconnect( this, SIGNAL( connectionStateChanged(int,const QString&) ),
|
---|
| 469 | url(), SIGNAL( connectionStateChanged(int,const QString&) ) );
|
---|
| 470 | }
|
---|
| 471 |
|
---|
| 472 |
|
---|
| 473 | // ### if autoDelete is TRUE, we should delete the QUrlOperator (something
|
---|
| 474 | // like below; but that is not possible since it would delete this, too).
|
---|
| 475 | //if ( d->autoDelete && (d->url!=u) ) {
|
---|
| 476 | // delete d->url; // destructor deletes the network protocol
|
---|
| 477 | //}
|
---|
| 478 | d->url = u;
|
---|
| 479 |
|
---|
| 480 | if ( url() ) {
|
---|
| 481 | connect( this, SIGNAL( data(const QByteArray&,QNetworkOperation*) ),
|
---|
| 482 | url(), SIGNAL( data(const QByteArray&,QNetworkOperation*) ) );
|
---|
| 483 | connect( this, SIGNAL( finished(QNetworkOperation*) ),
|
---|
| 484 | url(), SIGNAL( finished(QNetworkOperation*) ) );
|
---|
| 485 | connect( this, SIGNAL( start(QNetworkOperation*) ),
|
---|
| 486 | url(), SIGNAL( start(QNetworkOperation*) ) );
|
---|
| 487 | connect( this, SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ),
|
---|
| 488 | url(), SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ) );
|
---|
| 489 | connect( this, SIGNAL( newChildren(const QValueList<QUrlInfo>&,QNetworkOperation*) ),
|
---|
| 490 | url(), SLOT( addEntry(const QValueList<QUrlInfo>&) ) );
|
---|
| 491 | connect( this, SIGNAL( createdDirectory(const QUrlInfo&,QNetworkOperation*) ),
|
---|
| 492 | url(), SIGNAL( createdDirectory(const QUrlInfo&,QNetworkOperation*) ) );
|
---|
| 493 | connect( this, SIGNAL( removed(QNetworkOperation*) ),
|
---|
| 494 | url(), SIGNAL( removed(QNetworkOperation*) ) );
|
---|
| 495 | connect( this, SIGNAL( itemChanged(QNetworkOperation*) ),
|
---|
| 496 | url(), SIGNAL( itemChanged(QNetworkOperation*) ) );
|
---|
| 497 | connect( this, SIGNAL( dataTransferProgress(int,int,QNetworkOperation*) ),
|
---|
| 498 | url(), SIGNAL( dataTransferProgress(int,int,QNetworkOperation*) ) );
|
---|
| 499 | connect( this, SIGNAL( connectionStateChanged(int,const QString&) ),
|
---|
| 500 | url(), SIGNAL( connectionStateChanged(int,const QString&) ) );
|
---|
| 501 | }
|
---|
| 502 |
|
---|
| 503 | if ( !d->opInProgress && !d->operationQueue.isEmpty() )
|
---|
| 504 | d->opStartTimer->start( 0, TRUE );
|
---|
| 505 | }
|
---|
| 506 |
|
---|
| 507 | /*!
|
---|
| 508 | For processing operations the network protocol base class calls
|
---|
| 509 | this method quite often. This should be reimplemented by new
|
---|
| 510 | network protocols. It should return TRUE if the connection is OK
|
---|
| 511 | (open); otherwise it should return FALSE. If the connection is not
|
---|
| 512 | open the protocol should open it.
|
---|
| 513 |
|
---|
| 514 | If the connection can't be opened (e.g. because you already tried
|
---|
| 515 | but the host couldn't be found), set the state of \a op to
|
---|
| 516 | QNetworkProtocol::StFailed and emit the finished() signal with
|
---|
| 517 | this QNetworkOperation as argument.
|
---|
| 518 |
|
---|
| 519 | \a op is the operation that needs an open connection.
|
---|
| 520 | */
|
---|
| 521 |
|
---|
| 522 | bool QNetworkProtocol::checkConnection( QNetworkOperation * )
|
---|
| 523 | {
|
---|
| 524 | return TRUE;
|
---|
| 525 | }
|
---|
| 526 |
|
---|
| 527 | /*!
|
---|
| 528 | Returns an int that is OR'd together using the enum values of
|
---|
| 529 | \l{QNetworkProtocol::Operation}, which describes which operations
|
---|
| 530 | are supported by the network protocol. Should be reimplemented by
|
---|
| 531 | new network protocols.
|
---|
| 532 | */
|
---|
| 533 |
|
---|
| 534 | int QNetworkProtocol::supportedOperations() const
|
---|
| 535 | {
|
---|
| 536 | return 0;
|
---|
| 537 | }
|
---|
| 538 |
|
---|
| 539 | /*!
|
---|
| 540 | Adds the operation \a op to the operation queue. The operation
|
---|
| 541 | will be processed as soon as possible. This method returns
|
---|
| 542 | immediately.
|
---|
| 543 | */
|
---|
| 544 |
|
---|
| 545 | void QNetworkProtocol::addOperation( QNetworkOperation *op )
|
---|
| 546 | {
|
---|
| 547 | #ifdef QNETWORKPROTOCOL_DEBUG
|
---|
| 548 | qDebug( "QNetworkOperation: addOperation: %p %d", op, op->operation() );
|
---|
| 549 | #endif
|
---|
| 550 | d->operationQueue.enqueue( op );
|
---|
| 551 | if ( !d->opInProgress )
|
---|
| 552 | d->opStartTimer->start( 0, TRUE );
|
---|
| 553 | }
|
---|
| 554 |
|
---|
| 555 | /*!
|
---|
| 556 | Static method to register a network protocol for Qt. For example,
|
---|
| 557 | if you have an implementation of NNTP (called Nntp) which is
|
---|
| 558 | derived from QNetworkProtocol, call:
|
---|
| 559 | \code
|
---|
| 560 | QNetworkProtocol::registerNetworkProtocol( "nntp", new QNetworkProtocolFactory<Nntp> );
|
---|
| 561 | \endcode
|
---|
| 562 | after which your implementation is registered for future nntp
|
---|
| 563 | operations.
|
---|
| 564 |
|
---|
| 565 | The name of the protocol is given in \a protocol and a pointer to
|
---|
| 566 | the protocol factory is given in \a protocolFactory.
|
---|
| 567 | */
|
---|
| 568 |
|
---|
| 569 | void QNetworkProtocol::registerNetworkProtocol( const QString &protocol,
|
---|
| 570 | QNetworkProtocolFactoryBase *protocolFactory )
|
---|
| 571 | {
|
---|
| 572 | if ( !qNetworkProtocolRegister ) {
|
---|
| 573 | qNetworkProtocolRegister = new QNetworkProtocolDict;
|
---|
| 574 | QNetworkProtocol::registerNetworkProtocol( "file", new QNetworkProtocolFactory< QLocalFs > );
|
---|
| 575 | }
|
---|
| 576 |
|
---|
| 577 | qNetworkProtocolRegister->insert( protocol, protocolFactory );
|
---|
| 578 | }
|
---|
| 579 |
|
---|
| 580 | /*!
|
---|
| 581 | Static method to get a new instance of the network protocol \a
|
---|
| 582 | protocol. For example, if you need to do some FTP operations, do
|
---|
| 583 | the following:
|
---|
| 584 | \code
|
---|
| 585 | QFtp *ftp = QNetworkProtocol::getNetworkProtocol( "ftp" );
|
---|
| 586 | \endcode
|
---|
| 587 | This returns a pointer to a new instance of an ftp implementation
|
---|
| 588 | or null if no protocol for ftp was registered. The ownership of
|
---|
| 589 | the pointer is transferred to you, so you must delete it if you
|
---|
| 590 | don't need it anymore.
|
---|
| 591 |
|
---|
| 592 | Normally you should not work directly with network protocols, so
|
---|
| 593 | you will not need to call this method yourself. Instead, use
|
---|
| 594 | QUrlOperator, which makes working with network protocols much more
|
---|
| 595 | convenient.
|
---|
| 596 |
|
---|
| 597 | \sa QUrlOperator
|
---|
| 598 | */
|
---|
| 599 |
|
---|
| 600 | QNetworkProtocol *QNetworkProtocol::getNetworkProtocol( const QString &protocol )
|
---|
| 601 | {
|
---|
| 602 | if ( !qNetworkProtocolRegister ) {
|
---|
| 603 | qNetworkProtocolRegister = new QNetworkProtocolDict;
|
---|
| 604 | QNetworkProtocol::registerNetworkProtocol( "file", new QNetworkProtocolFactory< QLocalFs > );
|
---|
| 605 | }
|
---|
| 606 |
|
---|
| 607 | if ( protocol.isNull() )
|
---|
| 608 | return 0;
|
---|
| 609 |
|
---|
| 610 | QNetworkProtocolFactoryBase *factory = qNetworkProtocolRegister->find( protocol );
|
---|
| 611 | if ( factory )
|
---|
| 612 | return factory->createObject();
|
---|
| 613 |
|
---|
| 614 | return 0;
|
---|
| 615 | }
|
---|
| 616 |
|
---|
| 617 | /*!
|
---|
| 618 | Returns TRUE if the only protocol registered is for working on the
|
---|
| 619 | local filesystem; returns FALSE if other network protocols are
|
---|
| 620 | also registered.
|
---|
| 621 | */
|
---|
| 622 |
|
---|
| 623 | bool QNetworkProtocol::hasOnlyLocalFileSystem()
|
---|
| 624 | {
|
---|
| 625 | if ( !qNetworkProtocolRegister )
|
---|
| 626 | return FALSE;
|
---|
| 627 |
|
---|
| 628 | QDictIterator< QNetworkProtocolFactoryBase > it( *qNetworkProtocolRegister );
|
---|
| 629 | for ( ; it.current(); ++it )
|
---|
| 630 | if ( it.currentKey() != "file" )
|
---|
| 631 | return FALSE;
|
---|
| 632 | return TRUE;
|
---|
| 633 | }
|
---|
| 634 |
|
---|
| 635 | /*!
|
---|
| 636 | \internal
|
---|
| 637 | Starts processing network operations.
|
---|
| 638 | */
|
---|
| 639 |
|
---|
| 640 | void QNetworkProtocol::startOps()
|
---|
| 641 | {
|
---|
| 642 | #ifdef QNETWORKPROTOCOL_DEBUG
|
---|
| 643 | qDebug( "QNetworkOperation: start processing operations" );
|
---|
| 644 | #endif
|
---|
| 645 | processNextOperation( 0 );
|
---|
| 646 | }
|
---|
| 647 |
|
---|
| 648 | /*!
|
---|
| 649 | \internal
|
---|
| 650 | Processes the operation \a op. It calls the
|
---|
| 651 | corresponding operation[something]( QNetworkOperation * )
|
---|
| 652 | methods.
|
---|
| 653 | */
|
---|
| 654 |
|
---|
| 655 | void QNetworkProtocol::processOperation( QNetworkOperation *op )
|
---|
| 656 | {
|
---|
| 657 | if ( !op )
|
---|
| 658 | return;
|
---|
| 659 |
|
---|
| 660 | switch ( op->operation() ) {
|
---|
| 661 | case OpListChildren:
|
---|
| 662 | operationListChildren( op );
|
---|
| 663 | break;
|
---|
| 664 | case OpMkDir:
|
---|
| 665 | operationMkDir( op );
|
---|
| 666 | break;
|
---|
| 667 | case OpRemove:
|
---|
| 668 | operationRemove( op );
|
---|
| 669 | break;
|
---|
| 670 | case OpRename:
|
---|
| 671 | operationRename( op );
|
---|
| 672 | break;
|
---|
| 673 | case OpGet:
|
---|
| 674 | operationGet( op );
|
---|
| 675 | break;
|
---|
| 676 | case OpPut:
|
---|
| 677 | operationPut( op );
|
---|
| 678 | break;
|
---|
| 679 | }
|
---|
| 680 | }
|
---|
| 681 |
|
---|
| 682 | /*!
|
---|
| 683 | When implementing a new network protocol, this method should be
|
---|
| 684 | reimplemented if the protocol supports listing children (files);
|
---|
| 685 | this method should then process this QNetworkOperation.
|
---|
| 686 |
|
---|
| 687 | When you reimplement this method it's very important that you emit
|
---|
| 688 | the correct signals at the correct time (especially the finished()
|
---|
| 689 | signal after processing an operation). Take a look at the \link
|
---|
| 690 | network.html Qt Network Documentation\endlink which describes in
|
---|
| 691 | detail how to reimplement this method. You may also want to look
|
---|
| 692 | at the example implementation in
|
---|
| 693 | examples/network/networkprotocol/nntp.cpp.
|
---|
| 694 |
|
---|
| 695 | \a op is the pointer to the operation object which contains all
|
---|
| 696 | the information on the operation that has finished, including the
|
---|
| 697 | state, etc.
|
---|
| 698 | */
|
---|
| 699 |
|
---|
| 700 | void QNetworkProtocol::operationListChildren( QNetworkOperation * )
|
---|
| 701 | {
|
---|
| 702 | }
|
---|
| 703 |
|
---|
| 704 | /*!
|
---|
| 705 | When implementing a new network protocol, this method should be
|
---|
| 706 | reimplemented if the protocol supports making directories; this
|
---|
| 707 | method should then process this QNetworkOperation.
|
---|
| 708 |
|
---|
| 709 | When you reimplement this method it's very important that you emit
|
---|
| 710 | the correct signals at the correct time (especially the finished()
|
---|
| 711 | signal after processing an operation). Take a look at the \link
|
---|
| 712 | network.html Qt Network Documentation\endlink which describes in
|
---|
| 713 | detail how to reimplement this method. You may also want to look
|
---|
| 714 | at the example implementation in
|
---|
| 715 | examples/network/networkprotocol/nntp.cpp.
|
---|
| 716 |
|
---|
| 717 | \a op is the pointer to the operation object which contains all
|
---|
| 718 | the information on the operation that has finished, including the
|
---|
| 719 | state, etc.
|
---|
| 720 | */
|
---|
| 721 |
|
---|
| 722 | void QNetworkProtocol::operationMkDir( QNetworkOperation * )
|
---|
| 723 | {
|
---|
| 724 | }
|
---|
| 725 |
|
---|
| 726 | /*!
|
---|
| 727 | When implementing a new network protocol, this method should be
|
---|
| 728 | reimplemented if the protocol supports removing children (files);
|
---|
| 729 | this method should then process this QNetworkOperation.
|
---|
| 730 |
|
---|
| 731 | When you reimplement this method it's very important that you emit
|
---|
| 732 | the correct signals at the correct time (especially the finished()
|
---|
| 733 | signal after processing an operation). Take a look at the \link
|
---|
| 734 | network.html Qt Network Documentation\endlink which is describes
|
---|
| 735 | in detail how to reimplement this method. You may also want to
|
---|
| 736 | look at the example implementation in
|
---|
| 737 | examples/network/networkprotocol/nntp.cpp.
|
---|
| 738 |
|
---|
| 739 | \a op is the pointer to the operation object which contains all
|
---|
| 740 | the information on the operation that has finished, including the
|
---|
| 741 | state, etc.
|
---|
| 742 | */
|
---|
| 743 |
|
---|
| 744 | void QNetworkProtocol::operationRemove( QNetworkOperation * )
|
---|
| 745 | {
|
---|
| 746 | }
|
---|
| 747 |
|
---|
| 748 | /*!
|
---|
| 749 | When implementing a new newtork protocol, this method should be
|
---|
| 750 | reimplemented if the protocol supports renaming children (files);
|
---|
| 751 | this method should then process this QNetworkOperation.
|
---|
| 752 |
|
---|
| 753 | When you reimplement this method it's very important that you emit
|
---|
| 754 | the correct signals at the correct time (especially the finished()
|
---|
| 755 | signal after processing an operation). Take a look at the \link
|
---|
| 756 | network.html Qt Network Documentation\endlink which describes in
|
---|
| 757 | detail how to reimplement this method. You may also want to look
|
---|
| 758 | at the example implementation in
|
---|
| 759 | examples/network/networkprotocol/nntp.cpp.
|
---|
| 760 |
|
---|
| 761 | \a op is the pointer to the operation object which contains all
|
---|
| 762 | the information on the operation that has finished, including the
|
---|
| 763 | state, etc.
|
---|
| 764 | */
|
---|
| 765 |
|
---|
| 766 | void QNetworkProtocol::operationRename( QNetworkOperation * )
|
---|
| 767 | {
|
---|
| 768 | }
|
---|
| 769 |
|
---|
| 770 | /*!
|
---|
| 771 | When implementing a new network protocol, this method should be
|
---|
| 772 | reimplemented if the protocol supports getting data; this method
|
---|
| 773 | should then process the QNetworkOperation.
|
---|
| 774 |
|
---|
| 775 | When you reimplement this method it's very important that you emit
|
---|
| 776 | the correct signals at the correct time (especially the finished()
|
---|
| 777 | signal after processing an operation). Take a look at the \link
|
---|
| 778 | network.html Qt Network Documentation\endlink which describes in
|
---|
| 779 | detail how to reimplement this method. You may also want to look
|
---|
| 780 | at the example implementation in
|
---|
| 781 | examples/network/networkprotocol/nntp.cpp.
|
---|
| 782 |
|
---|
| 783 | \a op is the pointer to the operation object which contains all
|
---|
| 784 | the information on the operation that has finished, including the
|
---|
| 785 | state, etc.
|
---|
| 786 | */
|
---|
| 787 |
|
---|
| 788 | void QNetworkProtocol::operationGet( QNetworkOperation * )
|
---|
| 789 | {
|
---|
| 790 | }
|
---|
| 791 |
|
---|
| 792 | /*!
|
---|
| 793 | When implementing a new network protocol, this method should be
|
---|
| 794 | reimplemented if the protocol supports putting (uploading) data;
|
---|
| 795 | this method should then process the QNetworkOperation.
|
---|
| 796 |
|
---|
| 797 | When you reimplement this method it's very important that you emit
|
---|
| 798 | the correct signals at the correct time (especially the finished()
|
---|
| 799 | signal after processing an operation). Take a look at the \link
|
---|
| 800 | network.html Qt Network Documentation\endlink which describes in
|
---|
| 801 | detail how to reimplement this method. You may also want to look
|
---|
| 802 | at the example implementation in
|
---|
| 803 | examples/network/networkprotocol/nntp.cpp.
|
---|
| 804 |
|
---|
| 805 | \a op is the pointer to the operation object which contains all
|
---|
| 806 | the information on the operation that has finished, including the
|
---|
| 807 | state, etc.
|
---|
| 808 | */
|
---|
| 809 |
|
---|
| 810 | void QNetworkProtocol::operationPut( QNetworkOperation * )
|
---|
| 811 | {
|
---|
| 812 | }
|
---|
| 813 |
|
---|
| 814 | /*! \internal
|
---|
| 815 | */
|
---|
| 816 |
|
---|
| 817 | void QNetworkProtocol::operationPutChunk( QNetworkOperation * )
|
---|
| 818 | {
|
---|
| 819 | }
|
---|
| 820 |
|
---|
| 821 | /*!
|
---|
| 822 | \internal
|
---|
| 823 | Handles operations. Deletes the previous operation object and
|
---|
| 824 | tries to process the next operation. It also checks the connection state
|
---|
| 825 | and only processes the next operation, if the connection of the protocol
|
---|
| 826 | is open. Otherwise it waits until the protocol opens the connection.
|
---|
| 827 | */
|
---|
| 828 |
|
---|
| 829 | void QNetworkProtocol::processNextOperation( QNetworkOperation *old )
|
---|
| 830 | {
|
---|
| 831 | #ifdef QNETWORKPROTOCOL_DEBUG
|
---|
| 832 | qDebug( "QNetworkOperation: process next operation, old: %p", old );
|
---|
| 833 | #endif
|
---|
| 834 | d->removeTimer->stop();
|
---|
| 835 |
|
---|
| 836 | if ( old )
|
---|
| 837 | d->oldOps.append( old );
|
---|
| 838 | if ( d->opInProgress && d->opInProgress!=old )
|
---|
| 839 | d->oldOps.append( d->opInProgress );
|
---|
| 840 |
|
---|
| 841 | if ( d->operationQueue.isEmpty() ) {
|
---|
| 842 | d->opInProgress = 0;
|
---|
| 843 | if ( d->autoDelete )
|
---|
| 844 | d->removeTimer->start( d->removeInterval, TRUE );
|
---|
| 845 | return;
|
---|
| 846 | }
|
---|
| 847 |
|
---|
| 848 | QNetworkOperation *op = d->operationQueue.head();
|
---|
| 849 |
|
---|
| 850 | d->opInProgress = op;
|
---|
| 851 |
|
---|
| 852 | if ( !checkConnection( op ) ) {
|
---|
| 853 | if ( op->state() != QNetworkProtocol::StFailed ) {
|
---|
| 854 | d->opStartTimer->start( 0, TRUE );
|
---|
| 855 | } else {
|
---|
| 856 | d->operationQueue.dequeue();
|
---|
| 857 | clearOperationQueue();
|
---|
| 858 | emit finished( op );
|
---|
| 859 | }
|
---|
| 860 |
|
---|
| 861 | return;
|
---|
| 862 | }
|
---|
| 863 |
|
---|
| 864 | d->opInProgress = op;
|
---|
| 865 | d->operationQueue.dequeue();
|
---|
| 866 | processOperation( op );
|
---|
| 867 | }
|
---|
| 868 |
|
---|
| 869 | /*!
|
---|
| 870 | Returns the QUrlOperator on which the protocol works.
|
---|
| 871 | */
|
---|
| 872 |
|
---|
| 873 | QUrlOperator *QNetworkProtocol::url() const
|
---|
| 874 | {
|
---|
| 875 | return d->url;
|
---|
| 876 | }
|
---|
| 877 |
|
---|
| 878 | /*!
|
---|
| 879 | Returns the operation, which is being processed, or 0 of no
|
---|
| 880 | operation is being processed at the moment.
|
---|
| 881 | */
|
---|
| 882 |
|
---|
| 883 | QNetworkOperation *QNetworkProtocol::operationInProgress() const
|
---|
| 884 | {
|
---|
| 885 | return d->opInProgress;
|
---|
| 886 | }
|
---|
| 887 |
|
---|
| 888 | /*!
|
---|
| 889 | Clears the operation queue.
|
---|
| 890 | */
|
---|
| 891 |
|
---|
| 892 | void QNetworkProtocol::clearOperationQueue()
|
---|
| 893 | {
|
---|
| 894 | d->operationQueue.dequeue();
|
---|
| 895 | d->operationQueue.setAutoDelete( TRUE );
|
---|
| 896 | d->operationQueue.clear();
|
---|
| 897 | }
|
---|
| 898 |
|
---|
| 899 | /*!
|
---|
| 900 | Stops the current operation that is being processed and clears all
|
---|
| 901 | waiting operations.
|
---|
| 902 | */
|
---|
| 903 |
|
---|
| 904 | void QNetworkProtocol::stop()
|
---|
| 905 | {
|
---|
| 906 | QNetworkOperation *op = d->opInProgress;
|
---|
| 907 | clearOperationQueue();
|
---|
| 908 | if ( op ) {
|
---|
| 909 | op->setState( StStopped );
|
---|
| 910 | op->setProtocolDetail( tr( "Operation stopped by the user" ) );
|
---|
| 911 | emit finished( op );
|
---|
| 912 | setUrl( 0 );
|
---|
| 913 | op->free();
|
---|
| 914 | }
|
---|
| 915 | }
|
---|
| 916 |
|
---|
| 917 | /*!
|
---|
| 918 | Because it's sometimes hard to take care of removing network
|
---|
| 919 | protocol instances, QNetworkProtocol provides an auto-delete
|
---|
| 920 | mechanism. If you set \a b to TRUE, the network protocol instance
|
---|
| 921 | is removed after it has been inactive for \a i milliseconds (i.e.
|
---|
| 922 | \a i milliseconds after the last operation has been processed).
|
---|
| 923 | If you set \a b to FALSE the auto-delete mechanism is switched
|
---|
| 924 | off.
|
---|
| 925 |
|
---|
| 926 | If you switch on auto-delete, the QNetworkProtocol also deletes
|
---|
| 927 | its QUrlOperator.
|
---|
| 928 | */
|
---|
| 929 |
|
---|
| 930 | void QNetworkProtocol::setAutoDelete( bool b, int i )
|
---|
| 931 | {
|
---|
| 932 | d->autoDelete = b;
|
---|
| 933 | d->removeInterval = i;
|
---|
| 934 | }
|
---|
| 935 |
|
---|
| 936 | /*!
|
---|
| 937 | Returns TRUE if auto-deleting is enabled; otherwise returns FALSE.
|
---|
| 938 |
|
---|
| 939 | \sa QNetworkProtocol::setAutoDelete()
|
---|
| 940 | */
|
---|
| 941 |
|
---|
| 942 | bool QNetworkProtocol::autoDelete() const
|
---|
| 943 | {
|
---|
| 944 | return d->autoDelete;
|
---|
| 945 | }
|
---|
| 946 |
|
---|
| 947 | /*!
|
---|
| 948 | \internal
|
---|
| 949 | */
|
---|
| 950 |
|
---|
| 951 | void QNetworkProtocol::removeMe()
|
---|
| 952 | {
|
---|
| 953 | if ( d->autoDelete ) {
|
---|
| 954 | #ifdef QNETWORKPROTOCOL_DEBUG
|
---|
| 955 | qDebug( "QNetworkOperation: autodelete of QNetworkProtocol %p", this );
|
---|
| 956 | #endif
|
---|
| 957 | delete d->url; // destructor deletes the network protocol
|
---|
| 958 | }
|
---|
| 959 | }
|
---|
| 960 |
|
---|
| 961 | void QNetworkProtocol::emitNewChildren( const QUrlInfo &i, QNetworkOperation *op )
|
---|
| 962 | {
|
---|
| 963 | QValueList<QUrlInfo> lst;
|
---|
| 964 | lst << i;
|
---|
| 965 | emit newChildren( lst, op );
|
---|
| 966 | }
|
---|
| 967 |
|
---|
| 968 | class QNetworkOperationPrivate
|
---|
| 969 | {
|
---|
| 970 | public:
|
---|
| 971 | QNetworkProtocol::Operation operation;
|
---|
| 972 | QNetworkProtocol::State state;
|
---|
| 973 | QMap<int, QString> args;
|
---|
| 974 | QMap<int, QByteArray> rawArgs;
|
---|
| 975 | QString protocolDetail;
|
---|
| 976 | int errorCode;
|
---|
| 977 | QTimer *deleteTimer;
|
---|
| 978 | };
|
---|
| 979 |
|
---|
| 980 | /*!
|
---|
| 981 | \class QNetworkOperation
|
---|
| 982 |
|
---|
| 983 | \brief The QNetworkOperation class provides common operations for network protocols.
|
---|
| 984 | \if defined(commercial)
|
---|
| 985 | It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
|
---|
| 986 | \endif
|
---|
| 987 |
|
---|
| 988 | \module network
|
---|
| 989 | \ingroup io
|
---|
| 990 |
|
---|
| 991 | An object is created to describe the operation and the current
|
---|
| 992 | state for each operation that a network protocol should process.
|
---|
| 993 |
|
---|
| 994 | For a detailed description of the Qt Network Architecture and how
|
---|
| 995 | to implement and use network protocols in Qt, see the \link
|
---|
| 996 | network.html Qt Network Documentation\endlink.
|
---|
| 997 |
|
---|
| 998 | \sa QNetworkProtocol
|
---|
| 999 | */
|
---|
| 1000 |
|
---|
| 1001 | /*!
|
---|
| 1002 | Constructs a network operation object. \a operation is the type of
|
---|
| 1003 | the operation, and \a arg0, \a arg1 and \a arg2 are the first
|
---|
| 1004 | three arguments of the operation. The state is initialized to
|
---|
| 1005 | QNetworkProtocol::StWaiting.
|
---|
| 1006 |
|
---|
| 1007 | \sa QNetworkProtocol::Operation QNetworkProtocol::State
|
---|
| 1008 | */
|
---|
| 1009 |
|
---|
| 1010 | QNetworkOperation::QNetworkOperation( QNetworkProtocol::Operation operation,
|
---|
| 1011 | const QString &arg0, const QString &arg1,
|
---|
| 1012 | const QString &arg2 )
|
---|
| 1013 | {
|
---|
| 1014 | d = new QNetworkOperationPrivate;
|
---|
| 1015 | d->deleteTimer = new QTimer( this );
|
---|
| 1016 | connect( d->deleteTimer, SIGNAL( timeout() ),
|
---|
| 1017 | this, SLOT( deleteMe() ) );
|
---|
| 1018 | d->operation = operation;
|
---|
| 1019 | d->state = QNetworkProtocol::StWaiting;
|
---|
| 1020 | d->args[ 0 ] = arg0;
|
---|
| 1021 | d->args[ 1 ] = arg1;
|
---|
| 1022 | d->args[ 2 ] = arg2;
|
---|
| 1023 | d->rawArgs[ 0 ] = QByteArray( 0 );
|
---|
| 1024 | d->rawArgs[ 1 ] = QByteArray( 0 );
|
---|
| 1025 | d->rawArgs[ 2 ] = QByteArray( 0 );
|
---|
| 1026 | d->protocolDetail = QString::null;
|
---|
| 1027 | d->errorCode = (int)QNetworkProtocol::NoError;
|
---|
| 1028 | }
|
---|
| 1029 |
|
---|
| 1030 | /*!
|
---|
| 1031 | Constructs a network operation object. \a operation is the type of
|
---|
| 1032 | the operation, and \a arg0, \a arg1 and \a arg2 are the first
|
---|
| 1033 | three raw data arguments of the operation. The state is
|
---|
| 1034 | initialized to QNetworkProtocol::StWaiting.
|
---|
| 1035 |
|
---|
| 1036 | \sa QNetworkProtocol::Operation QNetworkProtocol::State
|
---|
| 1037 | */
|
---|
| 1038 |
|
---|
| 1039 | QNetworkOperation::QNetworkOperation( QNetworkProtocol::Operation operation,
|
---|
| 1040 | const QByteArray &arg0, const QByteArray &arg1,
|
---|
| 1041 | const QByteArray &arg2 )
|
---|
| 1042 | {
|
---|
| 1043 | d = new QNetworkOperationPrivate;
|
---|
| 1044 | d->deleteTimer = new QTimer( this );
|
---|
| 1045 | connect( d->deleteTimer, SIGNAL( timeout() ),
|
---|
| 1046 | this, SLOT( deleteMe() ) );
|
---|
| 1047 | d->operation = operation;
|
---|
| 1048 | d->state = QNetworkProtocol::StWaiting;
|
---|
| 1049 | d->args[ 0 ] = QString::null;
|
---|
| 1050 | d->args[ 1 ] = QString::null;
|
---|
| 1051 | d->args[ 2 ] = QString::null;
|
---|
| 1052 | d->rawArgs[ 0 ] = arg0;
|
---|
| 1053 | d->rawArgs[ 1 ] = arg1;
|
---|
| 1054 | d->rawArgs[ 2 ] = arg2;
|
---|
| 1055 | d->protocolDetail = QString::null;
|
---|
| 1056 | d->errorCode = (int)QNetworkProtocol::NoError;
|
---|
| 1057 | }
|
---|
| 1058 |
|
---|
| 1059 | /*!
|
---|
| 1060 | Destructor.
|
---|
| 1061 | */
|
---|
| 1062 |
|
---|
| 1063 | QNetworkOperation::~QNetworkOperation()
|
---|
| 1064 | {
|
---|
| 1065 | delete d;
|
---|
| 1066 | }
|
---|
| 1067 |
|
---|
| 1068 | /*!
|
---|
| 1069 | Sets the \a state of the operation object. This should be done by
|
---|
| 1070 | the network protocol during processing; at the end it should be
|
---|
| 1071 | set to QNetworkProtocol::StDone or QNetworkProtocol::StFailed,
|
---|
| 1072 | depending on success or failure.
|
---|
| 1073 |
|
---|
| 1074 | \sa QNetworkProtocol::State
|
---|
| 1075 | */
|
---|
| 1076 |
|
---|
| 1077 | void QNetworkOperation::setState( QNetworkProtocol::State state )
|
---|
| 1078 | {
|
---|
| 1079 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1080 | d->deleteTimer->stop();
|
---|
| 1081 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1082 | }
|
---|
| 1083 | d->state = state;
|
---|
| 1084 | }
|
---|
| 1085 |
|
---|
| 1086 | /*!
|
---|
| 1087 | If the operation failed, the error message can be specified as \a
|
---|
| 1088 | detail.
|
---|
| 1089 | */
|
---|
| 1090 |
|
---|
| 1091 | void QNetworkOperation::setProtocolDetail( const QString &detail )
|
---|
| 1092 | {
|
---|
| 1093 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1094 | d->deleteTimer->stop();
|
---|
| 1095 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1096 | }
|
---|
| 1097 | d->protocolDetail = detail;
|
---|
| 1098 | }
|
---|
| 1099 |
|
---|
| 1100 | /*!
|
---|
| 1101 | Sets the error code to \a ec.
|
---|
| 1102 |
|
---|
| 1103 | If the operation failed, the protocol should set an error code to
|
---|
| 1104 | describe the error in more detail. If possible, one of the error
|
---|
| 1105 | codes defined in QNetworkProtocol should be used.
|
---|
| 1106 |
|
---|
| 1107 | \sa setProtocolDetail() QNetworkProtocol::Error
|
---|
| 1108 | */
|
---|
| 1109 |
|
---|
| 1110 | void QNetworkOperation::setErrorCode( int ec )
|
---|
| 1111 | {
|
---|
| 1112 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1113 | d->deleteTimer->stop();
|
---|
| 1114 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1115 | }
|
---|
| 1116 | d->errorCode = ec;
|
---|
| 1117 | }
|
---|
| 1118 |
|
---|
| 1119 | /*!
|
---|
| 1120 | Sets the network operation's \a{num}-th argument to \a arg.
|
---|
| 1121 | */
|
---|
| 1122 |
|
---|
| 1123 | void QNetworkOperation::setArg( int num, const QString &arg )
|
---|
| 1124 | {
|
---|
| 1125 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1126 | d->deleteTimer->stop();
|
---|
| 1127 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1128 | }
|
---|
| 1129 | d->args[ num ] = arg;
|
---|
| 1130 | }
|
---|
| 1131 |
|
---|
| 1132 | /*!
|
---|
| 1133 | Sets the network operation's \a{num}-th raw data argument to \a arg.
|
---|
| 1134 | */
|
---|
| 1135 |
|
---|
| 1136 | void QNetworkOperation::setRawArg( int num, const QByteArray &arg )
|
---|
| 1137 | {
|
---|
| 1138 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1139 | d->deleteTimer->stop();
|
---|
| 1140 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1141 | }
|
---|
| 1142 | d->rawArgs[ num ] = arg;
|
---|
| 1143 | }
|
---|
| 1144 |
|
---|
| 1145 | /*!
|
---|
| 1146 | Returns the type of the operation.
|
---|
| 1147 | */
|
---|
| 1148 |
|
---|
| 1149 | QNetworkProtocol::Operation QNetworkOperation::operation() const
|
---|
| 1150 | {
|
---|
| 1151 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1152 | d->deleteTimer->stop();
|
---|
| 1153 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1154 | }
|
---|
| 1155 | return d->operation;
|
---|
| 1156 | }
|
---|
| 1157 |
|
---|
| 1158 | /*!
|
---|
| 1159 | Returns the state of the operation. You can determine whether an
|
---|
| 1160 | operation is still waiting to be processed, is being processed,
|
---|
| 1161 | has been processed successfully, or failed.
|
---|
| 1162 | */
|
---|
| 1163 |
|
---|
| 1164 | QNetworkProtocol::State QNetworkOperation::state() const
|
---|
| 1165 | {
|
---|
| 1166 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1167 | d->deleteTimer->stop();
|
---|
| 1168 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1169 | }
|
---|
| 1170 | return d->state;
|
---|
| 1171 | }
|
---|
| 1172 |
|
---|
| 1173 | /*!
|
---|
| 1174 | Returns the operation's \a{num}-th argument. If this argument was
|
---|
| 1175 | not already set, an empty string is returned.
|
---|
| 1176 | */
|
---|
| 1177 |
|
---|
| 1178 | QString QNetworkOperation::arg( int num ) const
|
---|
| 1179 | {
|
---|
| 1180 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1181 | d->deleteTimer->stop();
|
---|
| 1182 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1183 | }
|
---|
| 1184 | return d->args[ num ];
|
---|
| 1185 | }
|
---|
| 1186 |
|
---|
| 1187 | /*!
|
---|
| 1188 | Returns the operation's \a{num}-th raw data argument. If this
|
---|
| 1189 | argument was not already set, an empty bytearray is returned.
|
---|
| 1190 | */
|
---|
| 1191 |
|
---|
| 1192 | QByteArray QNetworkOperation::rawArg( int num ) const
|
---|
| 1193 | {
|
---|
| 1194 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1195 | d->deleteTimer->stop();
|
---|
| 1196 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1197 | }
|
---|
| 1198 | return d->rawArgs[ num ];
|
---|
| 1199 | }
|
---|
| 1200 |
|
---|
| 1201 | /*!
|
---|
| 1202 | Returns a detailed error message for the last error. This must
|
---|
| 1203 | have been set using setProtocolDetail().
|
---|
| 1204 | */
|
---|
| 1205 |
|
---|
| 1206 | QString QNetworkOperation::protocolDetail() const
|
---|
| 1207 | {
|
---|
| 1208 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1209 | d->deleteTimer->stop();
|
---|
| 1210 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1211 | }
|
---|
| 1212 | return d->protocolDetail;
|
---|
| 1213 | }
|
---|
| 1214 |
|
---|
| 1215 | /*!
|
---|
| 1216 | Returns the error code for the last error that occurred.
|
---|
| 1217 | */
|
---|
| 1218 |
|
---|
| 1219 | int QNetworkOperation::errorCode() const
|
---|
| 1220 | {
|
---|
| 1221 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1222 | d->deleteTimer->stop();
|
---|
| 1223 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1224 | }
|
---|
| 1225 | return d->errorCode;
|
---|
| 1226 | }
|
---|
| 1227 |
|
---|
| 1228 | /*!
|
---|
| 1229 | \internal
|
---|
| 1230 | */
|
---|
| 1231 |
|
---|
| 1232 | QByteArray& QNetworkOperation::raw( int num ) const
|
---|
| 1233 | {
|
---|
| 1234 | if ( d->deleteTimer->isActive() ) {
|
---|
| 1235 | d->deleteTimer->stop();
|
---|
| 1236 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1237 | }
|
---|
| 1238 | return d->rawArgs[ num ];
|
---|
| 1239 | }
|
---|
| 1240 |
|
---|
| 1241 | /*!
|
---|
| 1242 | Sets this object to delete itself when it hasn't been used for one
|
---|
| 1243 | second.
|
---|
| 1244 |
|
---|
| 1245 | Because QNetworkOperation pointers are passed around a lot the
|
---|
| 1246 | QNetworkProtocol generally does not have enough knowledge to
|
---|
| 1247 | delete these at the correct time. If a QNetworkProtocol doesn't
|
---|
| 1248 | need an operation any more it will call this function instead.
|
---|
| 1249 |
|
---|
| 1250 | Note: you should never need to call the method yourself.
|
---|
| 1251 | */
|
---|
| 1252 |
|
---|
| 1253 | void QNetworkOperation::free()
|
---|
| 1254 | {
|
---|
| 1255 | d->deleteTimer->start( NETWORK_OP_DELAY );
|
---|
| 1256 | }
|
---|
| 1257 |
|
---|
| 1258 | /*!
|
---|
| 1259 | \internal
|
---|
| 1260 | Internal slot for auto-deletion.
|
---|
| 1261 | */
|
---|
| 1262 |
|
---|
| 1263 | void QNetworkOperation::deleteMe()
|
---|
| 1264 | {
|
---|
[8] | 1265 | // ### A hackish workaround to prevent this op from being deleted during
|
---|
| 1266 | // the qApp->processEvents() call in QLocalFs::operationListChildren().
|
---|
| 1267 | // The proper way is to add something like QNetworkOperation::cancelFree()
|
---|
| 1268 | // to stop deleteTimer and make it a documented method.
|
---|
| 1269 | if ( !signalsBlocked() )
|
---|
| 1270 | delete this;
|
---|
[2] | 1271 | }
|
---|
| 1272 |
|
---|
| 1273 | #endif
|
---|