Q3FtpDTP Class Reference

Inheritance diagram for Q3FtpDTP:

Inheritance graph
[legend]
Collaboration diagram for Q3FtpDTP:

Collaboration graph
[legend]
List of all members.

Detailed Description

Definition at line 51 of file q3ftp.cpp.

Public Types

enum  ConnectState

Signals

void listInfo (const QUrlInfo &)
void readyRead ()
void dataTransferProgress (int, int)
void connectState (int)

Public Member Functions

 Q3FtpDTP (Q3FtpPI *p, QObject *parent=0, const char *name=0)
void setData (QByteArray *)
void setDevice (QIODevice *)
void writeData ()
void setBytesTotal (int bytes)
bool hasError () const
QString errorMessage () const
void clearError ()
void connectToHost (const QString &host, Q_UINT16 port)
Q3Socket::State socketState () const
Q_ULONG bytesAvailable () const
Q_LONG readBlock (char *data, Q_ULONG maxlen)
QByteArray readAll ()
void abortConnection ()

Static Public Member Functions

static bool parseDir (const QString &buffer, const QString &userName, QUrlInfo *info)

Private Slots

void socketConnected ()
void socketReadyRead ()
void socketError (int)
void socketConnectionClosed ()
void socketBytesWritten (int)

Private Member Functions

void clearData ()

Private Attributes

