src/qt3support/network/q3socket.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt3Support module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "q3socket.h"
       
    43 #ifndef QT_NO_NETWORK
       
    44 #include "q3ptrlist.h"
       
    45 #include "qtimer.h"
       
    46 #include "q3socketdevice.h"
       
    47 #include "q3dns.h"
       
    48 #include "private/q3membuf_p.h"
       
    49 
       
    50 #include <string.h>
       
    51 #ifndef NO_ERRNO_H
       
    52 #if defined(Q_OS_WINCE)
       
    53 #include "qfunctions_wince.h"
       
    54 #else
       
    55 #include <errno.h>
       
    56 #endif
       
    57 #endif
       
    58 
       
    59 QT_BEGIN_NAMESPACE
       
    60 
       
    61 //#define Q3SOCKET_DEBUG
       
    62 
       
    63 /*
       
    64   Perhaps this private functionality needs to be refactored.
       
    65 
       
    66   Comment from Robert D Gatlin (Intel):
       
    67 
       
    68     It would be nice to have the functionality inherent in Q3Socket available
       
    69     as a separate class as a standard part of the Qt library, something along
       
    70     the line of:
       
    71 
       
    72       class QByteBuffer : public QIODevice { ... }
       
    73 
       
    74     The same class could/would be used within Q3Socket for the Read/Write
       
    75     buffers.
       
    76 
       
    77     The above class could be used in the following way(s):
       
    78 
       
    79 	buffer.open( IO_WriteOnly | IO_Append );
       
    80 	buffer.writeBlock( a ); // a = QByteArray
       
    81 	buffer.close();
       
    82 
       
    83 	QByteArray b;
       
    84 	b.resize( buffer.size() );
       
    85 	buffer.open( IO_ReadOnly );
       
    86 	buffer.readBlock( b.data(), b.size() );
       
    87 	buffer.close();
       
    88 
       
    89     But would also be useable with QDataStream (via QIODevice) with:
       
    90 
       
    91 	buffer.open( IO_WriteOnly | IO_Append );
       
    92 	QDataStream is( &buffer );
       
    93 	is << 100;
       
    94 	buffer.close();
       
    95 
       
    96 	buffer.open( IO_ReadOnly );
       
    97 	QDataStream os( &buffer );
       
    98 	Q_UINT32 x;
       
    99 	os >> x;
       
   100 	buffer.close();
       
   101 
       
   102     The real usefulness is with any situations where data (QByteArray) arrives
       
   103     incrementally (as in Q3Socket and filter case above).
       
   104 
       
   105     I tried using QBuffer, but QBuffer does not trim bytes from the front of
       
   106     the buffer in cases like:
       
   107 
       
   108 	QBuffer buf;
       
   109 	buf.open( IO_ReadOnly );
       
   110 	QDataStream ds( &buf );
       
   111 	Q_INT32 x;
       
   112 	ds >> x;
       
   113 	buf.close();
       
   114 
       
   115     In the above case, buf.size() will be identical before and after the
       
   116     operation with QDataStream. Based on the implementation of QBuffer, it
       
   117     does not appear well suited for this kind of operation.
       
   118 */
       
   119 
       
   120 // Private class for Q3Socket
       
   121 
       
   122 class Q3SocketPrivate {
       
   123 public:
       
   124     Q3SocketPrivate();
       
   125    ~Q3SocketPrivate();
       
   126     void closeSocket();
       
   127     void close();
       
   128     void connectionClosed();
       
   129     void setSocketDevice( Q3Socket *q, Q3SocketDevice *device );
       
   130 
       
   131     Q3Socket::State	state;			// connection state
       
   132     QString		host;			// host name
       
   133     Q_UINT16		port;			// host port
       
   134     Q3SocketDevice      *socket;			// connection socket
       
   135     QSocketNotifier     *rsn, *wsn;		// socket notifiers
       
   136     Q3Membuf		rba;			// read buffer
       
   137     Q_ULONG		readBufferSize;		// limit for the read buffer size
       
   138     Q3PtrList<QByteArray> wba;			// list of write bufs
       
   139     QHostAddress	addr;			// connection address
       
   140     Q3ValueList<QHostAddress> addresses;		// alternatives looked up
       
   141     QIODevice::Offset	wsize;			// write total buf size
       
   142     QIODevice::Offset	windex;			// write index
       
   143 #ifndef QT_NO_DNS
       
   144     Q3Dns	       *dns4;
       
   145     Q3Dns	       *dns6;
       
   146 #endif
       
   147     static Q3PtrList<Q3Socket> sn_read_alreadyCalled; // used to avoid unwanted recursion
       
   148     Q3ValueList<QHostAddress> l4;
       
   149     Q3ValueList<QHostAddress> l6;
       
   150 };
       
   151 
       
   152 Q3PtrList<Q3Socket> Q3SocketPrivate::sn_read_alreadyCalled;
       
   153 
       
   154 Q3SocketPrivate::Q3SocketPrivate()
       
   155     : state(Q3Socket::Idle), host(QString::fromLatin1("")), port(0),
       
   156       socket(0), rsn(0), wsn(0), readBufferSize(0), wsize(0), windex(0)
       
   157 {
       
   158 #ifndef QT_NO_DNS
       
   159     dns4 = 0;
       
   160     dns6 = 0;
       
   161 #endif
       
   162     wba.setAutoDelete( true );
       
   163 }
       
   164 
       
   165 Q3SocketPrivate::~Q3SocketPrivate()
       
   166 {
       
   167     close();
       
   168     delete socket;
       
   169 #ifndef QT_NO_DNS
       
   170     delete dns4;
       
   171     delete dns6;
       
   172 #endif
       
   173 }
       
   174 
       
   175 extern void qDeleteInEventHandler(QObject *o);
       
   176 void Q3SocketPrivate::closeSocket()
       
   177 {
       
   178     // Order is important here - the socket notifiers must go away
       
   179     // before the socket does, otherwise libc or the kernel will
       
   180     // become unhappy.
       
   181     if (rsn) {
       
   182         qDeleteInEventHandler(rsn);
       
   183         rsn = 0;
       
   184     }
       
   185     if (wsn) {
       
   186         qDeleteInEventHandler(wsn);
       
   187         wsn = 0;
       
   188     }
       
   189     if ( socket )
       
   190 	socket->close();
       
   191 }
       
   192 
       
   193 void Q3SocketPrivate::close()
       
   194 {
       
   195     closeSocket();
       
   196     wsize = 0;
       
   197     rba.clear(); wba.clear();
       
   198     windex = 0;
       
   199 }
       
   200 
       
   201 void Q3SocketPrivate::connectionClosed()
       
   202 {
       
   203     // We keep the open state in case there's unread incoming data
       
   204     state = Q3Socket::Idle;
       
   205     closeSocket();
       
   206     wba.clear();
       
   207     windex = wsize = 0;
       
   208 }
       
   209 
       
   210 void Q3SocketPrivate::setSocketDevice( Q3Socket *q, Q3SocketDevice *device )
       
   211 {
       
   212     delete socket;
       
   213     delete rsn;
       
   214     delete wsn;
       
   215 
       
   216     if ( device ) {
       
   217 	socket = device;
       
   218     } else {
       
   219 	socket = new Q3SocketDevice( Q3SocketDevice::Stream,
       
   220 				    ( addr.isIPv4Address() ?
       
   221 				      Q3SocketDevice::IPv4 :
       
   222 				      Q3SocketDevice::IPv6 ), 0 );
       
   223 	socket->setBlocking( false );
       
   224 	socket->setAddressReusable( true );
       
   225     }
       
   226 
       
   227     rsn = new QSocketNotifier( socket->socket(),
       
   228 			       QSocketNotifier::Read, q, "read" );
       
   229     wsn = new QSocketNotifier( socket->socket(),
       
   230 			       QSocketNotifier::Write, q, "write" );
       
   231 
       
   232     QObject::connect( rsn, SIGNAL(activated(int)), q, SLOT(sn_read()) );
       
   233     rsn->setEnabled( false );
       
   234     QObject::connect( wsn, SIGNAL(activated(int)), q, SLOT(sn_write()) );
       
   235     wsn->setEnabled( false );
       
   236 }
       
   237 
       
   238 /*!
       
   239     \class Q3Socket
       
   240     \brief The Q3Socket class provides a buffered TCP connection.
       
   241 
       
   242     \compat
       
   243 
       
   244     It provides a totally non-blocking QIODevice, and modifies and
       
   245     extends the API of QIODevice with socket-specific code.
       
   246 
       
   247     The functions you're likely to call most are connectToHost(),
       
   248     bytesAvailable(), canReadLine() and the ones it inherits from
       
   249     QIODevice.
       
   250 
       
   251     connectToHost() is the most-used function. As its name implies,
       
   252     it opens a connection to a named host.
       
   253 
       
   254     Most network protocols are either packet-oriented or
       
   255     line-oriented. canReadLine() indicates whether a connection
       
   256     contains an entire unread line or not, and bytesAvailable()
       
   257     returns the number of bytes available for reading.
       
   258 
       
   259     The signals error(), connected(), readyRead() and
       
   260     connectionClosed() inform you of the progress of the connection.
       
   261     There are also some less commonly used signals. hostFound() is
       
   262     emitted when connectToHost() has finished its DNS lookup and is
       
   263     starting its TCP connection. delayedCloseFinished() is emitted
       
   264     when close() succeeds. bytesWritten() is emitted when Q3Socket
       
   265     moves data from its "to be written" queue into the TCP
       
   266     implementation.
       
   267 
       
   268     There are several access functions for the socket: state() returns
       
   269     whether the object is idle, is doing a DNS lookup, is connecting,
       
   270     has an operational connection, etc. address() and port() return
       
   271     the IP address and port used for the connection. The peerAddress()
       
   272     and peerPort() functions return the IP address and port used by
       
   273     the peer, and peerName() returns the name of the peer (normally
       
   274     the name that was passed to connectToHost()). socketDevice()
       
   275     returns a pointer to the Q3SocketDevice used for this socket.
       
   276 
       
   277     Q3Socket inherits QIODevice, and reimplements some functions. In
       
   278     general, you can treat it as a QIODevice for writing, and mostly
       
   279     also for reading. The match isn't perfect, since the QIODevice
       
   280     API is designed for devices that are controlled by the same
       
   281     machine, and an asynchronous peer-to-peer network connection isn't
       
   282     quite like that. For example, there is nothing that matches
       
   283     QIODevice::size() exactly. The documentation for open(), close(),
       
   284     flush(), size(), at(), atEnd(), readBlock(), writeBlock(),
       
   285     getch(), putch(), ungetch() and readLine() describes the
       
   286     differences in detail.
       
   287 
       
   288     \warning Q3Socket is not suitable for use in threads. If you need
       
   289     to uses sockets in threads use the lower-level Q3SocketDevice class.
       
   290 
       
   291     \sa Q3SocketDevice, QHostAddress, QSocketNotifier
       
   292 */
       
   293 
       
   294 
       
   295 /*!
       
   296     Creates a Q3Socket object in Q3Socket::Idle state.
       
   297 
       
   298     The \a parent and \a name arguments are passed on to the QObject
       
   299     constructor.
       
   300 */
       
   301 
       
   302 Q3Socket::Q3Socket( QObject *parent, const char *name )
       
   303     : QIODevice( parent )
       
   304 {
       
   305     setObjectName(QLatin1String(name));
       
   306     d = new Q3SocketPrivate;
       
   307     setSocketDevice( 0 );
       
   308     resetStatus();
       
   309 }
       
   310 
       
   311 
       
   312 /*!
       
   313     Destroys the socket. Closes the connection if necessary.
       
   314 
       
   315     \sa close()
       
   316 */
       
   317 
       
   318 Q3Socket::~Q3Socket()
       
   319 {
       
   320 #if defined(Q3SOCKET_DEBUG)
       
   321     qDebug( "Q3Socket (%s): Destroy", name() );
       
   322 #endif
       
   323     if ( state() != Idle )
       
   324 	close();
       
   325     Q_ASSERT( d != 0 );
       
   326     delete d;
       
   327 }
       
   328 
       
   329 
       
   330 /*!
       
   331     Returns a pointer to the internal socket device.
       
   332 
       
   333     There is normally no need to manipulate the socket device directly
       
   334     since this class does the necessary setup for most applications.
       
   335 */
       
   336 
       
   337 Q3SocketDevice *Q3Socket::socketDevice()
       
   338 {
       
   339     return d->socket;
       
   340 }
       
   341 
       
   342 /*!
       
   343     Sets the internal socket device to \a device. Passing a \a device
       
   344     of 0 will cause the internal socket device to be used. Any
       
   345     existing connection will be disconnected before using the new \a
       
   346     device.
       
   347 
       
   348     The new device should not be connected before being associated
       
   349     with a Q3Socket; after setting the socket call connectToHost() to
       
   350     make the connection.
       
   351 
       
   352     This function is useful if you need to subclass Q3SocketDevice and
       
   353     want to use the Q3Socket API, for example, to implement Unix domain
       
   354     sockets.
       
   355 */
       
   356 
       
   357 void Q3Socket::setSocketDevice( Q3SocketDevice *device )
       
   358 {
       
   359     if ( state() != Idle )
       
   360 	close();
       
   361     d->setSocketDevice( this, device );
       
   362 }
       
   363 
       
   364 /*!
       
   365     \enum Q3Socket::State
       
   366 
       
   367     This enum defines the connection states:
       
   368 
       
   369     \value Idle if there is no connection
       
   370     \value HostLookup during a DNS lookup
       
   371     \value Connecting during TCP connection establishment
       
   372     \value Connected when there is an operational connection
       
   373     \value Closing if the socket is closing down, but is not yet closed.
       
   374     \omitvalue Connection
       
   375 */
       
   376 
       
   377 /*!
       
   378     Returns the current state of the socket connection.
       
   379 
       
   380     \sa Q3Socket::State
       
   381 */
       
   382 
       
   383 Q3Socket::State Q3Socket::state() const
       
   384 {
       
   385     return d->state;
       
   386 }
       
   387 
       
   388 
       
   389 #ifndef QT_NO_DNS
       
   390 
       
   391 /*!
       
   392     Attempts to make a connection to \a host on the specified \a port
       
   393     and return immediately.
       
   394 
       
   395     Any connection or pending connection is closed immediately, and
       
   396     Q3Socket goes into the \c HostLookup state. When the lookup
       
   397     succeeds, it emits hostFound(), starts a TCP connection and goes
       
   398     into the \c Connecting state. Finally, when the connection
       
   399     succeeds, it emits connected() and goes into the \c Connected
       
   400     state. If there is an error at any point, it emits error().
       
   401 
       
   402     \a host may be an IP address in string form, or it may be a DNS
       
   403     name. Q3Socket will do a normal DNS lookup if required. Note that
       
   404     \a port is in native byte order, unlike some other libraries.
       
   405 
       
   406     \sa state()
       
   407 */
       
   408 
       
   409 void Q3Socket::connectToHost( const QString &host, Q_UINT16 port )
       
   410 {
       
   411 #if defined(Q3SOCKET_DEBUG)
       
   412     qDebug( "Q3Socket (%s)::connectToHost: host %s, port %d",
       
   413 	    name(), host.ascii(), port );
       
   414 #endif
       
   415     setSocketIntern( -1 );
       
   416     d->state = HostLookup;
       
   417     d->host = host;
       
   418     d->port = port;
       
   419     d->dns4 = new Q3Dns( host, Q3Dns::A );
       
   420     d->dns6 = new Q3Dns( host, Q3Dns::Aaaa );
       
   421 
       
   422     // try if the address is already available (for faster connecting...)
       
   423     tryConnecting();
       
   424     if ( d->state == HostLookup ) {
       
   425 	connect( d->dns4, SIGNAL(resultsReady()),
       
   426 		 this, SLOT(tryConnecting()) );
       
   427 	connect( d->dns6, SIGNAL(resultsReady()),
       
   428 		 this, SLOT(tryConnecting()) );
       
   429     }
       
   430 }
       
   431 
       
   432 #endif
       
   433 
       
   434 
       
   435 /*!
       
   436     This private slots continues the connection process where
       
   437     connectToHost() leaves off.
       
   438 */
       
   439 
       
   440 void Q3Socket::tryConnecting()
       
   441 {
       
   442 #if defined(Q3SOCKET_DEBUG)
       
   443     qDebug( "Q3Socket (%s)::tryConnecting()", name() );
       
   444 #endif
       
   445     // ### this ifdef isn't correct - addresses() also does /etc/hosts and
       
   446     // numeric-address-as-string handling.
       
   447 #ifndef QT_NO_DNS
       
   448 
       
   449     if ( d->dns4 ) {
       
   450 	d->l4 = d->dns4->addresses();
       
   451 	if ( !d->l4.isEmpty() || !d->dns4->isWorking() ) {
       
   452 #if defined(Q3SOCKET_DEBUG)
       
   453 	    qDebug( "Q3Socket (%s)::tryConnecting: host %s, port %d: "
       
   454 		    "%d IPv4 addresses",
       
   455 		    name(), d->host.ascii(), d->port, d->l4.count() );
       
   456 #endif
       
   457 	    delete d->dns4;
       
   458 	    d->dns4 = 0;
       
   459 	}
       
   460     }
       
   461 
       
   462     if ( d->dns6 ) {
       
   463 	d->l6 = d->dns6->addresses();
       
   464 	if ( !d->l6.isEmpty() || !d->dns6->isWorking() ) {
       
   465 #if defined(Q3SOCKET_DEBUG)
       
   466 	    qDebug( "Q3Socket (%s)::tryConnecting: host %s, port %d: "
       
   467 		    "%d IPv6 addresses",
       
   468 		    name(), d->host.ascii(), d->port, d->l6.count() );
       
   469 #endif
       
   470 	    delete d->dns6;
       
   471 	    d->dns6 = 0;
       
   472 	}
       
   473     }
       
   474 
       
   475     if ( d->state == HostLookup ) {
       
   476 	if ( d->l4.isEmpty() && d->l6.isEmpty() &&
       
   477 	     !d->dns4 && !d->dns6 ) {
       
   478 	    // no results and we're not still looking: give up
       
   479 	    d->state = Idle;
       
   480 	    emit error( ErrHostNotFound );
       
   481 	    return;
       
   482 	}
       
   483 	if ( d->l4.isEmpty() && d->l6.isEmpty() ) {
       
   484 	    // no results (yet): try again later
       
   485 	    return;
       
   486 	}
       
   487 
       
   488 	// we've found something. press on with that. if we later find
       
   489 	// more, fine.
       
   490 	emit hostFound();
       
   491 	d->state = Connecting;
       
   492     }
       
   493 
       
   494     if ( d->state == Connecting ) {
       
   495 	d->addresses += d->l4;
       
   496 	d->addresses += d->l6;
       
   497 	d->l4.clear();
       
   498 	d->l6.clear();
       
   499 
       
   500 	// try one address at a time, falling back to the next one if
       
   501 	// there is a connection failure. (should also support a timeout,
       
   502 	// or do multiple TCP-level connects at a time, with staggered
       
   503 	// starts to avoid bandwidth waste and cause fewer
       
   504 	// "connect-and-abort" errors. but that later.)
       
   505 	bool stuck = true;
       
   506 	while( stuck ) {
       
   507 	    stuck = false;
       
   508 	    if ( d->socket &&
       
   509 		 d->socket->connect( d->addr, d->port ) == false ) {
       
   510 		if ( d->socket->error() == Q3SocketDevice::NoError ) {
       
   511 		    if ( d->wsn )
       
   512 			d->wsn->setEnabled( true );
       
   513 		    return; // not serious, try again later
       
   514 		}
       
   515 
       
   516 #if defined(Q3SOCKET_DEBUG)
       
   517 		qDebug( "Q3Socket (%s)::tryConnecting: "
       
   518 			"Gave up on IP address %s",
       
   519 			name(), d->socket->peerAddress().toString().ascii() );
       
   520 #endif
       
   521 		delete d->wsn;
       
   522 		d->wsn = 0;
       
   523 		delete d->rsn;
       
   524 		d->rsn = 0;
       
   525 		delete d->socket;
       
   526 		d->socket = 0;
       
   527 
       
   528                 if(d->addresses.isEmpty()) {
       
   529                     emit error( ErrConnectionRefused );
       
   530                     return;
       
   531                 }
       
   532             }
       
   533 	    // if the host has more addresses, try another some.
       
   534 	    if ( d->socket == 0 && !d->addresses.isEmpty() ) {
       
   535 		d->addr = *d->addresses.begin();
       
   536 		d->addresses.remove( d->addresses.begin() );
       
   537 		d->setSocketDevice( this, 0 );
       
   538 		stuck = true;
       
   539 #if defined(Q3SOCKET_DEBUG)
       
   540 		qDebug( "Q3Socket (%s)::tryConnecting: Trying IP address %s",
       
   541 			name(), d->addr.toString().ascii() );
       
   542 #endif
       
   543 	    }
       
   544 	};
       
   545 
       
   546 	// The socket write notifier will fire when the connection succeeds
       
   547 	if ( d->wsn )
       
   548 	    d->wsn->setEnabled( true );
       
   549     }
       
   550 #endif
       
   551 }
       
   552 
       
   553 /*!
       
   554     \enum Q3Socket::Error
       
   555 
       
   556     This enum specifies the possible errors:
       
   557     \value ErrConnectionRefused if the connection was refused
       
   558     \value ErrHostNotFound if the host was not found
       
   559     \value ErrSocketRead if a read from the socket failed
       
   560 */
       
   561 
       
   562 /*!
       
   563     \fn void Q3Socket::error(int error)
       
   564 
       
   565     This signal is emitted after an error occurred. The \a error parameter is
       
   566     the \l Error value.
       
   567 */
       
   568 
       
   569 /*!
       
   570     \fn void Q3Socket::hostFound()
       
   571 
       
   572     This signal is emitted after connectToHost() has been called and
       
   573     the host lookup has succeeded.
       
   574 
       
   575     \sa connected()
       
   576 */
       
   577 
       
   578 
       
   579 /*!
       
   580     \fn void Q3Socket::connected()
       
   581 
       
   582     This signal is emitted after connectToHost() has been called and a
       
   583     connection has been successfully established.
       
   584 
       
   585     \sa connectToHost(), connectionClosed()
       
   586 */
       
   587 
       
   588 
       
   589 /*!
       
   590     \fn void Q3Socket::connectionClosed()
       
   591 
       
   592     This signal is emitted when the other end has closed the
       
   593     connection. The read buffers may contain buffered input data which
       
   594     you can read after the connection was closed.
       
   595 
       
   596     \sa connectToHost(), close()
       
   597 */
       
   598 
       
   599 
       
   600 /*!
       
   601     \fn void Q3Socket::delayedCloseFinished()
       
   602 
       
   603     This signal is emitted when a delayed close is finished.
       
   604 
       
   605     If you call close() and there is buffered output data to be
       
   606     written, Q3Socket goes into the Q3Socket::Closing state and
       
   607     returns immediately. It will then keep writing to the socket until
       
   608     all the data has been written. Then, the delayedCloseFinished()
       
   609     signal is emitted.
       
   610 
       
   611     \sa close()
       
   612 */
       
   613 
       
   614 
       
   615 /*!
       
   616     \fn void Q3Socket::readyRead()
       
   617 
       
   618     This signal is emitted every time there is new incoming data.
       
   619 
       
   620     Bear in mind that new incoming data is only reported once; if you do not
       
   621     read all the data, this class buffers the data and you can read it later,
       
   622     but no signal is emitted unless new data arrives. A good practice is to
       
   623     read all data in the slot connected to this signal unless you are sure that
       
   624     you need to receive more data to be able to process it.
       
   625 
       
   626     \sa readBlock(), readLine(), bytesAvailable()
       
   627 */
       
   628 
       
   629 
       
   630 /*!
       
   631     \fn void Q3Socket::bytesWritten( int nbytes )
       
   632 
       
   633     This signal is emitted when data has been written to the network.
       
   634     The \a nbytes parameter specifies how many bytes were written.
       
   635 
       
   636     The bytesToWrite() function is often used in the same context; it
       
   637     indicates how many buffered bytes there are left to write.
       
   638 
       
   639     \sa writeBlock(), bytesToWrite()
       
   640 */
       
   641 
       
   642 
       
   643 /*!
       
   644     Opens the socket using the specified QIODevice file mode \a m.
       
   645     This function is called automatically when needed and you should
       
   646     not call it yourself.
       
   647 
       
   648     \sa close()
       
   649 */
       
   650 
       
   651 bool Q3Socket::open( OpenMode m )
       
   652 {
       
   653     if ( isOpen() ) {
       
   654 #if defined(QT_CHECK_STATE)
       
   655 	qWarning( "Q3Socket::open: Already open" );
       
   656 #endif
       
   657 	return false;
       
   658     }
       
   659     QIODevice::setOpenMode( m & ReadWrite );
       
   660     return true;
       
   661 }
       
   662 
       
   663 /*!
       
   664     \fn bool Q3Socket::open(int m)
       
   665     \overload
       
   666 */
       
   667 
       
   668 /*!
       
   669     Closes the socket.
       
   670 
       
   671     The read buffer is cleared.
       
   672 
       
   673     If the output buffer is empty, the state is set to \c
       
   674     Q3Socket::Idle and the connection is terminated immediately. If the
       
   675     output buffer still contains data to be written, Q3Socket goes into
       
   676     the Q3Socket::Closing state and the rest of the data will be
       
   677     written. When all of the outgoing data have been written, the
       
   678     state is set to Q3Socket::Idle and the connection is terminated.
       
   679     At this point, the delayedCloseFinished() signal is emitted.
       
   680 
       
   681     If you don't want that the data of the output buffer is written, call
       
   682     clearPendingData() before you call close().
       
   683 
       
   684     \sa state(), bytesToWrite() clearPendingData()
       
   685 */
       
   686 
       
   687 void Q3Socket::close()
       
   688 {
       
   689     if ( !isOpen() || d->state == Idle )	// already closed
       
   690 	return;
       
   691     if ( d->state == Closing )
       
   692 	return;
       
   693     if ( !d->rsn || !d->wsn )
       
   694 	return;
       
   695 #if defined(Q3SOCKET_DEBUG)
       
   696     qDebug( "Q3Socket (%s): close socket", name() );
       
   697 #endif
       
   698     if ( d->socket && d->wsize ) {		// there's data to be written
       
   699 	d->state = Closing;
       
   700 	if ( d->rsn )
       
   701 	    d->rsn->setEnabled( false );
       
   702 	if ( d->wsn )
       
   703 	    d->wsn->setEnabled( true );
       
   704 	d->rba.clear();				// clear incoming data
       
   705 	return;
       
   706     }
       
   707     resetStatus();
       
   708     setOpenMode(NotOpen);
       
   709     d->close();
       
   710     d->state = Idle;
       
   711 }
       
   712 
       
   713 
       
   714 /*!
       
   715     This function consumes \a nbytes bytes of data from the write
       
   716     buffer.
       
   717 */
       
   718 
       
   719 bool Q3Socket::consumeWriteBuf( Q_ULONG nbytes )
       
   720 {
       
   721     if ( nbytes <= 0 || (qint64)nbytes > d->wsize )
       
   722 	return false;
       
   723 #if defined(Q3SOCKET_DEBUG)
       
   724     qDebug( "Q3Socket (%s): skipWriteBuf %d bytes", name(), (int)nbytes );
       
   725 #endif
       
   726     d->wsize -= nbytes;
       
   727     for ( ;; ) {
       
   728 	QByteArray *a = d->wba.first();
       
   729 	if ( (qint64)(d->windex + nbytes) >= a->size() ) {
       
   730 	    nbytes -= a->size() - d->windex;
       
   731 	    d->wba.remove();
       
   732 	    d->windex = 0;
       
   733 	    if ( nbytes == 0 )
       
   734 		break;
       
   735 	} else {
       
   736 	    d->windex += nbytes;
       
   737 	    break;
       
   738 	}
       
   739     }
       
   740     return true;
       
   741 }
       
   742 
       
   743 
       
   744 
       
   745 /*!
       
   746     Implementation of the abstract virtual QIODevice::flush() function.
       
   747     This function always returns true.
       
   748 */
       
   749 
       
   750 bool Q3Socket::flush()
       
   751 {
       
   752     if ( !d->socket )
       
   753         return true;
       
   754     bool osBufferFull = false;
       
   755     int consumed = 0;
       
   756     while ( !osBufferFull && d->state >= Connecting && d->wsize > 0 ) {
       
   757 #if defined(Q3SOCKET_DEBUG)
       
   758 	qDebug( "Q3Socket (%s): flush: Write data to the socket", name() );
       
   759 #endif
       
   760 	QByteArray *a = d->wba.first();
       
   761 	int nwritten;
       
   762 	int i = 0;
       
   763 	if ( (int)a->size() - d->windex < 1460 ) {
       
   764 	    // Concatenate many smaller blocks.  the first may be
       
   765 	    // partial, but each subsequent block is copied entirely
       
   766 	    // or not at all.  the sizes here are picked so that we
       
   767 	    // generally won't trigger nagle's algorithm in the tcp
       
   768 	    // implementation: we concatenate if we'd otherwise send
       
   769 	    // less than PMTU bytes (we assume PMTU is 1460 bytes),
       
   770 	    // and concatenate up to the largest payload TCP/IP can
       
   771 	    // carry.  with these precautions, nagle's algorithm
       
   772 	    // should apply only when really appropriate.
       
   773 	    QByteArray out( 65536 );
       
   774 	    int j = d->windex;
       
   775 	    int s = a->size() - j;
       
   776 	    while ( a && i+s < (int)out.size() ) {
       
   777 		memcpy( out.data()+i, a->data()+j, s );
       
   778 		j = 0;
       
   779 		i += s;
       
   780 		a = d->wba.next();
       
   781 		s = a ? a->size() : 0;
       
   782 	    }
       
   783 	    nwritten = d->socket->write( out.data(), i );
       
   784 	    if ( d->wsn )
       
   785 		d->wsn->setEnabled( false ); // the QSocketNotifier documentation says so
       
   786 	} else {
       
   787 	    // Big block, write it immediately
       
   788 	    i = a->size() - d->windex;
       
   789 	    nwritten = d->socket->write( a->data() + d->windex, i );
       
   790 	    if ( d->wsn )
       
   791 		d->wsn->setEnabled( false ); // the QSocketNotifier documentation says so
       
   792 	}
       
   793 	if ( nwritten > 0 ) {
       
   794 	    if ( consumeWriteBuf( nwritten ) )
       
   795 		consumed += nwritten;
       
   796 	}
       
   797 	if ( nwritten < i )
       
   798 	    osBufferFull = true;
       
   799     }
       
   800     if ( consumed > 0 ) {
       
   801 #if defined(Q3SOCKET_DEBUG)
       
   802 	qDebug( "Q3Socket (%s): flush: wrote %d bytes, %d left",
       
   803 		name(), consumed, (int)d->wsize );
       
   804 #endif
       
   805 	emit bytesWritten( consumed );
       
   806     }
       
   807     if ( d->state == Closing && d->wsize == 0 ) {
       
   808 #if defined(Q3SOCKET_DEBUG)
       
   809 	qDebug( "Q3Socket (%s): flush: Delayed close done. Terminating.",
       
   810 		name() );
       
   811 #endif
       
   812 	resetStatus();
       
   813 	setOpenMode(NotOpen);
       
   814 	d->close();
       
   815 	d->state = Idle;
       
   816 	emit delayedCloseFinished();
       
   817 	return true;
       
   818     }
       
   819     if ( !d->socket->isOpen() ) {
       
   820 	d->connectionClosed();
       
   821 	emit connectionClosed();
       
   822 	return true;
       
   823     }
       
   824     if ( d->wsn )
       
   825 	d->wsn->setEnabled( d->wsize > 0 ); // write if there's data
       
   826     return true;
       
   827 }
       
   828 
       
   829 
       
   830 /*!
       
   831     Returns the number of incoming bytes that can be read right now
       
   832     (like bytesAvailable()).
       
   833 */
       
   834 
       
   835 QIODevice::Offset Q3Socket::size() const
       
   836 {
       
   837     return (Offset)bytesAvailable();
       
   838 }
       
   839 
       
   840 
       
   841 /*!
       
   842     Returns the current read index. Since Q3Socket is a sequential
       
   843     device, the current read index is always zero.
       
   844 */
       
   845 
       
   846 QIODevice::Offset Q3Socket::at() const
       
   847 {
       
   848     return 0;
       
   849 }
       
   850 
       
   851 
       
   852 /*!
       
   853     \overload
       
   854 
       
   855     Moves the read index forward to \a index and returns true if the
       
   856     operation was successful; otherwise returns false. Moving the
       
   857     index forward means skipping incoming data.
       
   858 */
       
   859 
       
   860 bool Q3Socket::at( Offset index )
       
   861 {
       
   862     if ( index > d->rba.size() )
       
   863 	return false;
       
   864     d->rba.consumeBytes( (Q_ULONG)index, 0 );			// throw away data 0..index-1
       
   865     // After we read data from our internal buffer, if we use the
       
   866     // setReadBufferSize() to limit our buffer, we might now be able to
       
   867     // read more data in our buffer. So enable the read socket notifier,
       
   868     // but do this only if we are not in a slot connected to the
       
   869     // readyRead() signal since this might cause a bad recursive behavior.
       
   870     // We can test for this condition by looking at the
       
   871     // sn_read_alreadyCalled flag.
       
   872     if ( d->rsn && Q3SocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )
       
   873 	d->rsn->setEnabled( true );
       
   874     return true;
       
   875 }
       
   876 
       
   877 
       
   878 /*!
       
   879     Returns true if there is no more data to read; otherwise returns false.
       
   880 */
       
   881 
       
   882 bool Q3Socket::atEnd() const
       
   883 {
       
   884     if ( d->socket == 0 )
       
   885 	return true;
       
   886     Q3Socket * that = (Q3Socket *)this;
       
   887     if ( that->d->socket->bytesAvailable() )	// a little slow, perhaps...
       
   888 	that->sn_read();
       
   889     return that->d->rba.size() == 0;
       
   890 }
       
   891 
       
   892 
       
   893 /*!
       
   894     Returns the number of incoming bytes that can be read, i.e. the
       
   895     size of the input buffer. Equivalent to size().
       
   896 
       
   897     \sa bytesToWrite()
       
   898 */
       
   899 
       
   900 qint64 Q3Socket::bytesAvailable() const
       
   901 {
       
   902     if ( d->socket == 0 )
       
   903 	return 0;
       
   904     Q3Socket * that = (Q3Socket *)this;
       
   905     if ( that->d->socket->bytesAvailable() ) // a little slow, perhaps...
       
   906 	(void)that->sn_read();
       
   907     return that->d->rba.size() + QIODevice::bytesAvailable();
       
   908 }
       
   909 
       
   910 
       
   911 /*!
       
   912     Wait up to \a msecs milliseconds for more data to be available.
       
   913 
       
   914     If \a msecs is -1 the call will block indefinitely.
       
   915 
       
   916     Returns the number of bytes available.
       
   917 
       
   918     If \a timeout is non-null and no error occurred (i.e. it does not
       
   919     return -1): this function sets *\a timeout to true, if the reason
       
   920     for returning was that the timeout was reached; otherwise it sets
       
   921     *\a timeout to false. This is useful to find out if the peer
       
   922     closed the connection.
       
   923 
       
   924     \warning This is a blocking call and should be avoided in event
       
   925     driven applications.
       
   926 
       
   927     \sa bytesAvailable()
       
   928 */
       
   929 
       
   930 Q_ULONG Q3Socket::waitForMore( int msecs, bool *timeout ) const
       
   931 {
       
   932     if ( d->socket == 0 )
       
   933 	return 0;
       
   934     Q3Socket * that = (Q3Socket *)this;
       
   935     if ( that->d->socket->waitForMore( msecs, timeout ) > 0 )
       
   936 	(void)that->sn_read( true );
       
   937     return that->d->rba.size();
       
   938 }
       
   939 
       
   940 /*! \overload
       
   941 */
       
   942 
       
   943 Q_ULONG Q3Socket::waitForMore( int msecs ) const
       
   944 {
       
   945     return waitForMore( msecs, 0 );
       
   946 }
       
   947 
       
   948 /*!
       
   949     Returns the number of bytes that are waiting to be written, i.e.
       
   950     the size of the output buffer.
       
   951 
       
   952     \sa bytesAvailable() clearPendingData()
       
   953 */
       
   954 
       
   955 qint64 Q3Socket::bytesToWrite() const
       
   956 {
       
   957     return d->wsize;
       
   958 }
       
   959 
       
   960 /*!
       
   961     Deletes the data that is waiting to be written. This is useful if you want
       
   962     to close the socket without waiting for all the data to be written.
       
   963 
       
   964     \sa bytesToWrite() close() delayedCloseFinished()
       
   965 */
       
   966 
       
   967 void Q3Socket::clearPendingData()
       
   968 {
       
   969     d->wba.clear();
       
   970     d->windex = d->wsize = 0;
       
   971 }
       
   972 
       
   973 /*!
       
   974     Reads \a maxlen bytes from the socket into \a data and returns the
       
   975     number of bytes read. Returns -1 if an error occurred.
       
   976 */
       
   977 
       
   978 qint64 Q3Socket::readData( char *data, qint64 maxlen )
       
   979 {
       
   980     if ( data == 0 && maxlen != 0 ) {
       
   981 #if defined(QT_CHECK_NULL)
       
   982 	qWarning( "Q3Socket::readBlock: Null pointer error" );
       
   983 #endif
       
   984 	return -1;
       
   985     }
       
   986     if ( !isOpen() ) {
       
   987 #if defined(QT_CHECK_STATE)
       
   988 	qWarning( "Q3Socket::readBlock: Socket is not open" );
       
   989 #endif
       
   990 	return -1;
       
   991     }
       
   992     if ( maxlen >= d->rba.size() )
       
   993 	maxlen = d->rba.size();
       
   994 #if defined(Q3SOCKET_DEBUG)
       
   995     qDebug( "Q3Socket (%s): readBlock %d bytes", name(), (int)maxlen );
       
   996 #endif
       
   997     d->rba.consumeBytes( maxlen, data );
       
   998     // After we read data from our internal buffer, if we use the
       
   999     // setReadBufferSize() to limit our buffer, we might now be able to
       
  1000     // read more data in our buffer. So enable the read socket notifier,
       
  1001     // but do this only if we are not in a slot connected to the
       
  1002     // readyRead() signal since this might cause a bad recursive behavior.
       
  1003     // We can test for this condition by looking at the
       
  1004     // sn_read_alreadyCalled flag.
       
  1005     if ( d->rsn && Q3SocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )
       
  1006 	d->rsn->setEnabled( true );
       
  1007     return maxlen;
       
  1008 }
       
  1009 
       
  1010 
       
  1011 /*!
       
  1012     Writes \a len bytes to the socket from \a data and returns the
       
  1013     number of bytes written. Returns -1 if an error occurred.
       
  1014 */
       
  1015 
       
  1016 qint64 Q3Socket::writeData( const char *data, qint64 len )
       
  1017 {
       
  1018 #if defined(QT_CHECK_NULL)
       
  1019     if ( data == 0 && len != 0 ) {
       
  1020 	qWarning( "Q3Socket::writeBlock: Null pointer error" );
       
  1021     }
       
  1022 #endif
       
  1023 #if defined(QT_CHECK_STATE)
       
  1024     if ( !isOpen() ) {
       
  1025 	qWarning( "Q3Socket::writeBlock: Socket is not open" );
       
  1026 	return -1;
       
  1027     }
       
  1028 #endif
       
  1029 #if defined(QT_CHECK_STATE)
       
  1030     if ( d->state == Closing ) {
       
  1031 	qWarning( "Q3Socket::writeBlock: Cannot write, socket is closing" );
       
  1032     }
       
  1033 #endif
       
  1034     if ( len == 0 || d->state == Closing || d->state == Idle )
       
  1035 	return 0;
       
  1036     QByteArray *a = d->wba.last();
       
  1037 
       
  1038     // next bit is sensitive.  if we're writing really small chunks,
       
  1039     // try to buffer up since system calls are expensive, and nagle's
       
  1040     // algorithm is even more expensive.  but if anything even
       
  1041     // remotely large is being written, try to issue a write at once.
       
  1042 
       
  1043     bool writeNow = ( d->wsize + len >= 1400 || len > 512 );
       
  1044 
       
  1045     if ( a && a->size() + len < 128 ) {
       
  1046 	// small buffer, resize
       
  1047 	int i = a->size();
       
  1048 	a->resize( i+len );
       
  1049 	memcpy( a->data()+i, data, len );
       
  1050     } else {
       
  1051 	// append new buffer
       
  1052 	a = new QByteArray( len );
       
  1053 	memcpy( a->data(), data, len );
       
  1054 	d->wba.append( a );
       
  1055     }
       
  1056     d->wsize += len;
       
  1057     if ( writeNow )
       
  1058 	flush();
       
  1059     else if ( d->wsn )
       
  1060 	d->wsn->setEnabled( true );
       
  1061 #if defined(Q3SOCKET_DEBUG)
       
  1062     qDebug( "Q3Socket (%s): writeBlock %d bytes", name(), (int)len );
       
  1063 #endif
       
  1064     return len;
       
  1065 }
       
  1066 
       
  1067 
       
  1068 /*!
       
  1069     Reads a single byte/character from the internal read buffer.
       
  1070     Returns the byte/character read, or -1 if there is nothing to be
       
  1071     read.
       
  1072 
       
  1073     \sa bytesAvailable(), putch()
       
  1074 */
       
  1075 
       
  1076 int Q3Socket::getch()
       
  1077 {
       
  1078     if ( isOpen() && d->rba.size() > 0 ) {
       
  1079 	uchar c;
       
  1080 	d->rba.consumeBytes( 1, (char*)&c );
       
  1081 	// After we read data from our internal buffer, if we use the
       
  1082 	// setReadBufferSize() to limit our buffer, we might now be able to
       
  1083 	// read more data in our buffer. So enable the read socket notifier,
       
  1084 	// but do this only if we are not in a slot connected to the
       
  1085 	// readyRead() signal since this might cause a bad recursive behavior.
       
  1086 	// We can test for this condition by looking at the
       
  1087 	// sn_read_alreadyCalled flag.
       
  1088 	if ( d->rsn && Q3SocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )
       
  1089 	    d->rsn->setEnabled( true );
       
  1090 	return c;
       
  1091     }
       
  1092     return -1;
       
  1093 }
       
  1094 
       
  1095 
       
  1096 /*!
       
  1097     Writes the character \a ch to the output buffer.
       
  1098 
       
  1099     Returns \a ch, or -1 if an error occurred.
       
  1100 
       
  1101     \sa getch()
       
  1102 */
       
  1103 
       
  1104 int Q3Socket::putch( int ch )
       
  1105 {
       
  1106     char buf[2];
       
  1107     buf[0] = ch;
       
  1108     return writeBlock(buf, 1) == 1 ? ch : -1;
       
  1109 }
       
  1110 
       
  1111 
       
  1112 /*!
       
  1113     This implementation of the virtual function QIODevice::ungetch()
       
  1114     prepends the character \a ch to the read buffer so that the next
       
  1115     read returns this character as the first character of the output.
       
  1116 */
       
  1117 
       
  1118 int Q3Socket::ungetch( int ch )
       
  1119 {
       
  1120 #if defined(QT_CHECK_STATE)
       
  1121     if ( !isOpen() ) {
       
  1122 	qWarning( "Q3Socket::ungetch: Socket not open" );
       
  1123 	return -1;
       
  1124     }
       
  1125 #endif
       
  1126     return d->rba.ungetch( ch );
       
  1127 }
       
  1128 
       
  1129 
       
  1130 /*!
       
  1131     Returns true if it's possible to read an entire line of text from
       
  1132     this socket at this time; otherwise returns false.
       
  1133 
       
  1134     Note that if the peer closes the connection unexpectedly, this
       
  1135     function returns false. This means that loops such as this won't
       
  1136     work:
       
  1137 
       
  1138     \snippet doc/src/snippets/code/src_qt3support_network_q3socket.cpp 0
       
  1139 
       
  1140     \sa readLine()
       
  1141 */
       
  1142 
       
  1143 bool Q3Socket::canReadLine() const
       
  1144 {
       
  1145     if ( ((Q3Socket*)this)->d->rba.scanNewline( 0 ) )
       
  1146 	return true;
       
  1147     return ( bytesAvailable() > 0 &&
       
  1148 	     (((Q3Socket*)this)->d->rba.scanNewline( 0 ) || QIODevice::canReadLine()) );
       
  1149 }
       
  1150 
       
  1151 /*!
       
  1152   \internal
       
  1153     Internal slot for handling socket read notifications.
       
  1154 
       
  1155     This function has can usually only be entered once (i.e. no
       
  1156     recursive calls). If the argument \a force is true, the function
       
  1157     is executed, but no readyRead() signals are emitted. This
       
  1158     behaviour is useful for the waitForMore() function, so that it is
       
  1159     possible to call waitForMore() in a slot connected to the
       
  1160     readyRead() signal.
       
  1161 */
       
  1162 
       
  1163 void Q3Socket::sn_read( bool force )
       
  1164 {
       
  1165     Q_LONG maxToRead = 0;
       
  1166     if ( d->readBufferSize > 0 ) {
       
  1167 	maxToRead = d->readBufferSize - d->rba.size();
       
  1168 	if ( maxToRead <= 0 ) {
       
  1169 	    if ( d->rsn )
       
  1170 		d->rsn->setEnabled( false );
       
  1171 	    return;
       
  1172 	}
       
  1173     }
       
  1174 
       
  1175     // Use Q3SocketPrivate::sn_read_alreadyCalled to avoid recursive calls of
       
  1176     // sn_read() (and as a result avoid emitting the readyRead() signal in a
       
  1177     // slot for readyRead(), if you use bytesAvailable()).
       
  1178     if ( !force && Q3SocketPrivate::sn_read_alreadyCalled.findRef(this) != -1 )
       
  1179 	return;
       
  1180     Q3SocketPrivate::sn_read_alreadyCalled.append( this );
       
  1181 
       
  1182     char buf[4096];
       
  1183     Q_LONG nbytes = d->socket->bytesAvailable();
       
  1184     Q_LONG nread;
       
  1185     QByteArray *a = 0;
       
  1186 
       
  1187     if ( state() == Connecting ) {
       
  1188 	if ( nbytes > 0 ) {
       
  1189 	    tryConnection();
       
  1190 	} else {
       
  1191 	    // nothing to do, nothing to care about
       
  1192 	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1193 	    return;
       
  1194 	}
       
  1195     }
       
  1196     if ( state() == Idle ) {
       
  1197 	Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1198 	return;
       
  1199     }
       
  1200 
       
  1201     if ( nbytes <= 0 ) {			// connection closed?
       
  1202 	// On Windows this may happen when the connection is still open.
       
  1203 	// This happens when the system is heavily loaded and we have
       
  1204 	// read all the data on the socket before a new WSAAsyncSelect
       
  1205 	// event is processed. A new read operation would then block.
       
  1206 	// This code is also useful when Q3Socket is used without an
       
  1207 	// event loop.
       
  1208 	nread = d->socket->readBlock( buf, maxToRead ? QMIN((Q_LONG)sizeof(buf),maxToRead) : sizeof(buf) );
       
  1209 	if ( nread == 0 ) {			// really closed
       
  1210             if ( !d->socket->isOpen() ) {
       
  1211 #if defined(Q3SOCKET_DEBUG)
       
  1212                 qDebug( "Q3Socket (%s): sn_read: Connection closed", name() );
       
  1213 #endif
       
  1214                 d->connectionClosed();
       
  1215                 emit connectionClosed();
       
  1216             }
       
  1217 	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1218 	    return;
       
  1219 	} else {
       
  1220 	    if ( nread < 0 ) {
       
  1221 		if ( d->socket->error() == Q3SocketDevice::NoError ) {
       
  1222 		    // all is fine
       
  1223 		    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1224 		    return;
       
  1225 		}
       
  1226 #if defined(Q3SOCKET_DEBUG)
       
  1227 		qWarning( "Q3Socket::sn_read (%s): Close error", name() );
       
  1228 #endif
       
  1229 		if ( d->rsn )
       
  1230 		    d->rsn->setEnabled( false );
       
  1231 		emit error( ErrSocketRead );
       
  1232 		Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1233 		return;
       
  1234 	    }
       
  1235 	    a = new QByteArray( nread );
       
  1236 	    memcpy( a->data(), buf, nread );
       
  1237 	}
       
  1238 
       
  1239     } else {					// data to be read
       
  1240 #if defined(Q3SOCKET_DEBUG)
       
  1241 	qDebug( "Q3Socket (%s): sn_read: %ld incoming bytes", name(), nbytes );
       
  1242 #endif
       
  1243 	if ( nbytes > (int)sizeof(buf) ) {
       
  1244 	    // big
       
  1245 	    a = new QByteArray( nbytes );
       
  1246 	    nread = d->socket->readBlock( a->data(), maxToRead ? QMIN(nbytes,maxToRead) : nbytes );
       
  1247 	} else {
       
  1248 	    a = 0;
       
  1249 	    nread = d->socket->readBlock( buf, maxToRead ? QMIN((Q_LONG)sizeof(buf),maxToRead) : sizeof(buf) );
       
  1250 	    if ( nread > 0 ) {
       
  1251 		// ##### could setRawData
       
  1252 		a = new QByteArray( nread );
       
  1253 		memcpy( a->data(), buf, nread );
       
  1254 	    }
       
  1255 	}
       
  1256 	if ( nread == 0 ) {
       
  1257 #if defined(Q3SOCKET_DEBUG)
       
  1258 	    qDebug( "Q3Socket (%s): sn_read: Connection closed", name() );
       
  1259 #endif
       
  1260 	    // ### we should rather ask the socket device if it is closed
       
  1261 	    d->connectionClosed();
       
  1262 	    emit connectionClosed();
       
  1263 	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1264             delete a;
       
  1265 	    return;
       
  1266 	} else if ( nread < 0 ) {
       
  1267             delete a;
       
  1268 
       
  1269 	    if ( d->socket->error() == Q3SocketDevice::NoError ) {
       
  1270 		// all is fine
       
  1271 		Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1272 		return;
       
  1273 	    }
       
  1274 #if defined(QT_CHECK_RANGE)
       
  1275 	    qWarning( "Q3Socket::sn_read: Read error" );
       
  1276 #endif
       
  1277 	    if ( d->rsn )
       
  1278 		d->rsn->setEnabled( false );
       
  1279 	    emit error( ErrSocketRead );
       
  1280 	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1281 	    return;
       
  1282 	}
       
  1283 	if ( nread != (int)a->size() ) {		// unexpected
       
  1284 #if defined(CHECK_RANGE) && !defined(Q_OS_WIN32)
       
  1285 	    qWarning( "Q3Socket::sn_read: Unexpected short read" );
       
  1286 #endif
       
  1287 	    a->resize( nread );
       
  1288 	}
       
  1289     }
       
  1290     d->rba.append( a );
       
  1291     if ( !force ) {
       
  1292 	if ( d->rsn )
       
  1293 	    d->rsn->setEnabled( false );
       
  1294 	emit readyRead();
       
  1295 	if ( d->rsn )
       
  1296 	    d->rsn->setEnabled( true );
       
  1297     }
       
  1298 
       
  1299     Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );
       
  1300 }
       
  1301 
       
  1302 
       
  1303 /*!
       
  1304   \internal
       
  1305     Internal slot for handling socket write notifications.
       
  1306 */
       
  1307 
       
  1308 void Q3Socket::sn_write()
       
  1309 {
       
  1310     if ( d->state == Connecting )		// connection established?
       
  1311 	tryConnection();
       
  1312     flush();
       
  1313 }
       
  1314 
       
  1315 void Q3Socket::emitErrorConnectionRefused()
       
  1316 {
       
  1317     emit error( ErrConnectionRefused );
       
  1318 }
       
  1319 
       
  1320 void Q3Socket::tryConnection()
       
  1321 {
       
  1322     if ( d->socket->connect( d->addr, d->port ) ) {
       
  1323 	d->state = Connected;
       
  1324 #if defined(Q3SOCKET_DEBUG)
       
  1325 	qDebug( "Q3Socket (%s): sn_write: Got connection to %s",
       
  1326 		name(), peerName().ascii() );
       
  1327 #endif
       
  1328 	if ( d->rsn )
       
  1329 	    d->rsn->setEnabled( true );
       
  1330 	emit connected();
       
  1331     } else {
       
  1332 	d->state = Idle;
       
  1333 	QTimer::singleShot( 0, this, SLOT(emitErrorConnectionRefused()) );
       
  1334 	return;
       
  1335     }
       
  1336 }
       
  1337 
       
  1338 
       
  1339 /*!
       
  1340     Returns the socket number, or -1 if there is no socket at the moment.
       
  1341 */
       
  1342 
       
  1343 int Q3Socket::socket() const
       
  1344 {
       
  1345     if ( d->socket == 0 )
       
  1346 	return -1;
       
  1347     return d->socket->socket();
       
  1348 }
       
  1349 
       
  1350 /*!
       
  1351     Sets the socket to use \a socket and the state() to \c Connected.
       
  1352     The socket must already be connected.
       
  1353 
       
  1354     This allows us to use the Q3Socket class as a wrapper for other
       
  1355     socket types (e.g. Unix Domain Sockets).
       
  1356 */
       
  1357 
       
  1358 void Q3Socket::setSocket( int socket )
       
  1359 {
       
  1360     setSocketIntern( socket );
       
  1361     d->state = Connection;
       
  1362     d->rsn->setEnabled( true );
       
  1363 }
       
  1364 
       
  1365 
       
  1366 /*!
       
  1367     Sets the socket to \a socket. This is used by both setSocket() and
       
  1368     connectToHost() and can also be used on unconnected sockets.
       
  1369 */
       
  1370 
       
  1371 void Q3Socket::setSocketIntern( int socket )
       
  1372 {
       
  1373     if ( state() != Idle ) {
       
  1374 	clearPendingData();
       
  1375         close();
       
  1376     }
       
  1377     Q_ULONG oldBufferSize = d ? d->readBufferSize : 0;
       
  1378     delete d;
       
  1379 
       
  1380     d = new Q3SocketPrivate;
       
  1381     if (oldBufferSize)
       
  1382         d->readBufferSize = oldBufferSize;
       
  1383     if ( socket >= 0 ) {
       
  1384 	Q3SocketDevice *sd = new Q3SocketDevice( socket, Q3SocketDevice::Stream );
       
  1385 	sd->setBlocking( false );
       
  1386 	sd->setAddressReusable( true );
       
  1387 	d->setSocketDevice( this, sd );
       
  1388     }
       
  1389     d->state = Idle;
       
  1390 
       
  1391     // Initialize the IO device flags
       
  1392     resetStatus();
       
  1393     open( IO_ReadWrite );
       
  1394 
       
  1395     // hm... this is not very nice.
       
  1396     d->host.clear();
       
  1397     d->port = 0;
       
  1398 #ifndef QT_NO_DNS
       
  1399     delete d->dns4;
       
  1400     d->dns4 = 0;
       
  1401     delete d->dns6;
       
  1402     d->dns6 = 0;
       
  1403 #endif
       
  1404 }
       
  1405 
       
  1406 
       
  1407 /*!
       
  1408     Returns the host port number of this socket, in native byte order.
       
  1409 */
       
  1410 
       
  1411 Q_UINT16 Q3Socket::port() const
       
  1412 {
       
  1413     if ( d->socket == 0 )
       
  1414 	return 0;
       
  1415     return d->socket->port();
       
  1416 }
       
  1417 
       
  1418 
       
  1419 /*!
       
  1420     Returns the peer's host port number, normally as specified to the
       
  1421     connectToHost() function. If none has been set, this function
       
  1422     returns 0.
       
  1423 
       
  1424     Note that Qt always uses native byte order, i.e. 67 is 67 in Qt;
       
  1425     there is no need to call htons().
       
  1426 */
       
  1427 
       
  1428 Q_UINT16 Q3Socket::peerPort() const
       
  1429 {
       
  1430     if ( d->socket == 0 )
       
  1431 	return 0;
       
  1432     return d->socket->peerPort();
       
  1433 }
       
  1434 
       
  1435 
       
  1436 /*!
       
  1437     Returns the host address of this socket. (This is normally the
       
  1438     main IP address of the host, but can be e.g. 127.0.0.1 for
       
  1439     connections to localhost.)
       
  1440 */
       
  1441 
       
  1442 QHostAddress Q3Socket::address() const
       
  1443 {
       
  1444     if ( d->socket == 0 ) {
       
  1445 	QHostAddress tmp;
       
  1446 	return tmp;
       
  1447     }
       
  1448     return d->socket->address();
       
  1449 }
       
  1450 
       
  1451 
       
  1452 /*!
       
  1453     Returns the address of the connected peer if the socket is in
       
  1454     Connected state; otherwise an empty QHostAddress is returned.
       
  1455 */
       
  1456 
       
  1457 QHostAddress Q3Socket::peerAddress() const
       
  1458 {
       
  1459     if ( d->socket == 0 ) {
       
  1460 	QHostAddress tmp;
       
  1461 	return tmp;
       
  1462     }
       
  1463     return d->socket->peerAddress();
       
  1464 }
       
  1465 
       
  1466 
       
  1467 /*!
       
  1468     Returns the host name as specified to the connectToHost()
       
  1469     function. An empty string is returned if none has been set.
       
  1470 */
       
  1471 
       
  1472 QString Q3Socket::peerName() const
       
  1473 {
       
  1474     return d->host;
       
  1475 }
       
  1476 
       
  1477 /*!
       
  1478     Sets the size of the Q3Socket's internal read buffer to \a bufSize.
       
  1479 
       
  1480     Usually Q3Socket reads all data that is available from the operating
       
  1481     system's socket. If the buffer size is limited to a certain size, this
       
  1482     means that the Q3Socket class doesn't buffer more than this size of data.
       
  1483 
       
  1484     If the size of the read buffer is 0, the read buffer is unlimited and all
       
  1485     incoming data is buffered. This is the default.
       
  1486 
       
  1487     If you read the data in the readyRead() signal, you shouldn't use this
       
  1488     option since it might slow down your program unnecessary. This option is
       
  1489     useful if you only need to read the data at certain points in time, like in
       
  1490     a realtime streaming application.
       
  1491 
       
  1492     \sa readBufferSize()
       
  1493 */
       
  1494 
       
  1495 void Q3Socket::setReadBufferSize( Q_ULONG bufSize )
       
  1496 {
       
  1497     d->readBufferSize = bufSize;
       
  1498 }
       
  1499 
       
  1500 /*!
       
  1501     Returns the size of the read buffer.
       
  1502 
       
  1503     \sa setReadBufferSize()
       
  1504 */
       
  1505 
       
  1506 Q_ULONG Q3Socket::readBufferSize() const
       
  1507 {
       
  1508     return d->readBufferSize;
       
  1509 }
       
  1510 
       
  1511 /*!
       
  1512     \fn bool Q3Socket::isSequential() const
       
  1513     \internal
       
  1514 */
       
  1515 
       
  1516 QT_END_NAMESPACE
       
  1517 
       
  1518 #endif //QT_NO_NETWORK