src/network/socket/qnativesocketengine.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 QtNetwork 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 //#define QNATIVESOCKETENGINE_DEBUG
       
    43 
       
    44 /*! \class QNativeSocketEngine
       
    45     \internal
       
    46 
       
    47     \brief The QNativeSocketEngine class provides low level access to a socket.
       
    48 
       
    49     \reentrant
       
    50     \ingroup network
       
    51     \inmodule QtNetwork
       
    52 
       
    53     QtSocketLayer provides basic socket functionality provided by the
       
    54     operating system. It also keeps track of what state the socket is
       
    55     in, and which errors that occur.
       
    56 
       
    57     The classes QTcpSocket, QUdpSocket and QTcpServer provide a
       
    58     higher level API, and are in general more useful for the common
       
    59     application.
       
    60 
       
    61     There are two main ways of initializing the a QNativeSocketEngine; either
       
    62     create a new socket by passing the socket type (TcpSocket or
       
    63     UdpSocket) and network layer protocol (IPv4Protocol or
       
    64     IPv6Protocol) to initialize(), or pass an existing socket
       
    65     descriptor and have QNativeSocketEngine determine the type and protocol
       
    66     itself. The native socket descriptor can later be fetched by
       
    67     calling socketDescriptor(). The socket is made non-blocking, but
       
    68     blocking behavior can still be achieved by calling waitForRead()
       
    69     and waitForWrite(). isValid() can be called to check if the socket
       
    70     has been successfully initialized and is ready to use.
       
    71 
       
    72     To connect to a host, determine its address and pass this and the
       
    73     port number to connectToHost(). The socket can then be used as a
       
    74     TCP or UDP client. Otherwise; bind(), listen() and accept() are
       
    75     used to have the socket function as a TCP or UDP server. Call
       
    76     close() to close the socket.
       
    77 
       
    78     bytesAvailable() is called to determine how much data is available
       
    79     for reading. read() and write() are used by both TCP and UDP
       
    80     clients to exchange data with the connected peer. UDP clients can
       
    81     also call hasMoreDatagrams(), nextDatagramSize(),
       
    82     readDatagram(), and writeDatagram().
       
    83 
       
    84     Call state() to determine the state of the socket, for
       
    85     example, ListeningState or ConnectedState. socketType() tells
       
    86     whether the socket is a TCP socket or a UDP socket, or if the
       
    87     socket type is unknown. protocol() is used to determine the
       
    88     socket's network layer protocol.
       
    89 
       
    90     localAddress(), localPort() are called to find the address and
       
    91     port that are currently bound to the socket. If the socket is
       
    92     connected, peerAddress() and peerPort() determine the address and
       
    93     port of the connected peer.
       
    94 
       
    95     Finally, if any function should fail, error() and
       
    96     errorString() can be called to determine the cause of the error.
       
    97 */
       
    98 
       
    99 #include <qabstracteventdispatcher.h>
       
   100 #include <qsocketnotifier.h>
       
   101 
       
   102 #include "qnativesocketengine_p.h"
       
   103 #include <private/qthread_p.h>
       
   104 #include <private/qobject_p.h>
       
   105 
       
   106 #if !defined(QT_NO_NETWORKPROXY)
       
   107 # include "qnetworkproxy.h"
       
   108 # include "qabstractsocket.h"
       
   109 # include "qtcpserver.h"
       
   110 #endif
       
   111 
       
   112 QT_BEGIN_NAMESPACE
       
   113 
       
   114 //#define QNATIVESOCKETENGINE_DEBUG
       
   115 
       
   116 #define Q_VOID
       
   117 
       
   118 // Common constructs
       
   119 #define Q_CHECK_VALID_SOCKETLAYER(function, returnValue) do { \
       
   120     if (!isValid()) { \
       
   121         qWarning(""#function" was called on an uninitialized socket device"); \
       
   122         return returnValue; \
       
   123     } } while (0)
       
   124 #define Q_CHECK_INVALID_SOCKETLAYER(function, returnValue) do { \
       
   125     if (isValid()) { \
       
   126         qWarning(""#function" was called on an already initialized socket device"); \
       
   127         return returnValue; \
       
   128     } } while (0)
       
   129 #define Q_CHECK_STATE(function, checkState, returnValue) do { \
       
   130     if (d->socketState != (checkState)) { \
       
   131         qWarning(""#function" was not called in "#checkState); \
       
   132         return (returnValue); \
       
   133     } } while (0)
       
   134 #define Q_CHECK_NOT_STATE(function, checkState, returnValue) do { \
       
   135     if (d->socketState == (checkState)) { \
       
   136         qWarning(""#function" was called in "#checkState); \
       
   137         return (returnValue); \
       
   138     } } while (0)
       
   139 #define Q_CHECK_STATES(function, state1, state2, returnValue) do { \
       
   140     if (d->socketState != (state1) && d->socketState != (state2)) { \
       
   141         qWarning(""#function" was called" \
       
   142                  " not in "#state1" or "#state2); \
       
   143         return (returnValue); \
       
   144     } } while (0)
       
   145 #define Q_CHECK_TYPE(function, type, returnValue) do { \
       
   146     if (d->socketType != (type)) { \
       
   147         qWarning(#function" was called by a" \
       
   148                  " socket other than "#type""); \
       
   149         return (returnValue); \
       
   150     } } while (0)
       
   151 #define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a)
       
   152 
       
   153 /*! \internal
       
   154     Constructs the private class and initializes all data members.
       
   155 
       
   156     On Windows, WSAStartup is called "recursively" for every
       
   157     concurrent QNativeSocketEngine. This is safe, because WSAStartup and
       
   158     WSACleanup are reference counted.
       
   159 */
       
   160 QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()
       
   161 {
       
   162     socketDescriptor = -1;
       
   163     readNotifier = 0;
       
   164     writeNotifier = 0;
       
   165     exceptNotifier = 0;
       
   166 }
       
   167 
       
   168 /*! \internal
       
   169     Destructs the private class.
       
   170 */
       
   171 QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate()
       
   172 {
       
   173 }
       
   174 
       
   175 /*! \internal
       
   176 
       
   177     Sets the error and error string if not set already. The only
       
   178     interesting error is the first one that occurred, and not the last
       
   179     one.
       
   180 */
       
   181 void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, ErrorString errorString) const
       
   182 {
       
   183     if (hasSetSocketError) {
       
   184         // Only set socket errors once for one engine; expect the
       
   185         // socket to recreate its engine after an error. Note: There's
       
   186         // one exception: SocketError(11) bypasses this as it's purely
       
   187         // a temporary internal error condition.
       
   188         return;
       
   189     }
       
   190     if (error != QAbstractSocket::SocketError(11))
       
   191         hasSetSocketError = true;
       
   192 
       
   193     socketError = error;
       
   194 
       
   195     switch (errorString) {
       
   196     case NonBlockingInitFailedErrorString:
       
   197         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to initialize non-blocking socket"));
       
   198         break;
       
   199     case BroadcastingInitFailedErrorString:
       
   200         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to initialize broadcast socket"));
       
   201         break;
       
   202     case NoIpV6ErrorString:
       
   203         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Attempt to use IPv6 socket on a platform with no IPv6 support"));
       
   204         break;
       
   205     case RemoteHostClosedErrorString:
       
   206         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The remote host closed the connection"));
       
   207         break;
       
   208     case TimeOutErrorString:
       
   209         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network operation timed out"));
       
   210         break;
       
   211     case ResourceErrorString:
       
   212         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Out of resources"));
       
   213         break;
       
   214     case OperationUnsupportedErrorString:
       
   215         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unsupported socket operation"));
       
   216         break;
       
   217     case ProtocolUnsupportedErrorString:
       
   218         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Protocol type not supported"));
       
   219         break;
       
   220     case InvalidSocketErrorString:
       
   221         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Invalid socket descriptor"));
       
   222         break;
       
   223     case HostUnreachableErrorString:
       
   224         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Host unreachable"));
       
   225         break;
       
   226     case NetworkUnreachableErrorString:
       
   227         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network unreachable"));
       
   228         break;
       
   229     case AccessErrorString:
       
   230         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Permission denied"));
       
   231         break;
       
   232     case ConnectionTimeOutErrorString:
       
   233         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Connection timed out"));
       
   234         break;
       
   235     case ConnectionRefusedErrorString:
       
   236         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Connection refused"));
       
   237         break;
       
   238     case AddressInuseErrorString:
       
   239         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The bound address is already in use"));
       
   240         break;
       
   241     case AddressNotAvailableErrorString:
       
   242         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The address is not available"));
       
   243         break;
       
   244     case AddressProtectedErrorString:
       
   245         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The address is protected"));
       
   246         break;
       
   247     case DatagramTooLargeErrorString:
       
   248         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Datagram was too large to send"));
       
   249         break;
       
   250     case SendDatagramErrorString:
       
   251         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to send a message"));
       
   252         break;
       
   253     case ReceiveDatagramErrorString:
       
   254         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to receive a message"));
       
   255         break;
       
   256     case WriteErrorString:
       
   257         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to write"));
       
   258         break;
       
   259     case ReadErrorString:
       
   260         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network error"));
       
   261         break;
       
   262     case PortInuseErrorString:
       
   263         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Another socket is already listening on the same port"));
       
   264         break;
       
   265     case NotSocketErrorString:
       
   266         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Operation on non-socket"));
       
   267         break;
       
   268     case InvalidProxyTypeString:
       
   269         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The proxy type is invalid for this operation"));
       
   270         break;
       
   271     case UnknownSocketErrorString:
       
   272         socketErrorString = QLatin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unknown error"));
       
   273         break;
       
   274     }
       
   275 }
       
   276 
       
   277 bool QNativeSocketEnginePrivate::checkProxy(const QHostAddress &address)
       
   278 {
       
   279     if (address == QHostAddress::LocalHost || address == QHostAddress::LocalHostIPv6)
       
   280         return true;
       
   281 
       
   282 #if !defined(QT_NO_NETWORKPROXY)
       
   283     QObject *parent = q_func()->parent();
       
   284     QNetworkProxy proxy;
       
   285     if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(parent)) {
       
   286         proxy = socket->proxy();
       
   287     } else if (QTcpServer *server = qobject_cast<QTcpServer *>(parent)) {
       
   288         proxy = server->proxy();
       
   289     } else {
       
   290         // no parent -> no proxy
       
   291         return true;
       
   292     }
       
   293 
       
   294     if (proxy.type() == QNetworkProxy::DefaultProxy)
       
   295         proxy = QNetworkProxy::applicationProxy();
       
   296 
       
   297     if (proxy.type() != QNetworkProxy::DefaultProxy &&
       
   298         proxy.type() != QNetworkProxy::NoProxy) {
       
   299         // QNativeSocketEngine doesn't do proxies
       
   300         setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   301                  QNativeSocketEnginePrivate::InvalidProxyTypeString);
       
   302         return false;
       
   303     }
       
   304 #endif
       
   305 
       
   306     return true;
       
   307 }
       
   308 
       
   309 /*!
       
   310     Constructs a QNativeSocketEngine.
       
   311 
       
   312     \sa initialize()
       
   313 */
       
   314 QNativeSocketEngine::QNativeSocketEngine(QObject *parent)
       
   315     : QAbstractSocketEngine(*new QNativeSocketEnginePrivate(), parent)
       
   316 {
       
   317 }
       
   318 
       
   319 /*!
       
   320     Destructs a QNativeSocketEngine.
       
   321 */
       
   322 QNativeSocketEngine::~QNativeSocketEngine()
       
   323 {
       
   324     close();
       
   325 }
       
   326 
       
   327 /*!
       
   328     Initializes a QNativeSocketEngine by creating a new socket of type \a
       
   329     socketType and network layer protocol \a protocol. Returns true on
       
   330     success; otherwise returns false.
       
   331 
       
   332     If the socket was already initialized, this function closes the
       
   333     socket before reeinitializing it.
       
   334 
       
   335     The new socket is non-blocking, and for UDP sockets it's also
       
   336     broadcast enabled.
       
   337 */
       
   338 bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol protocol)
       
   339 {
       
   340     Q_D(QNativeSocketEngine);
       
   341     if (isValid())
       
   342         close();
       
   343 
       
   344 #if defined(QT_NO_IPV6)
       
   345     if (protocol == QAbstractSocket::IPv6Protocol) {
       
   346         d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   347                     QNativeSocketEnginePrivate::NoIpV6ErrorString);
       
   348         return false;
       
   349     }
       
   350 #endif
       
   351 
       
   352     // Create the socket
       
   353     if (!d->createNewSocket(socketType, protocol)) {
       
   354 #if defined (QNATIVESOCKETENGINE_DEBUG)
       
   355         QString typeStr = QLatin1String("UnknownSocketType");
       
   356         if (socketType == QAbstractSocket::TcpSocket) typeStr = QLatin1String("TcpSocket");
       
   357         else if (socketType == QAbstractSocket::UdpSocket) typeStr = QLatin1String("UdpSocket");
       
   358         QString protocolStr = QLatin1String("UnknownProtocol");
       
   359         if (protocol == QAbstractSocket::IPv4Protocol) protocolStr = QLatin1String("IPv4Protocol");
       
   360         else if (protocol == QAbstractSocket::IPv6Protocol) protocolStr = QLatin1String("IPv6Protocol");
       
   361         qDebug("QNativeSocketEngine::initialize(type == %s, protocol == %s) failed: %s",
       
   362                typeStr.toLatin1().constData(), protocolStr.toLatin1().constData(), d->socketErrorString.toLatin1().constData());
       
   363 #endif
       
   364         return false;
       
   365     }
       
   366 
       
   367     // Make the socket nonblocking.
       
   368     if (!setOption(NonBlockingSocketOption, 1)) {
       
   369         d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   370                     QNativeSocketEnginePrivate::NonBlockingInitFailedErrorString);
       
   371         close();
       
   372         return false;
       
   373     }
       
   374 
       
   375     // Set the broadcasting flag if it's a UDP socket.
       
   376     if (socketType == QAbstractSocket::UdpSocket
       
   377         && !setOption(BroadcastSocketOption, 1)) {
       
   378         d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   379                     QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
       
   380         close();
       
   381         return false;
       
   382     }
       
   383 
       
   384 
       
   385     // Make sure we receive out-of-band data
       
   386     // On Symbian OS this works only with native IP stack, not with WinSock
       
   387     if (socketType == QAbstractSocket::TcpSocket
       
   388         && !setOption(ReceiveOutOfBandData, 1)) {
       
   389         qWarning("QNativeSocketEngine::initialize unable to inline out-of-band data");
       
   390     }
       
   391 
       
   392     // Before Qt 4.6, we always set the send and receive buffer size to 49152 as
       
   393     // this was found to be an optimal value. However, modern OS
       
   394     // all have some kind of auto tuning for this and we therefore don't set
       
   395     // this explictly anymore.
       
   396     // If it introduces any performance regressions for Qt 4.6.x (x > 0) then
       
   397     // it will be put back in.
       
   398     //
       
   399     // You can use tests/manual/qhttpnetworkconnection to test HTTP download speed
       
   400     // with this.
       
   401     //
       
   402     // pre-4.6:
       
   403     // setReceiveBufferSize(49152);
       
   404     // setSendBufferSize(49152);
       
   405 
       
   406     d->socketType = socketType;
       
   407     d->socketProtocol = protocol;
       
   408     return true;
       
   409 }
       
   410 
       
   411 /*! \overload
       
   412 
       
   413     Initializes the socket using \a socketDescriptor instead of
       
   414     creating a new one. The socket type and network layer protocol are
       
   415     determined automatically. The socket's state is set to \a
       
   416     socketState.
       
   417 
       
   418     If the socket type is either TCP or UDP, it is made non-blocking.
       
   419     UDP sockets are also broadcast enabled.
       
   420  */
       
   421 bool QNativeSocketEngine::initialize(int socketDescriptor, QAbstractSocket::SocketState socketState)
       
   422 {
       
   423     Q_D(QNativeSocketEngine);
       
   424 
       
   425     if (isValid())
       
   426         close();
       
   427 
       
   428     d->socketDescriptor = socketDescriptor;
       
   429 
       
   430     // determine socket type and protocol
       
   431     if (!d->fetchConnectionParameters()) {
       
   432 #if defined (QNATIVESOCKETENGINE_DEBUG)
       
   433         qDebug("QNativeSocketEngine::initialize(socketDescriptor == %i) failed: %s",
       
   434                socketDescriptor, d->socketErrorString.toLatin1().constData());
       
   435 #endif
       
   436         d->socketDescriptor = -1;
       
   437         return false;
       
   438     }
       
   439 
       
   440     if (d->socketType != QAbstractSocket::UnknownSocketType) {
       
   441         // Make the socket nonblocking.
       
   442         if (!setOption(NonBlockingSocketOption, 1)) {
       
   443             d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   444                 QNativeSocketEnginePrivate::NonBlockingInitFailedErrorString);
       
   445             close();
       
   446             return false;
       
   447         }
       
   448 
       
   449         // Set the broadcasting flag if it's a UDP socket.
       
   450         if (d->socketType == QAbstractSocket::UdpSocket
       
   451             && !setOption(BroadcastSocketOption, 1)) {
       
   452             d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   453                 QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
       
   454             close();
       
   455             return false;
       
   456         }
       
   457     }
       
   458 
       
   459     d->socketState = socketState;
       
   460     return true;
       
   461 }
       
   462 
       
   463 /*!
       
   464     Returns true if the socket is valid; otherwise returns false. A
       
   465     socket is valid if it has not been successfully initialized, or if
       
   466     it has been closed.
       
   467 */
       
   468 bool QNativeSocketEngine::isValid() const
       
   469 {
       
   470     Q_D(const QNativeSocketEngine);
       
   471     return d->socketDescriptor != -1;
       
   472 }
       
   473 
       
   474 /*!
       
   475     Returns the native socket descriptor. Any use of this descriptor
       
   476     stands the risk of being non-portable.
       
   477 */
       
   478 int QNativeSocketEngine::socketDescriptor() const
       
   479 {
       
   480     Q_D(const QNativeSocketEngine);
       
   481     return d->socketDescriptor;
       
   482 }
       
   483 
       
   484 /*!
       
   485     Connects to the IP address and port specified by \a address and \a
       
   486     port. If the connection is established, this function returns true
       
   487     and the socket enters ConnectedState. Otherwise, false is
       
   488     returned.
       
   489 
       
   490     If false is returned, state() should be called to see if the
       
   491     socket is in ConnectingState. If so, a delayed TCP connection is
       
   492     taking place, and connectToHost() must be called again later to
       
   493     determine if the connection was established successfully or
       
   494     not. The second connection attempt must be made when the socket is
       
   495     ready for writing. This state can be determined either by
       
   496     connecting a QSocketNotifier to the socket descriptor returned by
       
   497     socketDescriptor(), or by calling the blocking function
       
   498     waitForWrite().
       
   499 
       
   500     Example:
       
   501     \snippet doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp 0
       
   502 
       
   503     Otherwise, error() should be called to determine the cause of the
       
   504     error.
       
   505 */
       
   506 bool QNativeSocketEngine::connectToHost(const QHostAddress &address, quint16 port)
       
   507 {
       
   508     Q_D(QNativeSocketEngine);
       
   509     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::connectToHost(), false);
       
   510 
       
   511 #if defined (QT_NO_IPV6)
       
   512     if (address.protocol() == QAbstractSocket::IPv6Protocol) {
       
   513         d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   514                     QNativeSocketEnginePrivate::NoIpV6ErrorString);
       
   515         return false;
       
   516     }
       
   517 #endif
       
   518     if (!d->checkProxy(address))
       
   519         return false;
       
   520 
       
   521     Q_CHECK_STATES(QNativeSocketEngine::connectToHost(),
       
   522                    QAbstractSocket::UnconnectedState, QAbstractSocket::ConnectingState, false);
       
   523 
       
   524     d->peerAddress = address;
       
   525     d->peerPort = port;
       
   526     bool connected = d->nativeConnect(address, port);
       
   527     if (connected)
       
   528         d->fetchConnectionParameters();
       
   529 
       
   530     return connected;
       
   531 }
       
   532 
       
   533 /*!
       
   534     If there's a connection activity on the socket, process it. Then
       
   535     notify our parent if there really was activity.
       
   536 */
       
   537 void QNativeSocketEngine::connectionNotification()
       
   538 {
       
   539     Q_D(QNativeSocketEngine);
       
   540     Q_ASSERT(state() == QAbstractSocket::ConnectingState);
       
   541 
       
   542     connectToHost(d->peerAddress, d->peerPort);
       
   543     if (state() != QAbstractSocket::ConnectingState) {
       
   544         // we changed states
       
   545         QAbstractSocketEngine::connectionNotification();
       
   546     }
       
   547 }
       
   548 
       
   549 /*!
       
   550     Connects to the remote host name given by \a name on port \a
       
   551     port. When this function is called, the upper-level will not
       
   552     perform a hostname lookup.
       
   553 
       
   554     The native socket engine does not support this operation,
       
   555     but some other socket engines (notably proxy-based ones) do.
       
   556 */
       
   557 bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port)
       
   558 {
       
   559     Q_UNUSED(name);
       
   560     Q_UNUSED(port);
       
   561     Q_D(QNativeSocketEngine);
       
   562     d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   563                 QNativeSocketEnginePrivate::OperationUnsupportedErrorString);
       
   564     return false;
       
   565 }
       
   566 
       
   567 /*!
       
   568     Binds the socket to the address \a address and port \a
       
   569     port. Returns true on success; otherwise false is returned. The
       
   570     port may be 0, in which case an arbitrary unused port is assigned
       
   571     automatically by the operating system.
       
   572 
       
   573     Servers call this function to set up the server's address and
       
   574     port. TCP servers must in addition call listen() after bind().
       
   575 */
       
   576 bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
       
   577 {
       
   578     Q_D(QNativeSocketEngine);
       
   579     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bind(), false);
       
   580 
       
   581 #if defined (QT_NO_IPV6)
       
   582     if (address.protocol() == QAbstractSocket::IPv6Protocol) {
       
   583         d->setError(QAbstractSocket::UnsupportedSocketOperationError,
       
   584                     QNativeSocketEnginePrivate::NoIpV6ErrorString);
       
   585         return false;
       
   586     }
       
   587 #endif
       
   588     if (!d->checkProxy(address))
       
   589         return false;
       
   590 
       
   591     Q_CHECK_STATE(QNativeSocketEngine::bind(), QAbstractSocket::UnconnectedState, false);
       
   592 
       
   593     if (!d->nativeBind(address, port))
       
   594         return false;
       
   595 
       
   596     d->fetchConnectionParameters();
       
   597     return true;
       
   598 }
       
   599 
       
   600 /*!
       
   601     Prepares a TCP server for accepting incoming connections. This
       
   602     function must be called after bind(), and only by TCP sockets.
       
   603 
       
   604     After this function has been called, pending client connections
       
   605     are detected by checking if the socket is ready for reading. This
       
   606     can be done by either creating a QSocketNotifier, passing the
       
   607     socket descriptor returned by socketDescriptor(), or by calling
       
   608     the blocking function waitForRead().
       
   609 
       
   610     Example:
       
   611     \snippet doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp 1
       
   612 
       
   613     \sa bind(), accept()
       
   614 */
       
   615 bool QNativeSocketEngine::listen()
       
   616 {
       
   617     Q_D(QNativeSocketEngine);
       
   618     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::listen(), false);
       
   619     Q_CHECK_STATE(QNativeSocketEngine::listen(), QAbstractSocket::BoundState, false);
       
   620     Q_CHECK_TYPE(QNativeSocketEngine::listen(), QAbstractSocket::TcpSocket, false);
       
   621 
       
   622     // We're using a backlog of 50. Most modern kernels support TCP
       
   623     // syncookies by default, and if they do, the backlog is ignored.
       
   624     // When there is no support for TCP syncookies, this value is
       
   625     // fine.
       
   626     return d->nativeListen(50);
       
   627 }
       
   628 
       
   629 /*!
       
   630     Accepts a pending connection from the socket, which must be in
       
   631     ListeningState, and returns its socket descriptor. If no pending
       
   632     connections are available, -1 is returned.
       
   633 
       
   634     \sa bind(), listen()
       
   635 */
       
   636 int QNativeSocketEngine::accept()
       
   637 {
       
   638     Q_D(QNativeSocketEngine);
       
   639     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::accept(), -1);
       
   640     Q_CHECK_STATE(QNativeSocketEngine::accept(), QAbstractSocket::ListeningState, false);
       
   641     Q_CHECK_TYPE(QNativeSocketEngine::accept(), QAbstractSocket::TcpSocket, false);
       
   642 
       
   643     return d->nativeAccept();
       
   644 }
       
   645 
       
   646 /*!
       
   647     Returns the number of bytes that are currently available for
       
   648     reading. On error, -1 is returned.
       
   649 
       
   650     For UDP sockets, this function returns the accumulated size of all
       
   651     pending datagrams, and it is therefore more useful for UDP sockets
       
   652     to call hasPendingDatagrams() and pendingDatagramSize().
       
   653 */
       
   654 qint64 QNativeSocketEngine::bytesAvailable() const
       
   655 {
       
   656     Q_D(const QNativeSocketEngine);
       
   657     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bytesAvailable(), -1);
       
   658     Q_CHECK_NOT_STATE(QNativeSocketEngine::bytesAvailable(), QAbstractSocket::UnconnectedState, false);
       
   659 
       
   660     return d->nativeBytesAvailable();
       
   661 }
       
   662 
       
   663 /*!
       
   664     Returns true if there is at least one datagram pending. This
       
   665     function is only called by UDP sockets, where a datagram can have
       
   666     a size of 0. TCP sockets call bytesAvailable().
       
   667 */
       
   668 bool QNativeSocketEngine::hasPendingDatagrams() const
       
   669 {
       
   670     Q_D(const QNativeSocketEngine);
       
   671     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::hasPendingDatagrams(), false);
       
   672     Q_CHECK_NOT_STATE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UnconnectedState, false);
       
   673     Q_CHECK_TYPE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UdpSocket, false);
       
   674 
       
   675     return d->nativeHasPendingDatagrams();
       
   676 }
       
   677 
       
   678 /*!
       
   679     Returns the size of the pending datagram, or -1 if no datagram is
       
   680     pending. A datagram size of 0 is perfectly valid. This function is
       
   681     called by UDP sockets before receiveMessage(). For TCP sockets,
       
   682     call bytesAvailable().
       
   683 */
       
   684 qint64 QNativeSocketEngine::pendingDatagramSize() const
       
   685 {
       
   686     Q_D(const QNativeSocketEngine);
       
   687     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::pendingDatagramSize(), -1);
       
   688     Q_CHECK_TYPE(QNativeSocketEngine::pendingDatagramSize(), QAbstractSocket::UdpSocket, false);
       
   689 
       
   690     return d->nativePendingDatagramSize();
       
   691 }
       
   692 
       
   693 /*!
       
   694     Reads up to \a maxSize bytes of a datagram from the socket,
       
   695     stores it in \a data and returns the number of bytes read. The
       
   696     address and port of the sender are stored in \a address and \a
       
   697     port. If either of these pointers is 0, the corresponding value is
       
   698     discarded.
       
   699 
       
   700     To avoid unnecessarily loss of data, call pendingDatagramSize() to
       
   701     determine the size of the pending message before reading it. If \a
       
   702     maxSize is too small, the rest of the datagram will be lost.
       
   703 
       
   704     Returns -1 if an error occurred.
       
   705 
       
   706     \sa hasPendingDatagrams()
       
   707 */
       
   708 qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxSize, QHostAddress *address,
       
   709                                       quint16 *port)
       
   710 {
       
   711     Q_D(QNativeSocketEngine);
       
   712     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::readDatagram(), -1);
       
   713     Q_CHECK_TYPE(QNativeSocketEngine::readDatagram(), QAbstractSocket::UdpSocket, false);
       
   714 
       
   715     return d->nativeReceiveDatagram(data, maxSize, address, port);
       
   716 }
       
   717 
       
   718 /*!
       
   719     Writes a UDP datagram of size \a size bytes to the socket from
       
   720     \a data to the address \a host on port \a port, and returns the
       
   721     number of bytes written, or -1 if an error occurred.
       
   722 
       
   723     Only one datagram is sent, and if there is too much data to fit
       
   724     into a single datagram, the operation will fail and error()
       
   725     will return QAbstractSocket::DatagramTooLargeError. Operating systems impose an
       
   726     upper limit to the size of a datagram, but this size is different
       
   727     on almost all platforms. Sending large datagrams is in general
       
   728     disadvised, as even if they are sent successfully, they are likely
       
   729     to be fragmented before arriving at their destination.
       
   730 
       
   731     Experience has shown that it is in general safe to send datagrams
       
   732     no larger than 512 bytes.
       
   733 
       
   734     \sa readDatagram()
       
   735 */
       
   736 qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size,
       
   737                                        const QHostAddress &host, quint16 port)
       
   738 {
       
   739     Q_D(QNativeSocketEngine);
       
   740     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::writeDatagram(), -1);
       
   741     Q_CHECK_TYPE(QNativeSocketEngine::writeDatagram(), QAbstractSocket::UdpSocket, -1);
       
   742     return d->nativeSendDatagram(data, size, host, port);
       
   743 }
       
   744 
       
   745 /*!
       
   746     Writes a block of \a size bytes from \a data to the socket.
       
   747     Returns the number of bytes written, or -1 if an error occurred.
       
   748 */
       
   749 qint64 QNativeSocketEngine::write(const char *data, qint64 size)
       
   750 {
       
   751     Q_D(QNativeSocketEngine);
       
   752     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::write(), -1);
       
   753     Q_CHECK_STATE(QNativeSocketEngine::write(), QAbstractSocket::ConnectedState, -1);
       
   754     return d->nativeWrite(data, size);
       
   755 }
       
   756 
       
   757 /*!
       
   758     Reads up to \a maxSize bytes into \a data from the socket.
       
   759     Returns the number of bytes read, or -1 if an error occurred.
       
   760 */
       
   761 qint64 QNativeSocketEngine::read(char *data, qint64 maxSize)
       
   762 {
       
   763     Q_D(QNativeSocketEngine);
       
   764     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::read(), -1);
       
   765     Q_CHECK_STATES(QNativeSocketEngine::read(), QAbstractSocket::ConnectedState, QAbstractSocket::BoundState, -1);
       
   766 
       
   767     qint64 readBytes = d->nativeRead(data, maxSize);
       
   768 
       
   769     // Handle remote close
       
   770     if (readBytes == 0 && d->socketType == QAbstractSocket::TcpSocket) {
       
   771         d->setError(QAbstractSocket::RemoteHostClosedError,
       
   772                     QNativeSocketEnginePrivate::RemoteHostClosedErrorString);
       
   773         close();
       
   774         return -1;
       
   775     }
       
   776     return readBytes;
       
   777 }
       
   778 
       
   779 /*!
       
   780     Closes the socket. In order to use the socket again, initialize()
       
   781     must be called.
       
   782 */
       
   783 void QNativeSocketEngine::close()
       
   784 {
       
   785     Q_D(QNativeSocketEngine);
       
   786     if (d->readNotifier)
       
   787         d->readNotifier->setEnabled(false);
       
   788     if (d->writeNotifier)
       
   789         d->writeNotifier->setEnabled(false);
       
   790     if (d->exceptNotifier)
       
   791         d->exceptNotifier->setEnabled(false);
       
   792 
       
   793     if(d->socketDescriptor != -1) {
       
   794         d->nativeClose();
       
   795         d->socketDescriptor = -1;
       
   796     }
       
   797     d->socketState = QAbstractSocket::UnconnectedState;
       
   798     d->hasSetSocketError = false;
       
   799     d->localPort = 0;
       
   800     d->localAddress.clear();
       
   801     d->peerPort = 0;
       
   802     d->peerAddress.clear();
       
   803     if (d->readNotifier) {
       
   804         qDeleteInEventHandler(d->readNotifier);
       
   805         d->readNotifier = 0;
       
   806     }
       
   807     if (d->writeNotifier) {
       
   808         qDeleteInEventHandler(d->writeNotifier);
       
   809         d->writeNotifier = 0;
       
   810     }
       
   811     if (d->exceptNotifier) {
       
   812         qDeleteInEventHandler(d->exceptNotifier);
       
   813         d->exceptNotifier = 0;
       
   814     }
       
   815 }
       
   816 
       
   817 /*!
       
   818     Waits for \a msecs milliseconds or until the socket is ready for
       
   819     reading. If \a timedOut is not 0 and \a msecs milliseconds have
       
   820     passed, the value of \a timedOut is set to true.
       
   821 
       
   822     Returns true if data is available for reading; otherwise returns
       
   823     false.
       
   824 
       
   825     This is a blocking function call; its use is disadvised in a
       
   826     single threaded application, as the whole thread will stop
       
   827     responding until the function returns. waitForRead() is most
       
   828     useful when there is no event loop available. The general approach
       
   829     is to create a QSocketNotifier, passing the socket descriptor
       
   830     returned by socketDescriptor() to its constructor.
       
   831 */
       
   832 bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut)
       
   833 {
       
   834     Q_D(const QNativeSocketEngine);
       
   835     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForRead(), false);
       
   836     Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForRead(),
       
   837                       QAbstractSocket::UnconnectedState, false);
       
   838 
       
   839     if (timedOut)
       
   840         *timedOut = false;
       
   841 
       
   842     int ret = d->nativeSelect(msecs, true);
       
   843     if (ret == 0) {
       
   844         if (timedOut)
       
   845             *timedOut = true;
       
   846         d->setError(QAbstractSocket::SocketTimeoutError,
       
   847             QNativeSocketEnginePrivate::TimeOutErrorString);
       
   848         return false;
       
   849     } else if (state() == QAbstractSocket::ConnectingState) {
       
   850         connectToHost(d->peerAddress, d->peerPort);
       
   851     }
       
   852 
       
   853     return ret > 0;
       
   854 }
       
   855 
       
   856 /*!
       
   857     Waits for \a msecs milliseconds or until the socket is ready for
       
   858     writing. If \a timedOut is not 0 and \a msecs milliseconds have
       
   859     passed, the value of \a timedOut is set to true.
       
   860 
       
   861     Returns true if data is available for writing; otherwise returns
       
   862     false.
       
   863 
       
   864     This is a blocking function call; its use is disadvised in a
       
   865     single threaded application, as the whole thread will stop
       
   866     responding until the function returns. waitForWrite() is most
       
   867     useful when there is no event loop available. The general approach
       
   868     is to create a QSocketNotifier, passing the socket descriptor
       
   869     returned by socketDescriptor() to its constructor.
       
   870 */
       
   871 bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut)
       
   872 {
       
   873     Q_D(const QNativeSocketEngine);
       
   874     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false);
       
   875     Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForWrite(),
       
   876                       QAbstractSocket::UnconnectedState, false);
       
   877 
       
   878     if (timedOut)
       
   879         *timedOut = false;
       
   880 
       
   881     int ret = d->nativeSelect(msecs, false);
       
   882     // On Windows, the socket is in connected state if a call to
       
   883     // select(writable) is successful. In this case we should not
       
   884     // issue a second call to WSAConnect()
       
   885 #if defined (Q_WS_WIN)
       
   886     if (ret > 0) {
       
   887         setState(QAbstractSocket::ConnectedState);
       
   888         d_func()->fetchConnectionParameters();
       
   889         return true;
       
   890     }
       
   891 #endif
       
   892 
       
   893     if (ret == 0) {
       
   894         if (timedOut)
       
   895             *timedOut = true;
       
   896         d->setError(QAbstractSocket::SocketTimeoutError,
       
   897                     QNativeSocketEnginePrivate::TimeOutErrorString);
       
   898         return false;
       
   899     } else if (state() == QAbstractSocket::ConnectingState) {
       
   900         connectToHost(d->peerAddress, d->peerPort);
       
   901     }
       
   902 
       
   903     return ret > 0;
       
   904 }
       
   905 
       
   906 bool QNativeSocketEngine::waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
       
   907                                       bool checkRead, bool checkWrite,
       
   908                                       int msecs, bool *timedOut)
       
   909 {
       
   910     Q_D(const QNativeSocketEngine);
       
   911     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false);
       
   912     Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForReadOrWrite(),
       
   913                       QAbstractSocket::UnconnectedState, false);
       
   914 
       
   915     int ret = d->nativeSelect(msecs, checkRead, checkWrite, readyToRead, readyToWrite);
       
   916     // On Windows, the socket is in connected state if a call to
       
   917     // select(writable) is successful. In this case we should not
       
   918     // issue a second call to WSAConnect()
       
   919 #if defined (Q_WS_WIN)
       
   920     if (checkWrite && ((readyToWrite && *readyToWrite) || !readyToWrite) && ret > 0) {
       
   921         setState(QAbstractSocket::ConnectedState);
       
   922         d_func()->fetchConnectionParameters();
       
   923         return true;
       
   924     }
       
   925 #endif
       
   926     if (ret == 0) {
       
   927         if (timedOut)
       
   928             *timedOut = true;
       
   929         d->setError(QAbstractSocket::SocketTimeoutError,
       
   930                     QNativeSocketEnginePrivate::TimeOutErrorString);
       
   931         return false;
       
   932     } else if (state() == QAbstractSocket::ConnectingState) {
       
   933         connectToHost(d->peerAddress, d->peerPort);
       
   934     }
       
   935 
       
   936     return ret > 0;
       
   937 }
       
   938 
       
   939 /*!
       
   940     Returns the size of the operating system's socket receive
       
   941     buffer. Depending on the operating system, this size may be
       
   942     different from what has been set earlier with
       
   943     setReceiveBufferSize().
       
   944 */
       
   945 qint64 QNativeSocketEngine::receiveBufferSize() const
       
   946 {
       
   947     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::receiveBufferSize(), -1);
       
   948     return option(ReceiveBufferSocketOption);
       
   949 }
       
   950 
       
   951 /*!
       
   952     Sets the size of the operating system receive buffer to \a size.
       
   953 
       
   954     For clients, this should be set before connectToHost() is called;
       
   955     otherwise it will have no effect. For servers, it should be called
       
   956     before listen().
       
   957 
       
   958     The operating system receive buffer size effectively limits two
       
   959     things: how much data can be in transit at any one moment, and how
       
   960     much data can be received in one iteration of the main event loop.
       
   961     Setting the size of the receive buffer may have an impact on the
       
   962     socket's performance.
       
   963 
       
   964     The default value is operating system-dependent.
       
   965 */
       
   966 void QNativeSocketEngine::setReceiveBufferSize(qint64 size)
       
   967 {
       
   968     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setReceiveBufferSize(), Q_VOID);
       
   969     setOption(ReceiveBufferSocketOption, size);
       
   970 }
       
   971 
       
   972 /*!
       
   973     Returns the size of the operating system send buffer. Depending on
       
   974     the operating system, this size may be different from what has
       
   975     been set earlier with setSendBufferSize().
       
   976 */
       
   977 qint64 QNativeSocketEngine::sendBufferSize() const
       
   978 {
       
   979     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setSendBufferSize(), -1);
       
   980     return option(SendBufferSocketOption);
       
   981 }
       
   982 
       
   983 /*!
       
   984     Sets the size of the operating system send buffer to \a size.
       
   985 
       
   986     The operating system send buffer size effectively limits how much
       
   987     data can be in transit at any one moment. Setting the size of the
       
   988     send buffer may have an impact on the socket's performance.
       
   989 
       
   990     The default value is operating system-dependent.
       
   991 */
       
   992 void QNativeSocketEngine::setSendBufferSize(qint64 size)
       
   993 {
       
   994     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setSendBufferSize(), Q_VOID);
       
   995     setOption(SendBufferSocketOption, size);
       
   996 }
       
   997 
       
   998 
       
   999 /*!
       
  1000     Sets the option \a option to the value \a value.
       
  1001 */
       
  1002 bool QNativeSocketEngine::setOption(SocketOption option, int value)
       
  1003 {
       
  1004     Q_D(QNativeSocketEngine);
       
  1005     return d->setOption(option, value);
       
  1006 }
       
  1007 
       
  1008 /*!
       
  1009     Returns the value of the option \a socketOption.
       
  1010 */
       
  1011 int QNativeSocketEngine::option(SocketOption socketOption) const
       
  1012 {
       
  1013     Q_D(const QNativeSocketEngine);
       
  1014     return d->option(socketOption);
       
  1015 }
       
  1016 
       
  1017 bool QNativeSocketEngine::isReadNotificationEnabled() const
       
  1018 {
       
  1019     Q_D(const QNativeSocketEngine);
       
  1020     return d->readNotifier && d->readNotifier->isEnabled();
       
  1021 }
       
  1022 
       
  1023 /*
       
  1024   \internal
       
  1025   \class QReadNotifier
       
  1026   \brief The QReadNotifer class is used to improve performance.
       
  1027 
       
  1028   QReadNotifier is a private class used for performance reasons vs
       
  1029   connecting to the QSocketNotifier activated() signal.
       
  1030  */
       
  1031 class QReadNotifier : public QSocketNotifier
       
  1032 {
       
  1033 public:
       
  1034     QReadNotifier(int fd, QNativeSocketEngine *parent)
       
  1035         : QSocketNotifier(fd, QSocketNotifier::Read, parent)
       
  1036     { engine = parent; }
       
  1037 
       
  1038 protected:
       
  1039     bool event(QEvent *);
       
  1040 
       
  1041     QNativeSocketEngine *engine;
       
  1042 };
       
  1043 
       
  1044 bool QReadNotifier::event(QEvent *e)
       
  1045 {
       
  1046     if (e->type() == QEvent::SockAct) {
       
  1047         engine->readNotification();
       
  1048         return true;
       
  1049     }
       
  1050     return QSocketNotifier::event(e);
       
  1051 }
       
  1052 
       
  1053 /*
       
  1054   \internal
       
  1055   \class QWriteNotifier
       
  1056   \brief The QWriteNotifer class is used to improve performance.
       
  1057 
       
  1058   QWriteNotifier is a private class used for performance reasons vs
       
  1059   connecting to the QSocketNotifier activated() signal.
       
  1060  */
       
  1061 class QWriteNotifier : public QSocketNotifier
       
  1062 {
       
  1063 public:
       
  1064     QWriteNotifier(int fd, QNativeSocketEngine *parent)
       
  1065         : QSocketNotifier(fd, QSocketNotifier::Write, parent) { engine = parent; }
       
  1066 
       
  1067 protected:
       
  1068     bool event(QEvent *);
       
  1069 
       
  1070     QNativeSocketEngine *engine;
       
  1071 };
       
  1072 
       
  1073 bool QWriteNotifier::event(QEvent *e)
       
  1074 {
       
  1075     if (e->type() == QEvent::SockAct) {
       
  1076         if (engine->state() == QAbstractSocket::ConnectingState)
       
  1077             engine->connectionNotification();
       
  1078         else
       
  1079             engine->writeNotification();
       
  1080         return true;
       
  1081     }
       
  1082     return QSocketNotifier::event(e);
       
  1083 }
       
  1084 
       
  1085 class QExceptionNotifier : public QSocketNotifier
       
  1086 {
       
  1087 public:
       
  1088     QExceptionNotifier(int fd, QNativeSocketEngine *parent)
       
  1089         : QSocketNotifier(fd, QSocketNotifier::Exception, parent) { engine = parent; }
       
  1090 
       
  1091 protected:
       
  1092     bool event(QEvent *);
       
  1093 
       
  1094     QNativeSocketEngine *engine;
       
  1095 };
       
  1096 
       
  1097 bool QExceptionNotifier::event(QEvent *e)
       
  1098 {
       
  1099     if (e->type() == QEvent::SockAct) {
       
  1100         if (engine->state() == QAbstractSocket::ConnectingState)
       
  1101             engine->connectionNotification();
       
  1102         else
       
  1103             engine->exceptionNotification();
       
  1104         return true;
       
  1105     }
       
  1106     return QSocketNotifier::event(e);
       
  1107 }
       
  1108 
       
  1109 void QNativeSocketEngine::setReadNotificationEnabled(bool enable)
       
  1110 {
       
  1111     Q_D(QNativeSocketEngine);
       
  1112     if (d->readNotifier) {
       
  1113         d->readNotifier->setEnabled(enable);
       
  1114     } else if (enable && d->threadData->eventDispatcher) {
       
  1115         d->readNotifier = new QReadNotifier(d->socketDescriptor, this);
       
  1116         d->readNotifier->setEnabled(true);
       
  1117     }
       
  1118 }
       
  1119 
       
  1120 bool QNativeSocketEngine::isWriteNotificationEnabled() const
       
  1121 {
       
  1122     Q_D(const QNativeSocketEngine);
       
  1123     return d->writeNotifier && d->writeNotifier->isEnabled();
       
  1124 }
       
  1125 
       
  1126 void QNativeSocketEngine::setWriteNotificationEnabled(bool enable)
       
  1127 {
       
  1128     Q_D(QNativeSocketEngine);
       
  1129     if (d->writeNotifier) {
       
  1130         d->writeNotifier->setEnabled(enable);
       
  1131     } else if (enable && d->threadData->eventDispatcher) {
       
  1132         d->writeNotifier = new QWriteNotifier(d->socketDescriptor, this);
       
  1133         d->writeNotifier->setEnabled(true);
       
  1134     }
       
  1135 }
       
  1136 
       
  1137 bool QNativeSocketEngine::isExceptionNotificationEnabled() const
       
  1138 {
       
  1139     Q_D(const QNativeSocketEngine);
       
  1140     return d->exceptNotifier && d->exceptNotifier->isEnabled();
       
  1141 }
       
  1142 
       
  1143 void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable)
       
  1144 {
       
  1145     Q_D(QNativeSocketEngine);
       
  1146     if (d->exceptNotifier) {
       
  1147         d->exceptNotifier->setEnabled(enable);
       
  1148     } else if (enable && d->threadData->eventDispatcher) {
       
  1149         d->exceptNotifier = new QExceptionNotifier(d->socketDescriptor, this);
       
  1150         d->exceptNotifier->setEnabled(true);
       
  1151     }
       
  1152 }
       
  1153 
       
  1154 QT_END_NAMESPACE