~ubuntu-branches/ubuntu/quantal/psi/quantal

« back to all changes in this revision

Viewing changes to cutestuff/network/bsocket.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-04-14 18:57:30 UTC
  • mfrom: (2.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080414185730-528re3zp0m2hdlhi
Tags: 0.11-8
* added CONFIG -= link_prl to .pro files and removed dependencies
  which are made unnecessary by this change
* Fix segfault when closing last chat tab with qt4.4
  (This is from upstream svn, rev. 1101) (Closes: Bug#476122)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *
19
19
 */
20
20
 
21
 
#include"bsocket.h"
22
 
 
23
 
#include<qcstring.h>
24
 
#include<qsocket.h>
25
 
#include<qdns.h>
26
 
#include<qguardedptr.h>
27
 
#include"safedelete.h"
 
21
#include <QTcpSocket>
 
22
#include <QHostAddress>
 
23
#include <QMetaType>
 
24
 
 
25
#include "bsocket.h"
 
26
 
 
27
//#include "safedelete.h"
28
28
#ifndef NO_NDNS
29
 
#include"ndns.h"
 
29
#include "ndns.h"
30
30
#endif
31
 
#include"srvresolver.h"
 
31
#include "srvresolver.h"
 
32
 
 
33
//#define BS_DEBUG
32
34
 
33
35
#ifdef BS_DEBUG
34
 
#include<stdio.h>
 
36
#include <stdio.h>
35
37
#endif
36
38
 
37
39
#define READBUFSIZE 65536
38
40
 
39
41
// CS_NAMESPACE_BEGIN
40
42
 
 
43
class QTcpSocketSignalRelay : public QObject
 
44
{
 
45
        Q_OBJECT
 
46
public:
 
47
        QTcpSocketSignalRelay(QTcpSocket *sock, QObject *parent = 0)
 
48
        :QObject(parent)
 
49
        {
 
50
                qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
 
51
                connect(sock, SIGNAL(hostFound()), SLOT(sock_hostFound()), Qt::QueuedConnection);
 
52
                connect(sock, SIGNAL(connected()), SLOT(sock_connected()), Qt::QueuedConnection);
 
53
                connect(sock, SIGNAL(disconnected()), SLOT(sock_disconnected()), Qt::QueuedConnection);
 
54
                connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()), Qt::QueuedConnection);
 
55
                connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64)), Qt::QueuedConnection);
 
56
                connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError)), Qt::QueuedConnection);
 
57
        }
 
58
 
 
59
signals:
 
60
        void hostFound();
 
61
        void connected();
 
62
        void disconnected();
 
63
        void readyRead();
 
64
        void bytesWritten(qint64);
 
65
        void error(QAbstractSocket::SocketError);
 
66
 
 
67
public slots:
 
68
        void sock_hostFound()
 
69
        {
 
70
                emit hostFound();
 
71
        }
 
72
 
 
73
        void sock_connected()
 
74
        {
 
75
                emit connected();
 
76
        }
 
77
 
 
78
        void sock_disconnected()
 
79
        {
 
80
                emit disconnected();
 
81
        }
 
82
 
 
83
        void sock_readyRead()
 
84
        {
 
85
                emit readyRead();
 
86
        }
 
87
 
 
88
        void sock_bytesWritten(qint64 x)
 
89
        {
 
90
                emit bytesWritten(x);
 
91
        }
 
92
 
 
93
        void sock_error(QAbstractSocket::SocketError x)
 
94
        {
 
95
                emit error(x);
 
96
        }
 
97
};
 
98
 
41
99
class BSocket::Private
42
100
{
43
101
public:
44
102
        Private()
45
103
        {
46
104
                qsock = 0;
 
105
                qsock_relay = 0;
47
106
        }
48
107
 
49
 
        QSocket *qsock;
 
108
        QTcpSocket *qsock;
 
109
        QTcpSocketSignalRelay *qsock_relay;
50
110
        int state;
51
111
 
52
112
#ifndef NO_NDNS
55
115
        SrvResolver srv;
56
116
        QString host;
57
117
        int port;
58
 
        SafeDelete sd;
 
118
        //SafeDelete sd;
59
119
};
60
120
 
