📄 q3ftp.cpp
字号:
error flag set to \c false, even though the command did not complete successfully. \sa clearPendingCommands()*/void Q3Ftp::abort(){ Q3FtpPrivate *d = ::d( this ); if ( d->pending.isEmpty() ) return; clearPendingCommands(); d->pi.abort();}/*! Returns the identifier of the FTP command that is being executed or 0 if there is no command being executed. \sa currentCommand()*/int Q3Ftp::currentId() const{ Q3FtpPrivate *d = ::d( this ); Q3FtpCommand *c = d->pending.getFirst(); if ( c == 0 ) return 0; return c->id;}/*! Returns the command type of the FTP command being executed or \c None if there is no command being executed. \sa currentId()*/Q3Ftp::Command Q3Ftp::currentCommand() const{ Q3FtpPrivate *d = ::d( this ); Q3FtpCommand *c = d->pending.getFirst(); if ( c == 0 ) return None; return c->command;}/*! Returns the QIODevice pointer that is used by the FTP command to read data from or store data to. If there is no current FTP command being executed or if the command does not use an IO device, this function returns 0. This function can be used to delete the QIODevice in the slot connected to the commandFinished() signal. \sa get() put()*/QIODevice* Q3Ftp::currentDevice() const{ Q3FtpPrivate *d = ::d( this ); Q3FtpCommand *c = d->pending.getFirst(); if ( !c ) return 0; if ( c->is_ba ) return 0; return c->data.dev;}/*! Returns true if there are any commands scheduled that have not yet been executed; otherwise returns false. The command that is being executed is \e not considered as a scheduled command. \sa clearPendingCommands() currentId() currentCommand()*/bool Q3Ftp::hasPendingCommands() const{ Q3FtpPrivate *d = ::d( this ); return d->pending.count() > 1;}/*! Deletes all pending commands from the list of scheduled commands. This does not affect the command that is being executed. If you want to stop this this as well, use abort(). \sa hasPendingCommands() abort()*/void Q3Ftp::clearPendingCommands(){ Q3FtpPrivate *d = ::d( this ); Q3FtpCommand *c = 0; if ( d->pending.count() > 0 ) c = d->pending.take( 0 ); d->pending.clear(); if ( c ) d->pending.append( c );}/*! Returns the current state of the object. When the state changes, the stateChanged() signal is emitted. \sa State stateChanged()*/Q3Ftp::State Q3Ftp::state() const{ Q3FtpPrivate *d = ::d( this ); return d->state;}/*! Returns the last error that occurred. This is useful to find out what when wrong when receiving a commandFinished() or a done() signal with the \c error argument set to \c true. If you start a new command, the error status is reset to \c NoError.*/Q3Ftp::Error Q3Ftp::error() const{ Q3FtpPrivate *d = ::d( this ); return d->error;}/*! Returns a human-readable description of the last error that occurred. This is useful for presenting a error message to the user when receiving a commandFinished() or a done() signal with the \c error argument set to \c true. The error string is often (but not always) the reply from the server, so it is not always possible to translate the string. If the message comes from Qt, the string has already passed through tr().*/QString Q3Ftp::errorString() const{ Q3FtpPrivate *d = ::d( this ); return d->errorString;}int Q3Ftp::addCommand( Q3FtpCommand *cmd ){ Q3FtpPrivate *d = ::d( this ); d->pending.append( cmd ); if ( d->pending.count() == 1 ) // don't emit the commandStarted() signal before the id is returned QTimer::singleShot( 0, this, SLOT(startNextCommand()) ); return cmd->id;}void Q3Ftp::startNextCommand(){ Q3FtpPrivate *d = ::d( this ); Q3FtpCommand *c = d->pending.getFirst(); if ( c == 0 ) return; d->error = NoError; d->errorString = QFtp::tr( "Unknown error" ); if ( bytesAvailable() ) readAll(); // clear the data emit commandStarted( c->id ); if ( c->command == ConnectToHost ) { d->pi.connectToHost( c->rawCmds[0], c->rawCmds[1].toUInt() ); } else { if ( c->command == Put ) { if ( c->is_ba ) { d->pi.dtp.setData( c->data.ba ); d->pi.dtp.setBytesTotal( c->data.ba->size() ); } else if ( c->data.dev && (c->data.dev->isOpen() || c->data.dev->open(QIODevice::ReadOnly)) ) { d->pi.dtp.setDevice( c->data.dev ); if ( c->data.dev->isSequentialAccess() ) d->pi.dtp.setBytesTotal( 0 ); else d->pi.dtp.setBytesTotal( c->data.dev->size() ); } } else if ( c->command == Get ) { if ( !c->is_ba && c->data.dev ) { d->pi.dtp.setDevice( c->data.dev ); } } else if ( c->command == Close ) { d->state = Q3Ftp::Closing; emit stateChanged( d->state ); } if ( !d->pi.sendCommands( c->rawCmds ) ) { // ### error handling (this case should not happen) } }}void Q3Ftp::piFinished( const QString& ){ Q3FtpPrivate *d = ::d( this ); Q3FtpCommand *c = d->pending.getFirst(); if ( c == 0 ) return; if ( c->command == Close ) { // The order of in which the slots are called is arbitrary, so // disconnect the SIGNAL-SIGNAL temporary to make sure that we // don't get the commandFinished() signal before the stateChanged() // signal. if ( d->state != Q3Ftp::Unconnected ) { d->close_waitForStateChange = true; return; } } emit commandFinished( c->id, false ); d->pending.removeFirst(); if ( d->pending.isEmpty() ) { emit done( false ); } else { startNextCommand(); }}void Q3Ftp::piError( int errorCode, const QString &text ){ Q3FtpPrivate *d = ::d( this ); Q3FtpCommand *c = d->pending.getFirst(); // non-fatal errors if ( c->command==Get && d->pi.currentCommand().startsWith(QLatin1String("SIZE ")) ) { d->pi.dtp.setBytesTotal( -1 ); return; } else if ( c->command==Put && d->pi.currentCommand().startsWith(QLatin1String("ALLO ")) ) { return; } d->error = (Error)errorCode; switch ( currentCommand() ) { case ConnectToHost: d->errorString = QFtp::tr( "Connecting to host failed:\n%1" ).arg( text ); break; case Login: d->errorString = QFtp::tr( "Login failed:\n%1" ).arg( text ); break; case List: d->errorString = QFtp::tr( "Listing directory failed:\n%1" ).arg( text ); break; case Cd: d->errorString = QFtp::tr( "Changing directory failed:\n%1" ).arg( text ); break; case Get: d->errorString = QFtp::tr( "Downloading file failed:\n%1" ).arg( text ); break; case Put: d->errorString = QFtp::tr( "Uploading file failed:\n%1" ).arg( text ); break; case Remove: d->errorString = QFtp::tr( "Removing file failed:\n%1" ).arg( text ); break; case Mkdir: d->errorString = QFtp::tr( "Creating directory failed:\n%1" ).arg( text ); break; case Rmdir: d->errorString = QFtp::tr( "Removing directory failed:\n%1" ).arg( text ); break; default: d->errorString = text; break; } d->pi.clearPendingCommands(); clearPendingCommands(); emit commandFinished( c->id, true ); d->pending.removeFirst(); if ( d->pending.isEmpty() ) emit done( true ); else startNextCommand();}void Q3Ftp::piConnectState( int state ){ Q3FtpPrivate *d = ::d( this ); d->state = (State)state; emit stateChanged( d->state ); if ( d->close_waitForStateChange ) { d->close_waitForStateChange = false; piFinished( QFtp::tr( "Connection closed" ) ); }}void Q3Ftp::piFtpReply( int code, const QString &text ){ if ( currentCommand() == RawCommand ) { Q3FtpPrivate *d = ::d( this ); d->pi.rawCommand = true; emit rawCommandReply( code, text ); }}/*! Destructor.*/Q3Ftp::~Q3Ftp(){ abort(); close(); delete_d( this );}/********************************************************************** * * Q3Ftp implementation of the Q3NetworkProtocol interface * *********************************************************************//*! \reimp*/void Q3Ftp::operationListChildren( Q3NetworkOperation *op ){ op->setState( StInProgress ); cd( ( url()->path().isEmpty() ? QString( QLatin1String("/") ) : url()->path() ) ); list(); emit start( op );}/*! \reimp*/void Q3Ftp::operationMkDir( Q3NetworkOperation *op ){ op->setState( StInProgress ); mkdir( op->arg( 0 ) );}/*! \reimp*/void Q3Ftp::operationRemove( Q3NetworkOperation *op ){ op->setState( StInProgress ); cd( ( url()->path().isEmpty() ? QString( QLatin1String("/") ) : url()->path() ) ); remove( Q3Url( op->arg( 0 ) ).path() );}/*! \reimp*/void Q3Ftp::operationRename( Q3NetworkOperation *op ){ op->setState( StInProgress ); cd( ( url()->path().isEmpty() ? QString( QLatin1String("/") ) : url()->path() ) ); rename( op->arg( 0 ), op->arg( 1 ));}/*! \reimp*/void Q3Ftp::operationGet( Q3NetworkOperation *op ){ op->setState( StInProgress ); Q3Url u( op->arg( 0 ) ); get( u.path() );}/*! \reimp*/void Q3Ftp::operationPut( Q3NetworkOperation *op ){ op->setState( StInProgress ); Q3Url u( op->arg( 0 ) ); put( op->rawArg(1), u.path() );}/*! \reimp*/bool Q3Ftp::checkConnection( Q3NetworkOperation *op ){ Q3FtpPrivate *d = ::d( this ); if ( state() == Unconnected && !d->npWaitForLoginDone ) { connect( this, SIGNAL(listInfo(QUrlInfo)), this, SLOT(npListInfo(QUrlInfo)) ); connect( this, SIGNAL(done(bool)), this, SLOT(npDone(bool)) ); connect( this, SIGNAL(stateChanged(int)), this, SLOT(npStateChanged(int)) ); connect( this, SIGNAL(dataTransferProgress(int,int)), this, SLOT(npDataTransferProgress(int,int)) ); connect( this, SIGNAL(readyRead()), this, SLOT(npReadyRead()) ); d->npWaitForLoginDone = true; switch ( op->operation() ) { case OpGet: case OpPut: { Q3Url u( op->arg( 0 ) ); connectToHost( u.host(), u.port() != -1 ? u.port() : 21 ); } break; default: connectToHost( url()->host(), url()->port() != -1 ? url()->port() : 21 ); break; } QString user = url()->user().isEmpty() ? QString( QLatin1String("anonymous") ) : url()->user(); QString pass = url()->password().isEmpty() ? QString( QLatin1String("anonymous@") ) : url()->password(); login( user, pass ); } if ( state() == LoggedIn ) return true; return false;}/*! \reimp*/int Q3Ftp::supportedOperations() const{ return OpListChildren | OpMkDir | OpRemove | OpRename | OpGet | OpPut;}/*! \internal Parses the string, \a buffer, which is one line of a directory listing which came from the FTP server, and sets the values which have been parsed to the url info object, \a info.*/void Q3Ftp::parseDir( const QString &buffer, QUrlInfo &info ){ Q3FtpDTP::parseDir( buffer, url()->user(), &info );}void Q3Ftp::npListInfo( const QUrlInfo & i ){ if ( url() ) { QRegExp filt( url()->nameFilter(), false, true ); if ( i.isDir() || filt.search( i.name() ) != -1 ) { emit newChild( i, operationInProgress() ); } } else { emit newChild( i, operationInProgress() ); }}void Q3Ftp::npDone( bool err ){ Q3FtpPrivate *d = ::d( this ); bool emitFinishedSignal = false; Q3NetworkOperation *op = operationInProgress(); if ( op ) { if ( err ) { op->setProtocolDetail( errorString() ); op
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -