• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • network
kbufferedsocket.cpp
1/*
2 * Copyright (C) 2003-2005 Thiago Macieira <thiago.macieira@kdemail.net>
3 *
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include <config.h>
26
27#include <tqmutex.h>
28#include <tqtimer.h>
29
30#include "tdesocketdevice.h"
31#include "tdesocketaddress.h"
32#include "tdesocketbuffer_p.h"
33#include "kbufferedsocket.h"
34
35using namespace KNetwork;
36using namespace KNetwork::Internal;
37
38class KNetwork::TDEBufferedSocketPrivate
39{
40public:
41 mutable TDESocketBuffer *input, *output;
42
43 TDEBufferedSocketPrivate()
44 {
45 input = 0L;
46 output = 0L;
47 }
48};
49
50TDEBufferedSocket::TDEBufferedSocket(const TQString& host, const TQString& service,
51 TQObject *parent, const char *name)
52 : KStreamSocket(host, service, parent, name),
53 d(new TDEBufferedSocketPrivate)
54{
55 setInputBuffering(true);
56 setOutputBuffering(true);
57}
58
59TDEBufferedSocket::~TDEBufferedSocket()
60{
61 closeNow();
62 delete d->input;
63 delete d->output;
64 delete d;
65}
66
67void TDEBufferedSocket::setSocketDevice(TDESocketDevice* device)
68{
69 KStreamSocket::setSocketDevice(device);
70 device->setBlocking(false);
71}
72
73bool TDEBufferedSocket::setSocketOptions(int opts)
74{
75 if (opts == Blocking)
76 return false;
77
78 opts &= ~Blocking;
79 return KStreamSocket::setSocketOptions(opts);
80}
81
82void TDEBufferedSocket::close()
83{
84 if (!d->output || d->output->isEmpty())
85 closeNow();
86 else
87 {
88 setState(Closing);
89 TQSocketNotifier *n = socketDevice()->readNotifier();
90 if (n)
91 n->setEnabled(false);
92 emit stateChanged(Closing);
93 }
94}
95
96TQ_LONG TDEBufferedSocket::bytesAvailable() const
97{
98 if (!d->input)
99 return KStreamSocket::bytesAvailable();
100
101 return d->input->length();
102}
103
104TQ_LONG TDEBufferedSocket::waitForMore(int msecs, bool *timeout)
105{
106 TQ_LONG retval = KStreamSocket::waitForMore(msecs, timeout);
107 if (d->input)
108 {
109 resetError();
110 slotReadActivity();
111 return bytesAvailable();
112 }
113 return retval;
114}
115
116TQ_LONG TDEBufferedSocket::readBlock(char *data, TQ_ULONG maxlen)
117{
118 if (d->input)
119 {
120 if (d->input->isEmpty())
121 {
122 setError(IO_ReadError, WouldBlock);
123 emit gotError(WouldBlock);
124 return -1;
125 }
126 resetError();
127 return d->input->consumeBuffer(data, maxlen);
128 }
129 return KStreamSocket::readBlock(data, maxlen);
130}
131
132TQ_LONG TDEBufferedSocket::readBlock(char *data, TQ_ULONG maxlen, TDESocketAddress& from)
133{
134 from = peerAddress();
135 return readBlock(data, maxlen);
136}
137
138TQ_LONG TDEBufferedSocket::peekBlock(char *data, TQ_ULONG maxlen)
139{
140 if (d->input)
141 {
142 if (d->input->isEmpty())
143 {
144 setError(IO_ReadError, WouldBlock);
145 emit gotError(WouldBlock);
146 return -1;
147 }
148 resetError();
149 return d->input->consumeBuffer(data, maxlen, false);
150 }
151 return KStreamSocket::peekBlock(data, maxlen);
152}
153
154TQ_LONG TDEBufferedSocket::peekBlock(char *data, TQ_ULONG maxlen, TDESocketAddress& from)
155{
156 from = peerAddress();
157 return peekBlock(data, maxlen);
158}
159
160TQ_LONG TDEBufferedSocket::writeBlock(const char *data, TQ_ULONG len)
161{
162 if (state() != Connected)
163 {
164 // cannot write now!
165 setError(IO_WriteError, NotConnected);
166 return -1;
167 }
168
169 if (d->output)
170 {
171 if (d->output->isFull())
172 {
173 setError(IO_WriteError, WouldBlock);
174 emit gotError(WouldBlock);
175 return -1;
176 }
177 resetError();
178
179 // enable notifier to send data
180 TQSocketNotifier *n = socketDevice()->writeNotifier();
181 if (n)
182 n->setEnabled(true);
183
184 return d->output->feedBuffer(data, len);
185 }
186
187 return KStreamSocket::writeBlock(data, len);
188}
189
190TQ_LONG TDEBufferedSocket::writeBlock(const char *data, TQ_ULONG maxlen,
191 const TDESocketAddress&)
192{
193 // ignore the third parameter
194 return writeBlock(data, maxlen);
195}
196
197void TDEBufferedSocket::enableRead(bool enable)
198{
199 KStreamSocket::enableRead(enable);
200 if (!enable && d->input)
201 {
202 // reenable it
203 TQSocketNotifier *n = socketDevice()->readNotifier();
204 if (n)
205 n->setEnabled(true);
206 }
207
208 if (enable && state() != Connected && d->input && !d->input->isEmpty())
209 // this means the buffer is still dirty
210 // allow the signal to be emitted
211 TQTimer::singleShot(0, this, TQ_SLOT(slotReadActivity()));
212}
213
214void TDEBufferedSocket::enableWrite(bool enable)
215{
216 KStreamSocket::enableWrite(enable);
217 if (!enable && d->output && !d->output->isEmpty())
218 {
219 // reenable it
220 TQSocketNotifier *n = socketDevice()->writeNotifier();
221 if (n)
222 n->setEnabled(true);
223 }
224}
225
226void TDEBufferedSocket::stateChanging(SocketState newState)
227{
228 if (newState == Connecting || newState == Connected)
229 {
230 // we're going to connect
231 // make sure the buffers are clean
232 if (d->input)
233 d->input->clear();
234 if (d->output)
235 d->output->clear();
236
237 // also, turn on notifiers
238 enableRead(emitsReadyRead());
239 enableWrite(emitsReadyWrite());
240 }
241 KStreamSocket::stateChanging(newState);
242}
243
244void TDEBufferedSocket::setInputBuffering(bool enable)
245{
246 TQMutexLocker locker(mutex());
247 if (!enable)
248 {
249 delete d->input;
250 d->input = 0L;
251 }
252 else if (d->input == 0L)
253 {
254 d->input = new TDESocketBuffer;
255 }
256}
257
258TDEIOBufferBase* TDEBufferedSocket::inputBuffer()
259{
260 return d->input;
261}
262
263void TDEBufferedSocket::setOutputBuffering(bool enable)
264{
265 TQMutexLocker locker(mutex());
266 if (!enable)
267 {
268 delete d->output;
269 d->output = 0L;
270 }
271 else if (d->output == 0L)
272 {
273 d->output = new TDESocketBuffer;
274 }
275}
276
277TDEIOBufferBase* TDEBufferedSocket::outputBuffer()
278{
279 return d->output;
280}
281
282TQ_ULONG TDEBufferedSocket::bytesToWrite() const
283{
284 if (!d->output)
285 return 0;
286
287 return d->output->length();
288}
289
290void TDEBufferedSocket::closeNow()
291{
292 KStreamSocket::close();
293 if (d->output)
294 d->output->clear();
295}
296
297bool TDEBufferedSocket::canReadLine() const
298{
299 if (!d->input)
300 return false;
301
302 return d->input->canReadLine();
303}
304
305TQCString TDEBufferedSocket::readLine()
306{
307 return d->input->readLine();
308}
309
310void TDEBufferedSocket::waitForConnect()
311{
312 if (state() != Connecting)
313 return; // nothing to be waited on
314
315 KStreamSocket::setSocketOptions(socketOptions() | Blocking);
316 connectionEvent();
317 KStreamSocket::setSocketOptions(socketOptions() & ~Blocking);
318}
319
320void TDEBufferedSocket::slotReadActivity()
321{
322 if (d->input && state() == Connected)
323 {
324 mutex()->lock();
325 TQ_LONG len = d->input->receiveFrom(socketDevice());
326
327 if (len == -1)
328 {
329 if (socketDevice()->error() != WouldBlock)
330 {
331 // nope, another error!
332 copyError();
333 mutex()->unlock();
334 emit gotError(error());
335 closeNow(); // emits closed
336 return;
337 }
338 }
339 else if (len == 0)
340 {
341 // remotely closed
342 setError(IO_ReadError, RemotelyDisconnected);
343 mutex()->unlock();
344 emit gotError(error());
345 closeNow(); // emits closed
346 return;
347 }
348
349 // no error
350 mutex()->unlock();
351 }
352
353 if (state() == Connected)
354 KStreamSocket::slotReadActivity(); // this emits readyRead
355 else if (emitsReadyRead()) // state() != Connected
356 {
357 if (d->input && !d->input->isEmpty())
358 {
359 // buffer isn't empty
360 // keep emitting signals till it is
361 TQTimer::singleShot(0, this, TQ_SLOT(slotReadActivity()));
362 emit readyRead();
363 }
364 }
365}
366
367void TDEBufferedSocket::slotWriteActivity()
368{
369 if (d->output && !d->output->isEmpty() &&
370 (state() == Connected || state() == Closing))
371 {
372 mutex()->lock();
373 TQ_LONG len = d->output->sendTo(socketDevice());
374
375 if (len == -1)
376 {
377 if (socketDevice()->error() != WouldBlock)
378 {
379 // nope, another error!
380 copyError();
381 mutex()->unlock();
382 emit gotError(error());
383 closeNow();
384 return;
385 }
386 }
387 else if (len == 0)
388 {
389 // remotely closed
390 setError(IO_ReadError, RemotelyDisconnected);
391 mutex()->unlock();
392 emit gotError(error());
393 closeNow();
394 return;
395 }
396
397 if (d->output->isEmpty())
398 // deactivate the notifier until we have something to send
399 // writeNotifier can't return NULL here
400 socketDevice()->writeNotifier()->setEnabled(false);
401
402 mutex()->unlock();
403 emit bytesWritten(len);
404 }
405
406 if (state() != Closing)
407 KStreamSocket::slotWriteActivity();
408 else if (d->output && d->output->isEmpty() && state() == Closing)
409 {
410 KStreamSocket::close(); // finished sending data
411 }
412}
413
414#include "kbufferedsocket.moc"
KNetwork::KActiveSocketBase::setError
void setError(int status, SocketError error)
Sets the socket's error code and the I/O Device's status.
Definition: tdesocketbase.cpp:309
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: tdesocketbase.cpp:315
KNetwork::KClientSocketBase::waitForMore
virtual TQ_LONG waitForMore(int msecs, bool *timeout=0L)
Waits for more data.
Definition: kclientsocketbase.cpp:289
KNetwork::KClientSocketBase::emitsReadyWrite
bool emitsReadyWrite() const
Returns true if the readyWrite signal is set to be emitted.
Definition: kclientsocketbase.cpp:398
KNetwork::KClientSocketBase::SocketState
SocketState
Socket states.
Definition: kclientsocketbase.h:73
KNetwork::KClientSocketBase::stateChanging
virtual void stateChanging(SocketState newState)
This function is called by setState whenever the state changes.
Definition: kclientsocketbase.cpp:448
KNetwork::KClientSocketBase::writeBlock
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len)
Writes data to the socket.
Definition: kclientsocketbase.cpp:349
KNetwork::KClientSocketBase::bytesAvailable
virtual TQ_LONG bytesAvailable() const
Returns the number of bytes available on this socket.
Definition: kclientsocketbase.cpp:281
KNetwork::KClientSocketBase::enableRead
virtual void enableRead(bool enable)
Enables the emission of the readyRead signal.
Definition: kclientsocketbase.cpp:388
KNetwork::KClientSocketBase::slotReadActivity
virtual void slotReadActivity()
This slot is connected to the read notifier's signal meaning the socket can read more data.
Definition: kclientsocketbase.cpp:413
KNetwork::KClientSocketBase::enableWrite
virtual void enableWrite(bool enable)
Enables the emission of the readyWrite signal.
Definition: kclientsocketbase.cpp:403
KNetwork::KClientSocketBase::setState
void setState(SocketState state)
Sets the socket state to state.
Definition: kclientsocketbase.cpp:69
KNetwork::KClientSocketBase::readyRead
void readyRead()
This signal is emitted whenever the socket is ready for reading – i.e., there is data to be read in t...
KNetwork::KClientSocketBase::readBlock
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen)
Reads data from a socket.
Definition: kclientsocketbase.cpp:301
KNetwork::KClientSocketBase::close
virtual void close()
Closes the socket.
Definition: kclientsocketbase.cpp:261
KNetwork::KClientSocketBase::emitsReadyRead
bool emitsReadyRead() const
Returns true if the readyRead signal is set to be emitted.
Definition: kclientsocketbase.cpp:383
KNetwork::KClientSocketBase::state
SocketState state() const
Returns the current state for this socket.
Definition: kclientsocketbase.cpp:64
KNetwork::KClientSocketBase::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data from the socket.
Definition: kclientsocketbase.cpp:325
KNetwork::KClientSocketBase::gotError
void gotError(int code)
This signal is emitted when this object finds an error.
KNetwork::KClientSocketBase::copyError
void copyError()
Convenience function to set this object's error code to match that of the socket device.
Definition: kclientsocketbase.cpp:472
KNetwork::KClientSocketBase::slotWriteActivity
virtual void slotWriteActivity()
This slot is connected to the write notifier's signal meaning the socket can write more data.
Definition: kclientsocketbase.cpp:419
KNetwork::KClientSocketBase::peerAddress
virtual TDESocketAddress peerAddress() const
Returns the peer socket address.
Definition: kclientsocketbase.cpp:378
KNetwork::KClientSocketBase::setSocketOptions
virtual bool setSocketOptions(int opts)
Sets the socket options.
Definition: kclientsocketbase.cpp:75
KNetwork::KClientSocketBase::stateChanged
void stateChanged(int newstate)
This signal is emitted whenever the socket state changes.
KNetwork::KStreamSocket
Simple stream socket.
Definition: kstreamsocket.h:98
KNetwork::KStreamSocket::timeout
int timeout() const
Retrieves the timeout value (in milliseconds).
Definition: kstreamsocket.cpp:73
KNetwork::TDEBufferedSocket::stateChanging
virtual void stateChanging(SocketState newState)
Catch connection to clear the buffers.
Definition: kbufferedsocket.cpp:226
KNetwork::TDEBufferedSocket::setSocketOptions
virtual bool setSocketOptions(int opts)
Buffered sockets can only operate in non-blocking mode.
Definition: kbufferedsocket.cpp:73
KNetwork::TDEBufferedSocket::writeBlock
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len)
Writes data to the socket.
Definition: kbufferedsocket.cpp:160
KNetwork::TDEBufferedSocket::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data from the socket.
Definition: kbufferedsocket.cpp:138
KNetwork::TDEBufferedSocket::bytesAvailable
virtual TQ_LONG bytesAvailable() const
Make use of the buffers.
Definition: kbufferedsocket.cpp:96
KNetwork::TDEBufferedSocket::outputBuffer
TDEIOBufferBase * outputBuffer()
Retrieves the output buffer object.
Definition: kbufferedsocket.cpp:277
KNetwork::TDEBufferedSocket::waitForConnect
void waitForConnect()
Blocks until the connection is either established, or completely failed.
Definition: kbufferedsocket.cpp:310
KNetwork::TDEBufferedSocket::~TDEBufferedSocket
virtual ~TDEBufferedSocket()
Destructor.
Definition: kbufferedsocket.cpp:59
KNetwork::TDEBufferedSocket::bytesToWrite
virtual TQ_ULONG bytesToWrite() const
Returns the length of the output buffer.
Definition: kbufferedsocket.cpp:282
KNetwork::TDEBufferedSocket::readLine
TQCString readLine()
Reads a line of data from the socket buffers.
Definition: kbufferedsocket.cpp:305
KNetwork::TDEBufferedSocket::slotWriteActivity
virtual void slotWriteActivity()
Slot called when there's write activity.
Definition: kbufferedsocket.cpp:367
KNetwork::TDEBufferedSocket::enableRead
virtual void enableRead(bool enable)
Catch changes.
Definition: kbufferedsocket.cpp:197
KNetwork::TDEBufferedSocket::setSocketDevice
virtual void setSocketDevice(TDESocketDevice *device)
Be sure to catch new devices.
Definition: kbufferedsocket.cpp:67
KNetwork::TDEBufferedSocket::readBlock
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen)
Reads data from the socket.
Definition: kbufferedsocket.cpp:116
KNetwork::TDEBufferedSocket::close
virtual void close()
Closes the socket for new data, but allow data that had been buffered for output with writeBlock to b...
Definition: kbufferedsocket.cpp:82
KNetwork::TDEBufferedSocket::inputBuffer
TDEIOBufferBase * inputBuffer()
Retrieves the input buffer object.
Definition: kbufferedsocket.cpp:258
KNetwork::TDEBufferedSocket::slotReadActivity
virtual void slotReadActivity()
Slot called when there's read activity.
Definition: kbufferedsocket.cpp:320
KNetwork::TDEBufferedSocket::bytesWritten
void bytesWritten(int bytes)
This signal is emitted whenever data is written.
KNetwork::TDEBufferedSocket::waitForMore
virtual TQ_LONG waitForMore(int msecs, bool *timeout=0L)
Make use of buffers.
Definition: kbufferedsocket.cpp:104
KNetwork::TDEBufferedSocket::canReadLine
bool canReadLine() const
Returns true if a line can be read with readLine.
Definition: kbufferedsocket.cpp:297
KNetwork::TDEBufferedSocket::enableWrite
virtual void enableWrite(bool enable)
Catch changes.
Definition: kbufferedsocket.cpp:214
KNetwork::TDEBufferedSocket::closeNow
virtual void closeNow()
Closes the socket and discards any output data that had been buffered with writeBlock but that had no...
Definition: kbufferedsocket.cpp:290
KNetwork::TDEBufferedSocket::setOutputBuffering
void setOutputBuffering(bool enable)
Sets the use of output buffering.
Definition: kbufferedsocket.cpp:263
KNetwork::TDEBufferedSocket::setInputBuffering
void setInputBuffering(bool enable)
Sets the use of input buffering.
Definition: kbufferedsocket.cpp:244
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:424
KNetwork::TDESocketBase::setSocketDevice
virtual void setSocketDevice(TDESocketDevice *device)
Sets the socket implementation to be used on this socket.
Definition: tdesocketbase.cpp:136
KNetwork::TDESocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: tdesocketbase.cpp:76
KNetwork::TDESocketBase::mutex
TQMutex * mutex() const
Returns the internal mutex for this class.
Definition: tdesocketbase.cpp:278
KNetwork::TDESocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: tdesocketbase.cpp:160
KNetwork::TDESocketBase::socketDevice
TDESocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
Definition: tdesocketbase.cpp:116
KNetwork::TDESocketBase::socketOptions
virtual int socketOptions() const
Retrieves the socket options that have been set.
Definition: tdesocketbase.cpp:71
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:51
KNetwork::TDESocketDevice::writeNotifier
TQSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
Definition: tdesocketdevice.cpp:627
KNetwork::TDESocketDevice::readNotifier
TQSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
Definition: tdesocketdevice.cpp:609
TDEIOBufferBase
base for I/O buffer implementation
Definition: tdeiobuffer.h:46
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.