61
121
BSocket::BSocket(QObject *parent)
79
139
void BSocket::reset(bool clear)
80
140
{
81
141
        if(d->qsock) {
82
 
                d->qsock->disconnect(this);
83
 
 
84
 
                if(!clear && d->qsock->isOpen()) {
 
142
                delete d->qsock_relay;
 
143
                d->qsock_relay = 0;
 
144
 
 
145
                /*d->qsock->disconnect(this);
 
146
 
 
147
                if(!clear && d->qsock->isOpen() && d->qsock->isValid()) {*/
85
148
                        // move remaining into the local queue
86
 
                        QByteArray block(d->qsock->bytesAvailable());
87
 
                        d->qsock->readBlock(block.data(), block.size());
 
149
                        QByteArray block(d->qsock->bytesAvailable(), 0);
 
150
                        d->qsock->read(block.data(), block.size());
88
151
                        appendRead(block);
89
 
                }
 
152
                //}
90
153
 
91
 
                d->sd.deleteLater(d->qsock);
 
154
                //d->sd.deleteLater(d->qsock);
 
155
                delete d->qsock;
92
156
                d->qsock = 0;
93
157
        }
94
158
        else {
108
172
void BSocket::ensureSocket()
109
173
{
110
174
        if(!d->qsock) {
111
 
                d->qsock = new QSocket;
 
175
                d->qsock = new QTcpSocket;
112
176
#if QT_VERSION >= 0x030200
113
177
                d->qsock->setReadBufferSize(READBUFSIZE);
114
178
#endif
115
 
                connect(d->qsock, SIGNAL(hostFound()), SLOT(qs_hostFound()));
116
 
                connect(d->qsock, SIGNAL(connected()), SLOT(qs_connected()));
117
 
                connect(d->qsock, SIGNAL(connectionClosed()), SLOT(qs_connectionClosed()));
118
 
                connect(d->qsock, SIGNAL(delayedCloseFinished()), SLOT(qs_delayedCloseFinished()));
119
 
                connect(d->qsock, SIGNAL(readyRead()), SLOT(qs_readyRead()));
120
 
                connect(d->qsock, SIGNAL(bytesWritten(int)), SLOT(qs_bytesWritten(int)));
121
 
                connect(d->qsock, SIGNAL(error(int)), SLOT(qs_error(int)));
 
179
                d->qsock_relay = new QTcpSocketSignalRelay(d->qsock);
 
180
                connect(d->qsock_relay, SIGNAL(hostFound()), SLOT(qs_hostFound()));
 
181
                connect(d->qsock_relay, SIGNAL(connected()), SLOT(qs_connected()));
 
182
                connect(d->qsock_relay, SIGNAL(disconnected()), SLOT(qs_closed()));
 
183
                connect(d->qsock_relay, SIGNAL(readyRead()), SLOT(qs_readyRead()));
 
184
                connect(d->qsock_relay, SIGNAL(bytesWritten(qint64)), SLOT(qs_bytesWritten(qint64)));
 
185
                connect(d->qsock_relay, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(qs_error(QAbstractSocket::SocketError)));
122
186
        }
123
187
}
124
188
 
125
 
void BSocket::connectToHost(const QString &host, Q_UINT16 port)
 
189
void BSocket::connectToHost(const QString &host, quint16 port)
126
190
{
127
191
        reset(true);
128
192
        d->host = host;
146
210
int BSocket::socket() const
147
211
{
148
212
        if(d->qsock)
149
 
                return d->qsock->socket();
 
213
                return d->qsock->socketDescriptor();
150
214
        else
151
215
                return -1;
152
216
}
156
220
        reset(true);
157
221
        ensureSocket();
158
222
        d->state = Connected;
159
 
        d->qsock->setSocket(s);
 
223
        d->qsock->setSocketDescriptor(s);
160
224
}
161
225
 
162
226
int BSocket::state() const
193
257
        if(d->state != Connected)
194
258
                return;
195
259
#ifdef BS_DEBUG
196
 
        QCString cs;
197
 
        cs.resize(a.size()+1);
198
 
        memcpy(cs.data(), a.data(), a.size());
199
 
        QString s = QString::fromUtf8(cs);
200
 
        fprintf(stderr, "BSocket: writing [%d]: {%s}\n", a.size(), cs.data());
 
260
        QString s = QString::fromUtf8(a);
 
261
        fprintf(stderr, "BSocket: writing [%d]: {%s}\n", a.size(), s.latin1());
201
262
#endif
202
 
        d->qsock->writeBlock(a.data(), a.size());
 
263
        d->qsock->write(a.data(), a.size());
203
264
}
204
265
 
205
266
QByteArray BSocket::read(int bytes)
210
271
                if(bytes <= 0 || bytes > max)
211
272
                        bytes = max;
212
273
                block.resize(bytes);
213
 
                d->qsock->readBlock(block.data(), block.size());
 
274
                d->qsock->read(block.data(), block.size());
214
275
        }
215
276
        else
216
277
                block = ByteStream::read(bytes);
217
278
 
218
279
#ifdef BS_DEBUG
219
 
        QCString cs;
220
 
        cs.resize(block.size()+1);
221
 
        memcpy(cs.data(), block.data(), block.size());
222
 
        QString s = QString::fromUtf8(cs);
 
280
        QString s = QString::fromUtf8(block);
223
281
        fprintf(stderr, "BSocket: read [%d]: {%s}\n", block.size(), s.latin1());
224
282
#endif
225
283
        return block;
243
301
QHostAddress BSocket::address() const
244
302
{
245
303
        if(d->qsock)
246
 
                return d->qsock->address();
 
304
                return d->qsock->localAddress();
247
305
        else
248
306
                return QHostAddress();
249
307
}
250
308
 
251
 
Q_UINT16 BSocket::port() const
 
