~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/qt3support/network/q3socket.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

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