00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include <config.h>
00026
00027
#include <qmutex.h>
00028
#include <qtimer.h>
00029
00030
#include "ksocketdevice.h"
00031
#include "ksocketaddress.h"
00032
#include "ksocketbuffer_p.h"
00033
#include "kbufferedsocket.h"
00034
00035
using namespace KNetwork;
00036
using namespace KNetwork::Internal;
00037
00038
class KNetwork::KBufferedSocketPrivate
00039 {
00040
public:
00041
mutable KSocketBuffer *input, *output;
00042
00043 KBufferedSocketPrivate()
00044 {
00045 input = 0L;
00046 output = 0L;
00047 }
00048 };
00049
00050 KBufferedSocket::KBufferedSocket(
const QString& host,
const QString& service,
00051
QObject *parent,
const char *name)
00052 :
KStreamSocket(host, service, parent, name),
00053 d(new KBufferedSocketPrivate)
00054 {
00055
setBlocking(
false);
00056
setInputBuffering(
true);
00057
setOutputBuffering(
true);
00058 }
00059
00060 KBufferedSocket::~KBufferedSocket()
00061 {
00062
closeNow();
00063
delete d->input;
00064
delete d->output;
00065
delete d;
00066 }
00067
00068 void KBufferedSocket::setSocketDevice(
KSocketDevice* device)
00069 {
00070
KStreamSocket::setSocketDevice(device);
00071 device->
setBlocking(
false);
00072 }
00073
00074 bool KBufferedSocket::setSocketOptions(
int opts)
00075 {
00076
if (opts == Blocking)
00077
return false;
00078
00079 opts &= ~Blocking;
00080
return KStreamSocket::setSocketOptions(opts);
00081 }
00082
00083 void KBufferedSocket::close()
00084 {
00085
if (!d->output || d->output->isEmpty())
00086
closeNow();
00087
else
00088 {
00089
setState(Closing);
00090
QSocketNotifier *n =
socketDevice()->
readNotifier();
00091
if (n)
00092 n->setEnabled(
false);
00093 emit
stateChanged(Closing);
00094 }
00095 }
00096
00097 Q_LONG
KBufferedSocket::bytesAvailable()
const
00098
{
00099
if (!d->input)
00100
return KStreamSocket::bytesAvailable();
00101
00102
return d->input->length();
00103 }
00104
00105 Q_LONG
KBufferedSocket::waitForMore(
int msecs,
bool *timeout)
00106 {
00107 Q_LONG retval =
KStreamSocket::waitForMore(msecs, timeout);
00108
if (d->input)
00109 {
00110
resetError();
00111
slotReadActivity();
00112
return bytesAvailable();
00113 }
00114
return retval;
00115 }
00116
00117 Q_LONG
KBufferedSocket::readBlock(
char *data, Q_ULONG maxlen)
00118 {
00119
if (d->input)
00120 {
00121
if (d->input->isEmpty())
00122 {
00123
setError(IO_ReadError, WouldBlock);
00124 emit
gotError(WouldBlock);
00125
return -1;
00126 }
00127
resetError();
00128
return d->input->consumeBuffer(data, maxlen);
00129 }
00130
return KStreamSocket::readBlock(data, maxlen);
00131 }
00132
00133 Q_LONG
KBufferedSocket::readBlock(
char *data, Q_ULONG maxlen,
KSocketAddress& from)
00134 {
00135 from =
peerAddress();
00136
return readBlock(data, maxlen);
00137 }
00138
00139 Q_LONG
KBufferedSocket::peekBlock(
char *data, Q_ULONG maxlen)
00140 {
00141
if (d->input)
00142 {
00143
if (d->input->isEmpty())
00144 {
00145
setError(IO_ReadError, WouldBlock);
00146 emit
gotError(WouldBlock);
00147
return -1;
00148 }
00149
resetError();
00150
return d->input->consumeBuffer(data, maxlen,
false);
00151 }
00152
return KStreamSocket::peekBlock(data, maxlen);
00153 }
00154
00155 Q_LONG
KBufferedSocket::peekBlock(
char *data, Q_ULONG maxlen,
KSocketAddress& from)
00156 {
00157 from =
peerAddress();
00158
return peekBlock(data, maxlen);
00159 }
00160
00161 Q_LONG
KBufferedSocket::writeBlock(
const char *data, Q_ULONG len)
00162 {
00163
if (
state() != Connected)
00164 {
00165
00166
setError(IO_WriteError, NotConnected);
00167
return -1;
00168 }
00169
00170
if (d->output)
00171 {
00172
if (d->output->isFull())
00173 {
00174
setError(IO_WriteError, WouldBlock);
00175 emit
gotError(WouldBlock);
00176
return -1;
00177 }
00178
resetError();
00179
00180
00181
QSocketNotifier *n =
socketDevice()->
writeNotifier();
00182
if (n)
00183 n->setEnabled(
true);
00184
00185
return d->output->feedBuffer(data, len);
00186 }
00187
00188
return KStreamSocket::writeBlock(data, len);
00189 }
00190
00191 Q_LONG
KBufferedSocket::writeBlock(
const char *data, Q_ULONG maxlen,
00192
const KSocketAddress&)
00193 {
00194
00195
return writeBlock(data, maxlen);
00196 }
00197
00198 void KBufferedSocket::enableRead(
bool enable)
00199 {
00200
KStreamSocket::enableRead(enable);
00201
if (!enable && d->input)
00202 {
00203
00204
QSocketNotifier *n =
socketDevice()->
readNotifier();
00205
if (n)
00206 n->setEnabled(
true);
00207 }
00208
00209
if (enable &&
state() != Connected && d->input && !d->input->isEmpty())
00210
00211
00212 QTimer::singleShot(0,
this, SLOT(
slotReadActivity()));
00213 }
00214
00215 void KBufferedSocket::enableWrite(
bool enable)
00216 {
00217
KStreamSocket::enableWrite(enable);
00218
if (!enable && d->output && !d->output->isEmpty())
00219 {
00220
00221
QSocketNotifier *n =
socketDevice()->
writeNotifier();
00222
if (n)
00223 n->setEnabled(
true);
00224 }
00225 }
00226
00227 void KBufferedSocket::stateChanging(SocketState newState)
00228 {
00229
if (newState == Connecting || newState == Connected)
00230 {
00231
00232
00233
if (d->input)
00234 d->input->clear();
00235
if (d->output)
00236 d->output->clear();
00237
00238
00239
enableRead(
emitsReadyRead());
00240
enableWrite(
emitsReadyWrite());
00241 }
00242
KStreamSocket::stateChanging(newState);
00243 }
00244
00245 void KBufferedSocket::setInputBuffering(
bool enable)
00246 {
00247
QMutexLocker locker(
mutex());
00248
if (!enable)
00249 {
00250
delete d->input;
00251 d->input = 0L;
00252 }
00253
else if (d->input == 0L)
00254 {
00255 d->input =
new KSocketBuffer;
00256 }
00257 }
00258
00259 KIOBufferBase*
KBufferedSocket::inputBuffer()
00260 {
00261
return d->input;
00262 }
00263
00264 void KBufferedSocket::setOutputBuffering(
bool enable)
00265 {
00266
QMutexLocker locker(
mutex());
00267
if (!enable)
00268 {
00269
delete d->output;
00270 d->output = 0L;
00271 }
00272
else if (d->output == 0L)
00273 {
00274 d->output =
new KSocketBuffer;
00275 }
00276 }
00277
00278 KIOBufferBase*
KBufferedSocket::outputBuffer()
00279 {
00280
return d->output;
00281 }
00282
00283 Q_ULONG
KBufferedSocket::bytesToWrite()
const
00284
{
00285
if (!d->output)
00286
return 0;
00287
00288
return d->output->length();
00289 }
00290
00291 void KBufferedSocket::closeNow()
00292 {
00293
KStreamSocket::close();
00294 }
00295
00296 bool KBufferedSocket::canReadLine()
const
00297
{
00298
if (!d->input)
00299
return false;
00300
00301
return d->input->canReadLine();
00302 }
00303
00304 QCString KBufferedSocket::readLine()
00305 {
00306
return d->input->readLine();
00307 }
00308
00309 void KBufferedSocket::slotReadActivity()
00310 {
00311
if (d->input &&
state() == Connected)
00312 {
00313
mutex()->lock();
00314 Q_LONG len = d->input->receiveFrom(
socketDevice());
00315
00316
if (len == -1)
00317 {
00318
if (
socketDevice()->
error() != WouldBlock)
00319 {
00320
00321
copyError();
00322
mutex()->unlock();
00323
closeNow();
00324
return;
00325 }
00326 }
00327
else if (len == 0)
00328 {
00329
00330
resetError();
00331
mutex()->unlock();
00332
closeNow();
00333
return;
00334 }
00335
00336
00337
mutex()->unlock();
00338 }
00339
00340
if (
state() == Connected)
00341
KStreamSocket::slotReadActivity();
00342
else if (
emitsReadyRead())
00343 {
00344
if (d->input && !d->input->isEmpty())
00345 {
00346
00347
00348 QTimer::singleShot(0,
this, SLOT(
slotReadActivity()));
00349 emit
readyRead();
00350 }
00351 }
00352 }
00353
00354 void KBufferedSocket::slotWriteActivity()
00355 {
00356
if (d->output && !d->output->isEmpty() &&
00357 (
state() == Connected ||
state() == Closing))
00358 {
00359
mutex()->lock();
00360 Q_LONG len = d->output->sendTo(
socketDevice());
00361
00362
if (len == -1)
00363 {
00364
if (
socketDevice()->
error() != WouldBlock)
00365 {
00366
00367
copyError();
00368
mutex()->unlock();
00369
closeNow();
00370
return;
00371 }
00372 }
00373
else if (len == 0)
00374 {
00375
00376
resetError();
00377
mutex()->unlock();
00378
closeNow();
00379
return;
00380 }
00381
00382
if (d->output->isEmpty())
00383
00384
00385
socketDevice()->
writeNotifier()->setEnabled(
false);
00386
00387
mutex()->unlock();
00388 emit
bytesWritten(len);
00389 }
00390
00391
if (
state() != Closing)
00392
KStreamSocket::slotWriteActivity();
00393
else if (d->output && d->output->isEmpty() &&
state() == Closing)
00394 {
00395
KStreamSocket::close();
00396 }
00397 }
00398
00399
#include "kbufferedsocket.moc"