309
quint16 BSocket::port() const
252
310
{
253
311
        if(d->qsock)
254
 
                return d->qsock->port();
 
312
                return d->qsock->localPort();
255
313
        else
256
314
                return 0;
257
315
}
264
322
                return QHostAddress();
265
323
}
266
324
 
267
 
Q_UINT16 BSocket::peerPort() const
 
325
quint16 BSocket::peerPort() const
268
326
{
269
327
        if(d->qsock)
270
 
                return d->qsock->port();
 
328
                return d->qsock->peerPort();
271
329
        else
272
330
                return 0;
273
331
}
292
350
void BSocket::ndns_done()
293
351
{
294
352
#ifndef NO_NDNS
295
 
        if(d->ndns.result()) {
 
353
        if(!d->ndns.result().isNull()) {
296
354
                d->host = d->ndns.resultString();
297
355
                d->state = Connecting;
298
356
                do_connect();
328
386
#ifdef BS_DEBUG
329
387
        fprintf(stderr, "BSocket: Connected.\n");
330
388
#endif
331
 
        SafeDeleteLock s(&d->sd);
 
389
        //SafeDeleteLock s(&d->sd);
332
390
        connected();
333
391
}
334
392
 
335
 
void BSocket::qs_connectionClosed()
336
 
{
337
 
#ifdef BS_DEBUG
338
 
        fprintf(stderr, "BSocket: Connection Closed.\n");
339
 
#endif
340
 
        SafeDeleteLock s(&d->sd);
341
 
        reset();
342
 
        connectionClosed();
343
 
}
344
 
 
345
 
void BSocket::qs_delayedCloseFinished()
346
 
{
347
 
#ifdef BS_DEBUG
348
 
        fprintf(stderr, "BSocket: Delayed Close Finished.\n");
349
 
#endif
350
 
        SafeDeleteLock s(&d->sd);
351
 
        reset();
352
 
        delayedCloseFinished();
 
393
void BSocket::qs_closed()
 
394
{
 
395
        if(d->state == Closing)
 
396
        {
 
397
#ifdef BS_DEBUG
 
398
                fprintf(stderr, "BSocket: Delayed Close Finished.\n");
 
399
#endif
 
400
                //SafeDeleteLock s(&d->sd);
 
401
                reset();
 
402
                delayedCloseFinished();
 
403
        }
353
404
}
354
405
 
355
406
void BSocket::qs_readyRead()
356
407
{
357
 
        SafeDeleteLock s(&d->sd);
 
408
        //SafeDeleteLock s(&d->sd);
358
409
        readyRead();
359
410
}
360
411
 
361
 
void BSocket::qs_bytesWritten(int x)
 
412
void BSocket::qs_bytesWritten(qint64 x64)
362
413
{
 
414
        int x = x64;
363
415
#ifdef BS_DEBUG
364
416
        fprintf(stderr, "BSocket: BytesWritten [%d].\n", x);
365
417
#endif
366
 
        SafeDeleteLock s(&d->sd);
 
418
        //SafeDeleteLock s(&d->sd);
367
419
        bytesWritten(x);
368
420
}
369
421
 
370
 
void BSocket::qs_error(int x)
 
422
void BSocket::qs_error(QAbstractSocket::SocketError x)
371
423
{
 
424
        if(x == QTcpSocket::RemoteHostClosedError) {
 
425
#ifdef BS_DEBUG
 
426
                fprintf(stderr, "BSocket: Connection Closed.\n");
 
427
#endif
 
428
                //SafeDeleteLock s(&d->sd);
 
429
                reset();
 
430
                connectionClosed();
 
431
                return;
 
432
        }
 
433
 
372
434
#ifdef BS_DEBUG
373
435
        fprintf(stderr, "BSocket: Error.\n");
374
436
#endif
375
 
        SafeDeleteLock s(&d->sd);
 
437
        //SafeDeleteLock s(&d->sd);
376
438
 
377
439
        // connection error during SRV host connect?  try next
378
 
        if(d->state == HostLookup && (x == QSocket::ErrConnectionRefused || x == QSocket::ErrHostNotFound)) {
 
440
        if(d->state == HostLookup && (x == QTcpSocket::ConnectionRefusedError || x == QTcpSocket::HostNotFoundError)) {
379
441
                d->srv.next();
380
442
                return;
381
443
        }
382
444
 
383
445
        reset();
384
 
        if(x == QSocket::ErrConnectionRefused)
 
446
        if(x == QTcpSocket::ConnectionRefusedError)
385
447
                error(ErrConnectionRefused);
386
 
        else if(x == QSocket::ErrHostNotFound)
 
448
        else if(x == QTcpSocket::HostNotFoundError)
387
449
                error(ErrHostNotFound);
388
 
        else if(x == QSocket::ErrSocketRead)
 
450
        else
389
451
                error(ErrRead);
390
452
}
391
453
 
 
454
#include "bsocket.moc"
 
455
 
392
456
// CS_NAMESPACE_END