Q3Socket socket
Q3FtpPIpi
QString err
int bytesDone
int bytesTotal
bool callWriteData
union {
   QByteArray *   ba
   QIODevice *   dev
data
bool is_ba


Member Enumeration Documentation

enum Q3FtpDTP::ConnectState

Definition at line 56 of file q3ftp.cpp.

00056                       {
00057   CsHostFound,
00058   CsConnected,
00059   CsClosed,
00060   CsHostNotFound,
00061   CsConnectionRefused
00062     };


Constructor & Destructor Documentation

Q3FtpDTP::Q3FtpDTP ( Q3FtpPI p,
QObject parent = 0,
const char *  name = 0 
)

Definition at line 278 of file q3ftp.cpp.

References clearData(), QObject::connect(), error, readyRead(), SIGNAL, SLOT, socket, socketBytesWritten(), socketConnected(), socketConnectionClosed(), socketError(), and socketReadyRead().

00278                                                                   :
00279     QObject( parent, name ),
00280     socket( 0, "Q3FtpDTP_socket" ),
00281     pi( p ),
00282     callWriteData( false )
00283 {
00284     clearData();
00285 
00286     connect( &socket, SIGNAL(connected()),
00287        SLOT(socketConnected()) );
00288     connect( &socket, SIGNAL(readyRead()),
00289        SLOT(socketReadyRead()) );
00290     connect( &socket, SIGNAL(error(int)),
00291        SLOT(socketError(int)) );
00292     connect( &socket, SIGNAL(connectionClosed()),
00293        SLOT(socketConnectionClosed()) );
00294     connect( &socket, SIGNAL(bytesWritten(int)),
00295        SLOT(socketBytesWritten(int)) );
00296 }

Here is the call graph for this function:


Member Function Documentation

void Q3FtpDTP::setData ( QByteArray  ) 

Definition at line 298 of file q3ftp.cpp.

References ba, data, and is_ba.

00299 {
00300     is_ba = true;
00301     data.ba = ba;
00302 }

void Q3FtpDTP::setDevice ( QIODevice  ) 

Definition at line 304 of file q3ftp.cpp.

References data, dev, and is_ba.

00305 {
00306     is_ba = false;
00307     data.dev = dev;
00308 }

void Q3FtpDTP::writeData (  ) 

Definition at line 310 of file q3ftp.cpp.

References buf, bytesDone, bytesTotal, Q3Socket::bytesToWrite(), callWriteData, clearData(), Q3Socket::close(), data, dataTransferProgress(), emit, is_ba, qDebug(), and socket.

Referenced by Q3FtpPI::processReply(), and socketBytesWritten().

00311 {
00312     if ( is_ba ) {
00313 #if defined(Q3FTPDTP_DEBUG)
00314   qDebug( "Q3FtpDTP::writeData: write %d bytes", data.ba->size() );
00315 #endif
00316   if ( data.ba->size() == 0 )
00317       emit dataTransferProgress( 0, bytesTotal );
00318   else
00319       socket.writeBlock( data.ba->data(), data.ba->size() );
00320   socket.close();
00321   clearData();
00322     } else if ( data.dev ) {
00323   callWriteData = false;
00324   const int blockSize = 16*1024;
00325   char buf[blockSize];
00326   while ( !data.dev->atEnd() && socket.bytesToWrite()==0 ) {
00327       Q_LONG read = data.dev->readBlock( buf, blockSize );
00328 #if defined(Q3FTPDTP_DEBUG)
00329       qDebug( "Q3FtpDTP::writeData: writeBlock() of size %d bytes", (int)read );
00330 #endif
00331       socket.writeBlock( buf, read );
00332       if ( !data.dev )
00333     return; // this can happen when a command is aborted
00334   }
00335   if ( data.dev->atEnd() ) {
00336       if ( bytesDone==0 && socket.bytesToWrite()==0 )
00337     emit dataTransferProgress( 0, bytesTotal );
00338       socket.close();
00339       clearData();
00340   } else {
00341       callWriteData = true;
00342   }
00343     }
00344 }

Here is the call graph for this function:

void Q3FtpDTP::setBytesTotal ( int  bytes  )  [inline]

Definition at line 70 of file q3ftp.cpp.

References bytesDone, bytesTotal, dataTransferProgress(), and emit.

Referenced by Q3FtpPI::processReply().

00071     {
00072   bytesTotal = bytes;
00073   bytesDone = 0;
00074   emit dataTransferProgress( bytesDone, bytesTotal );
00075     }

bool Q3FtpDTP::hasError (  )  const [inline]

Definition at line 346 of file q3ftp.cpp.

References err, and QString::isNull().

Referenced by Q3FtpPI::processReply().

00347 {
00348     return !err.isNull();
00349 }

Here is the call graph for this function:

QString Q3FtpDTP::errorMessage (  )  const [inline]

Definition at line 351 of file q3ftp.cpp.

References err.

Referenced by Q3FtpPI::processReply().

00352 {
00353     return err;
00354 }

void Q3FtpDTP::clearError (  )  [inline]

Definition at line 356 of file q3ftp.cpp.

References QString::clear(), and err.

Referenced by Q3FtpPI::processReply().

00357 {
00358     err.clear();
00359 }

Here is the call graph for this function:

void Q3FtpDTP::connectToHost ( const QString host,
Q_UINT16  port 
) [inline]

Definition at line 81 of file q3ftp.cpp.

References Q3Socket::connectToHost(), and socket.

Referenced by Q3FtpPI::processReply().

00082     { socket.connectToHost( host, port ); }

Here is the call graph for this function:

Q3Socket::State Q3FtpDTP::socketState (  )  const [inline]

Definition at line 84 of file q3ftp.cpp.

References socket, and Q3Socket::state().

Referenced by Q3FtpPI::processReply().

00085     { return socket.state(); }

Here is the call graph for this function:

Q_ULONG Q3FtpDTP::bytesAvailable (  )  const [inline]

Definition at line 87 of file q3ftp.cpp.

References Q3Socket::bytesAvailable(), and socket.

Referenced by socketReadyRead().

00088     { return socket.bytesAvailable(); }

Here is the call graph for this function:

Q_LONG Q3FtpDTP::readBlock ( char *  data,
Q_ULONG  maxlen 
) [inline]

Definition at line 90 of file q3ftp.cpp.

References bytesDone, and socket.

00091     {
00092   Q_LONG read = socket.readBlock( data, maxlen );
00093   bytesDone += read;
00094   return read;
00095     }

QByteArray Q3FtpDTP::readAll (  )  [inline]

Definition at line 97 of file q3ftp.cpp.

References bytesDone, QIODevice::readAll(), QByteArray::size(), and socket.

00098     {
00099   QByteArray tmp = socket.readAll();
00100   bytesDone += tmp.size();
00101   return tmp;
00102     }

Here is the call graph for this function:

void Q3FtpDTP::abortConnection (  ) 

Definition at line 361 of file q3ftp.cpp.

References callWriteData, clearData(), Q3Socket::clearPendingData(), Q3Socket::close(), qDebug(), and socket.

Referenced by Q3FtpPI::abort(), and Q3FtpPI::clearPendingCommands().

00362 {
00363 #if defined(Q3FTPDTP_DEBUG)
00364     qDebug( "Q3FtpDTP::abortConnection" );
00365 #endif
00366     callWriteData = false;
00367     clearData();
00368 
00369     socket.clearPendingData();
00370     socket.close();
00371 }

Here is the call graph for this function:

bool Q3FtpDTP::parseDir ( const QString buffer,
const QString userName,
QUrlInfo info 
) [static]

Definition at line 373 of file q3ftp.cpp.

References buffer, QList< T >::count(), QDate::currentDate(), QDateTime::currentDateTime(), d, QUrlInfo::ExeGroup, QUrlInfo::ExeOther, QUrlInfo::ExeOwner, QDate::fromString(), i, info, left(), n, QString::number(), p, QUrlInfo::ReadGroup, QUrlInfo::ReadOther, QUrlInfo::ReadOwner, right(), QString::toInt(), QUrlInfo::WriteGroup, QUrlInfo::WriteOther, and QUrlInfo::WriteOwner.

Referenced by Q3Ftp::parseDir(), and socketReadyRead().

00374 {
00375     QStringList lst = QStringList::split( " ", buffer );
00376 
00377     if ( lst.count() < 9 )
00378   return false;
00379 
00380     QString tmp;
00381 
00382     // permissions
00383     tmp = lst[ 0 ];
00384 
00385     if ( tmp[ 0 ] == QChar( 'd' ) ) {
00386   info->setDir( true );
00387   info->setFile( false );
00388   info->setSymLink( false );
00389     } else if ( tmp[ 0 ] == QChar( '-' ) ) {
00390   info->setDir( false );
00391   info->setFile( true );
00392   info->setSymLink( false );
00393     } else if ( tmp[ 0 ] == QChar( 'l' ) ) {
00394   info->setDir( true ); // #### todo
00395   info->setFile( false );
00396   info->setSymLink( true );
00397     } else {
00398   return false;
00399     }
00400 
00401     static int user = 0;
00402     static int group = 1;
00403     static int other = 2;
00404     static int readable = 0;
00405     static int writable = 1;
00406     static int executable = 2;
00407 
00408     bool perms[ 3 ][ 3 ];
00409     perms[0][0] = (tmp[ 1 ] == 'r');
00410     perms[0][1] = (tmp[ 2 ] == 'w');
00411     perms[0][2] = (tmp[ 3 ] == 'x');
00412     perms[1][0] = (tmp[ 4 ] == 'r');
00413     perms[1][1] = (tmp[ 5 ] == 'w');
00414     perms[1][2] = (tmp[ 6 ] == 'x');
00415     perms[2][0] = (tmp[ 7 ] == 'r');
00416     perms[2][1] = (tmp[ 8 ] == 'w');
00417     perms[2][2] = (tmp[ 9 ] == 'x');
00418 
00419     // owner
00420     tmp = lst[ 2 ];
00421     info->setOwner( tmp );
00422 
00423     // group
00424     tmp = lst[ 3 ];
00425     info->setGroup( tmp );
00426 
00427     // ### not correct
00428     info->setWritable( ( userName == info->owner() && perms[ user ][ writable ] ) ||
00429   perms[ other ][ writable ] );
00430     info->setReadable( ( userName == info->owner() && perms[ user ][ readable ] ) ||
00431   perms[ other ][ readable ] );
00432 
00433     int p = 0;
00434     if ( perms[ user ][ readable ] )
00435   p |= QUrlInfo::ReadOwner;
00436     if ( perms[ user ][ writable ] )
00437   p |= QUrlInfo::WriteOwner;
00438     if ( perms[ user ][ executable ] )
00439   p |= QUrlInfo::ExeOwner;
00440     if ( perms[ group ][ readable ] )
00441   p |= QUrlInfo::ReadGroup;
00442     if ( perms[ group ][ writable ] )
00443   p |= QUrlInfo::WriteGroup;
00444     if ( perms[ group ][ executable ] )
00445   p |= QUrlInfo::ExeGroup;
00446     if ( perms[ other ][ readable ] )
00447   p |= QUrlInfo::ReadOther;
00448     if ( perms[ other ][ writable ] )
00449   p |= QUrlInfo::WriteOther;
00450     if ( perms[ other ][ executable ] )
00451   p |= QUrlInfo::ExeOther;
00452     info->setPermissions( p );
00453 
00454     // size
00455     tmp = lst[ 4 ];
00456     info->setSize( tmp.toInt() );
00457 
00458     // date and time
00459     QTime time;
00460     QString dateStr;
00461     dateStr += "Sun ";
00462     lst[ 5 ][ 0 ] = lst[ 5 ][ 0 ].upper();
00463     dateStr += lst[ 5 ];
00464     dateStr += ' ';
00465     dateStr += lst[ 6 ];
00466     dateStr += ' ';
00467 
00468     if ( lst[ 7 ].contains( ":" ) ) {
00469   time = QTime( lst[ 7 ].left( 2 ).toInt(), lst[ 7 ].right( 2 ).toInt() );
00470   dateStr += QString::number( QDate::currentDate().year() );
00471     } else {
00472   dateStr += lst[ 7 ];
00473     }
00474 
00475     QDate date = QDate::fromString( dateStr );
00476     info->setLastModified( QDateTime( date, time ) );
00477 
00478     if ( lst[ 7 ].contains( ":" ) ) {
00479   const int futureTolerance = 600;
00480   if( info->lastModified().secsTo( QDateTime::currentDateTime() ) < -futureTolerance ) {
00481       QDateTime dt = info->lastModified();
00482       QDate d = dt.date();
00483       d.setYMD(d.year()-1, d.month(), d.day());
00484       dt.setDate(d);
00485       info->setLastModified(dt);
00486   }
00487     }
00488 
00489     // name
00490     if ( info->isSymLink() )
00491   info->setName( lst[ 8 ].stripWhiteSpace() );
00492     else {
00493   QString n;
00494   for ( uint i = 8; i < (uint) lst.count(); ++i )
00495       n += lst[ i ] + " ";
00496   n = n.stripWhiteSpace();
00497   info->setName( n );
00498     }
00499     return true;
00500 }

Here is the call graph for this function:

void Q3FtpDTP::listInfo ( const QUrlInfo  )  [signal]

Referenced by socketReadyRead().

void Q3FtpDTP::readyRead (  )  [signal]

Referenced by Q3FtpDTP(), and socketReadyRead().

void Q3FtpDTP::dataTransferProgress ( int  ,
int   
) [signal]

Referenced by setBytesTotal(), socketBytesWritten(), socketReadyRead(), and writeData().

void Q3FtpDTP::connectState ( int   )  [signal]

Referenced by socketConnected(), socketConnectionClosed(), socketError(), and socketReadyRead().

void Q3FtpDTP::socketConnected (  )  [private, slot]

Definition at line 502 of file q3ftp.cpp.

References bytesDone, connectState(), CsConnected, emit, qDebug(), Q3SocketDevice::setReceiveBufferSize(), Q3SocketDevice::setSendBufferSize(), socket, and Q3Socket::socketDevice().

Referenced by Q3FtpDTP().

00503 {
00504 #if !defined (Q_WS_QWS)
00505     // Use a large send buffer to reduce the number
00506     // of writeBlocks when download and uploading files.
00507     // The actual size used here (128k) is default on most
00508     // Unixes.
00509     socket.socketDevice()->setSendBufferSize(128 * 1024);
00510     socket.socketDevice()->setReceiveBufferSize(128 * 1024);
00511 #endif
00512 
00513     bytesDone = 0;
00514 #if defined(Q3FTPDTP_DEBUG)
00515     qDebug( "Q3FtpDTP::connectState( CsConnected )" );
00516 #endif
00517     emit connectState( Q3FtpDTP::CsConnected );
00518 }

void Q3FtpDTP::socketReadyRead (  )  [private, slot]

Definition at line 520 of file q3ftp.cpp.

References ba, bytesAvailable(), Q3Socket::bytesAvailable(), bytesDone, bytesTotal, Q3Socket::canReadLine(), Q3Socket::close(), connectState(), CsClosed, Q3FtpPI::currentCommand(), data, QByteArray::data(), dataTransferProgress(), emit, QString::endsWith(), err, i, is_ba, QString::isEmpty(), listInfo(), parseDir(), pi, qDebug(), QIODevice::readLine(), readyRead(), QByteArray::resize(), QByteArray::size(), socket, and QString::startsWith().

Referenced by Q3FtpDTP().

00521 {
00522     if ( pi->currentCommand().isEmpty() ) {
00523   socket.close();
00524 #if defined(Q3FTPDTP_DEBUG)
00525   qDebug( "Q3FtpDTP::connectState( CsClosed )" );
00526 #endif
00527   emit connectState( Q3FtpDTP::CsClosed );
00528   return;
00529     }
00530 
00531     if ( pi->currentCommand().startsWith("LIST") ) {
00532   while ( socket.canReadLine() ) {
00533       QUrlInfo i;
00534       QString line = socket.readLine();
00535 #if defined(Q3FTPDTP_DEBUG)
00536       qDebug( "Q3FtpDTP read (list): '%s'", line.latin1() );
00537 #endif
00538       if ( parseDir( line, "", &i ) ) {
00539     emit listInfo( i );
00540       } else {
00541     // some FTP servers don't return a 550 if the file or directory
00542     // does not exist, but rather write a text to the data socket
00543     // -- try to catch these cases
00544     if ( line.endsWith( "No such file or directory\r\n" ) )
00545         err = line;
00546       }
00547   }
00548     } else {
00549   if ( !is_ba && data.dev ) {
00550       QByteArray ba( socket.bytesAvailable() );
00551       Q_LONG bytesRead = socket.readBlock( ba.data(), ba.size() );
00552       if ( bytesRead < 0 ) {
00553     // ### error handling
00554     return;
00555       }
00556       ba.resize( bytesRead );
00557       bytesDone += bytesRead;
00558 #if defined(Q3FTPDTP_DEBUG)
00559       qDebug( "Q3FtpDTP read: %d bytes (total %d bytes)", (int)bytesRead, bytesDone );
00560 #endif
00561       emit dataTransferProgress( bytesDone, bytesTotal );
00562             if (data.dev)       // make sure it wasn't deleted in the slot
00563                 data.dev->writeBlock( ba );
00564   } else {
00565 #if defined(Q3FTPDTP_DEBUG)
00566       qDebug( "Q3FtpDTP readyRead: %d bytes available (total %d bytes read)", (int)bytesAvailable(), bytesDone );
00567 #endif
00568       emit dataTransferProgress( bytesDone+socket.bytesAvailable(), bytesTotal );
00569       emit readyRead();
00570   }
00571     }
00572 }

void Q3FtpDTP::socketError ( int   )  [private, slot]

Definition at line 574 of file q3ftp.cpp.

References connectState(), CsConnectionRefused, CsHostNotFound, emit, Q3Socket::ErrConnectionRefused, Q3Socket::ErrHostNotFound, and qDebug().

Referenced by Q3FtpDTP().

00575 {
00576     if ( e == Q3Socket::ErrHostNotFound ) {
00577 #if defined(Q3FTPDTP_DEBUG)
00578   qDebug( "Q3FtpDTP::connectState( CsHostNotFound )" );
00579 #endif
00580   emit connectState( Q3FtpDTP::CsHostNotFound );
00581     } else if ( e == Q3Socket::ErrConnectionRefused ) {
00582 #if defined(Q3FTPDTP_DEBUG)
00583   qDebug( "Q3FtpDTP::connectState( CsConnectionRefused )" );
00584 #endif
00585   emit connectState( Q3FtpDTP::CsConnectionRefused );
00586     }
00587 }

void Q3FtpDTP::socketConnectionClosed (  )  [private, slot]

Definition at line 589 of file q3ftp.cpp.

References clearData(), connectState(), CsClosed, data, emit, is_ba, and qDebug().

Referenced by Q3FtpDTP().

00590 {
00591     if ( !is_ba && data.dev ) {
00592   clearData();
00593     }
00594 #if defined(Q3FTPDTP_DEBUG)
00595     qDebug( "Q3FtpDTP::connectState( CsClosed )" );
00596 #endif
00597     emit connectState( Q3FtpDTP::CsClosed );
00598 }

void Q3FtpDTP::socketBytesWritten ( int   )  [private, slot]

Definition at line 600 of file q3ftp.cpp.

References bytesDone, bytesTotal, callWriteData, dataTransferProgress(), emit, qDebug(), and writeData().

Referenced by Q3FtpDTP().

00601 {
00602     bytesDone += bytes;
00603 #if defined(Q3FTPDTP_DEBUG)
00604     qDebug( "Q3FtpDTP::bytesWritten( %d )", bytesDone );
00605 #endif
00606     emit dataTransferProgress( bytesDone, bytesTotal );
00607     if ( callWriteData )
00608   writeData();
00609 }

void Q3FtpDTP::clearData (  )  [inline, private]

Definition at line 123 of file q3ftp.cpp.

References data, and is_ba.

Referenced by abortConnection(), Q3FtpDTP(), socketConnectionClosed(), and writeData().

00124     {
00125   is_ba = false;
00126   data.dev = 0;
00127     }


Member Data Documentation

Q3Socket Q3FtpDTP::socket [private]

Definition at line 129 of file q3ftp.cpp.

Referenced by abortConnection(), bytesAvailable(), connectToHost(), Q3FtpDTP(), readAll(), readBlock(), socketConnected(), socketReadyRead(), socketState(), and writeData().

Q3FtpPI* Q3FtpDTP::pi [private]

Definition at line 130 of file q3ftp.cpp.

Referenced by socketReadyRead().

QString Q3FtpDTP::err [private]

Definition at line 131 of file q3ftp.cpp.

Referenced by clearError(), errorMessage(), hasError(), and socketReadyRead().

int Q3FtpDTP::bytesDone [private]

Definition at line 132 of file q3ftp.cpp.

Referenced by readAll(), readBlock(), setBytesTotal(), socketBytesWritten(), socketConnected(), socketReadyRead(), and writeData().

int Q3FtpDTP::bytesTotal [private]

Definition at line 133 of file q3ftp.cpp.

Referenced by setBytesTotal(), socketBytesWritten(), socketReadyRead(), and writeData().

bool Q3FtpDTP::callWriteData [private]

Definition at line 134 of file q3ftp.cpp.

Referenced by abortConnection(), socketBytesWritten(), and writeData().

QByteArray* Q3FtpDTP::ba [private]

Definition at line 139 of file q3ftp.cpp.

Referenced by setData(), and socketReadyRead().

QIODevice* Q3FtpDTP::dev [private]

Definition at line 140 of file q3ftp.cpp.

Referenced by setDevice().

union { ... } Q3FtpDTP::data [private]

Referenced by clearData(), setData(), setDevice(), socketConnectionClosed(), socketReadyRead(), and writeData().

bool Q3FtpDTP::is_ba [private]

Definition at line 142 of file q3ftp.cpp.

Referenced by clearData(), setData(), setDevice(), socketConnectionClosed(), socketReadyRead(), and writeData().


The documentation for this class was generated from the following file:
Generated on Thu Mar 15 15:57:07 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1