• 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 
35 using namespace KNetwork;
36 using namespace KNetwork::Internal;
37 
38 class KNetwork::TDEBufferedSocketPrivate
39 {
40 public:
41  mutable TDESocketBuffer *input, *output;
42 
43  TDEBufferedSocketPrivate()
44  {
45  input = 0L;
46  output = 0L;
47  }
48 };
49 
50 TDEBufferedSocket::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 
59 TDEBufferedSocket::~TDEBufferedSocket()
60 {
61  closeNow();
62  delete d->input;
63  delete d->output;
64  delete d;
65 }
66 
67 void TDEBufferedSocket::setSocketDevice(TDESocketDevice* device)
68 {
69  KStreamSocket::setSocketDevice(device);
70  device->setBlocking(false);
71 }
72 
73 bool TDEBufferedSocket::setSocketOptions(int opts)
74 {
75  if (opts == Blocking)
76  return false;
77 
78  opts &= ~Blocking;
79  return KStreamSocket::setSocketOptions(opts);
80 }
81 
82 void 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 
96 #ifdef USE_QT3
97 TQ_LONG TDEBufferedSocket::bytesAvailable() const
98 #endif
99 #ifdef USE_QT4
100 qint64 TDEBufferedSocket::bytesAvailable() const
101 #endif
102 {
103  if (!d->input)
104  return KStreamSocket::bytesAvailable();
105 
106  return d->input->length();
107 }
108 
109 TQ_LONG TDEBufferedSocket::waitForMore(int msecs, bool *timeout)
110 {
111  TQ_LONG retval = KStreamSocket::waitForMore(msecs, timeout);
112  if (d->input)
113  {
114  resetError();
115  slotReadActivity();
116  return bytesAvailable();
117  }
118  return retval;
119 }
120 
121 TQT_TQIO_LONG TDEBufferedSocket::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
122 {
123  if (d->input)
124  {
125  if (d->input->isEmpty())
126  {
127  setError(IO_ReadError, WouldBlock);
128  emit gotError(WouldBlock);
129  return -1;
130  }
131  resetError();
132  return d->input->consumeBuffer(data, maxlen);
133  }
134  return KStreamSocket::tqreadBlock(data, maxlen);
135 }
136 
137 TQT_TQIO_LONG TDEBufferedSocket::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, TDESocketAddress& from)
138 {
139  from = peerAddress();
140  return tqreadBlock(data, maxlen);
141 }
142 
143 TQ_LONG TDEBufferedSocket::peekBlock(char *data, TQ_ULONG maxlen)
144 {
145  if (d->input)
146  {
147  if (d->input->isEmpty())
148  {
149  setError(IO_ReadError, WouldBlock);
150  emit gotError(WouldBlock);
151  return -1;
152  }
153  resetError();
154  return d->input->consumeBuffer(data, maxlen, false);
155  }
156  return KStreamSocket::peekBlock(data, maxlen);
157 }
158 
159 TQ_LONG TDEBufferedSocket::peekBlock(char *data, TQ_ULONG maxlen, TDESocketAddress& from)
160 {
161  from = peerAddress();
162  return peekBlock(data, maxlen);
163 }
164 
165 TQT_TQIO_LONG TDEBufferedSocket::tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
166 {
167  if (state() != Connected)
168  {
169  // cannot write now!
170  setError(IO_WriteError, NotConnected);
171  return -1;
172  }
173 
174  if (d->output)
175  {
176  if (d->output->isFull())
177  {
178  setError(IO_WriteError, WouldBlock);
179  emit gotError(WouldBlock);
180  return -1;
181  }
182  resetError();
183 
184  // enable notifier to send data
185  TQSocketNotifier *n = socketDevice()->writeNotifier();
186  if (n)
187  n->setEnabled(true);
188 
189  return d->output->feedBuffer(data, len);
190  }
191 
192  return KStreamSocket::tqwriteBlock(data, len);
193 }
194 
195 TQT_TQIO_LONG TDEBufferedSocket::tqwriteBlock(const char *data, TQT_TQIO_ULONG maxlen,
196  const TDESocketAddress&)
197 {
198  // ignore the third parameter
199  return tqwriteBlock(data, maxlen);
200 }
201 
202 void TDEBufferedSocket::enableRead(bool enable)
203 {
204  KStreamSocket::enableRead(enable);
205  if (!enable && d->input)
206  {
207  // reenable it
208  TQSocketNotifier *n = socketDevice()->readNotifier();
209  if (n)
210  n->setEnabled(true);
211  }
212 
213  if (enable && state() != Connected && d->input && !d->input->isEmpty())
214  // this means the buffer is still dirty
215  // allow the signal to be emitted
216  TQTimer::singleShot(0, this, TQT_SLOT(slotReadActivity()));
217 }
218 
219 void TDEBufferedSocket::enableWrite(bool enable)
220 {
221  KStreamSocket::enableWrite(enable);
222  if (!enable && d->output && !d->output->isEmpty())
223  {
224  // reenable it
225  TQSocketNotifier *n = socketDevice()->writeNotifier();
226  if (n)
227  n->setEnabled(true);
228  }
229 }
230 
231 void TDEBufferedSocket::stateChanging(SocketState newState)
232 {
233  if (newState == Connecting || newState == Connected)
234  {
235  // we're going to connect
236  // make sure the buffers are clean
237  if (d->input)
238  d->input->clear();
239  if (d->output)
240  d->output->clear();
241 
242  // also, turn on notifiers
243  enableRead(emitsReadyRead());
244  enableWrite(emitsReadyWrite());
245  }
246  KStreamSocket::stateChanging(newState);
247 }
248 
249 void TDEBufferedSocket::setInputBuffering(bool enable)
250 {
251  TQMutexLocker locker(mutex());
252  if (!enable)
253  {
254  delete d->input;
255  d->input = 0L;
256  }
257  else if (d->input == 0L)
258  {
259  d->input = new TDESocketBuffer;
260  }
261 }
262 
263 TDEIOBufferBase* TDEBufferedSocket::inputBuffer()
264 {
265  return d->input;
266 }
267 
268 void TDEBufferedSocket::setOutputBuffering(bool enable)
269 {
270  TQMutexLocker locker(mutex());
271  if (!enable)
272  {
273  delete d->output;
274  d->output = 0L;
275  }
276  else if (d->output == 0L)
277  {
278  d->output = new TDESocketBuffer;
279  }
280 }
281 
282 TDEIOBufferBase* TDEBufferedSocket::outputBuffer()
283 {
284  return d->output;
285 }
286 
287 #ifdef USE_QT3
288 TQ_ULONG TDEBufferedSocket::bytesToWrite() const
289 #endif
290 #ifdef USE_QT4
291 qint64 TDEBufferedSocket::bytesToWrite() const
292 #endif
293 {
294  if (!d->output)
295  return 0;
296 
297  return d->output->length();
298 }
299 
300 void TDEBufferedSocket::closeNow()
301 {
302  KStreamSocket::close();
303  if (d->output)
304  d->output->clear();
305 }
306 
307 bool TDEBufferedSocket::canReadLine() const
308 {
309  if (!d->input)
310  return false;
311 
312  return d->input->canReadLine();
313 }
314 
315 TQCString TDEBufferedSocket::readLine()
316 {
317  return d->input->readLine();
318 }
319 
320 void TDEBufferedSocket::waitForConnect()
321 {
322  if (state() != Connecting)
323  return; // nothing to be waited on
324 
325  KStreamSocket::setSocketOptions(socketOptions() | Blocking);
326  connectionEvent();
327  KStreamSocket::setSocketOptions(socketOptions() & ~Blocking);
328 }
329 
330 void TDEBufferedSocket::slotReadActivity()
331 {
332  if (d->input && state() == Connected)
333  {
334  mutex()->lock();
335  TQ_LONG len = d->input->receiveFrom(socketDevice());
336 
337  if (len == -1)
338  {
339  if (socketDevice()->error() != WouldBlock)
340  {
341  // nope, another error!
342  copyError();
343  mutex()->unlock();
344  emit gotError(error());
345  closeNow(); // emits closed
346  return;
347  }
348  }
349  else if (len == 0)
350  {
351  // remotely closed
352  setError(IO_ReadError, RemotelyDisconnected);
353  mutex()->unlock();
354  emit gotError(error());
355  closeNow(); // emits closed
356  return;
357  }
358 
359  // no error
360  mutex()->unlock();
361  }
362 
363  if (state() == Connected)
364  KStreamSocket::slotReadActivity(); // this emits readyRead
365  else if (emitsReadyRead()) // state() != Connected
366  {
367  if (d->input && !d->input->isEmpty())
368  {
369  // buffer isn't empty
370  // keep emitting signals till it is
371  TQTimer::singleShot(0, this, TQT_SLOT(slotReadActivity()));
372  emit readyRead();
373  }
374  }
375 }
376 
377 void TDEBufferedSocket::slotWriteActivity()
378 {
379  if (d->output && !d->output->isEmpty() &&
380  (state() == Connected || state() == Closing))
381  {
382  mutex()->lock();
383  TQ_LONG len = d->output->sendTo(socketDevice());
384 
385  if (len == -1)
386  {
387  if (socketDevice()->error() != WouldBlock)
388  {
389  // nope, another error!
390  copyError();
391  mutex()->unlock();
392  emit gotError(error());
393  closeNow();
394  return;
395  }
396  }
397  else if (len == 0)
398  {
399  // remotely closed
400  setError(IO_ReadError, RemotelyDisconnected);
401  mutex()->unlock();
402  emit gotError(error());
403  closeNow();
404  return;
405  }
406 
407  if (d->output->isEmpty())
408  // deactivate the notifier until we have something to send
409  // writeNotifier can't return NULL here
410  socketDevice()->writeNotifier()->setEnabled(false);
411 
412  mutex()->unlock();
413  emit bytesWritten(len);
414  }
415 
416  if (state() != Closing)
417  KStreamSocket::slotWriteActivity();
418  else if (d->output && d->output->isEmpty() && state() == Closing)
419  {
420  KStreamSocket::close(); // finished sending data
421  }
422 }
423 
424 #include "kbufferedsocket.moc"
KNetwork::TDESocketDevice::readNotifier
TQSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
Definition: tdesocketdevice.cpp:614
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:423
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::TDESocketBase::setSocketDevice
virtual void setSocketDevice(TDESocketDevice *device)
Sets the socket implementation to be used on this socket.
Definition: tdesocketbase.cpp:136
KNetwork::KStreamSocket
Simple stream socket.
Definition: kstreamsocket.h:97
KNetwork::KClientSocketBase::state
SocketState state() const
Returns the current state for this socket.
Definition: kclientsocketbase.cpp:72
KNetwork::TDEBufferedSocket::slotWriteActivity
virtual void slotWriteActivity()
Slot called when there's write activity.
Definition: kbufferedsocket.cpp:377
KNetwork::TDEBufferedSocket::~TDEBufferedSocket
virtual ~TDEBufferedSocket()
Destructor.
Definition: kbufferedsocket.cpp:59
KNetwork::Internal
Definition: kresolver.h:47
KNetwork::TDEBufferedSocket::enableRead
virtual void enableRead(bool enable)
Catch changes.
Definition: kbufferedsocket.cpp:202
TDEIOBufferBase
base for I/O buffer implementation
Definition: tdeiobuffer.h:45
KNetwork::TDESocketBase::mutex
TQMutex * mutex() const
Returns the internal mutex for this class.
Definition: tdesocketbase.cpp:278
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: tdesocketbase.cpp:315
KNetwork::KClientSocketBase::peerAddress
virtual TDESocketAddress peerAddress() const
Returns the peer socket address.
Definition: kclientsocketbase.cpp:391
KNetwork::TDEBufferedSocket::setSocketOptions
virtual bool setSocketOptions(int opts)
Buffered sockets can only operate in non-blocking mode.
Definition: kbufferedsocket.cpp:73
KNetwork::TDESocketDevice::writeNotifier
TQSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
Definition: tdesocketdevice.cpp:632
KNetwork::TDEBufferedSocket::readLine
TQCString readLine()
Reads a line of data from the socket buffers.
Definition: kbufferedsocket.cpp:315
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:50
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:426
KNetwork::TDESocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: tdesocketbase.cpp:160
KNetwork::TDEBufferedSocket::stateChanging
virtual void stateChanging(SocketState newState)
Catch connection to clear the buffers.
Definition: kbufferedsocket.cpp:231
KNetwork::KClientSocketBase::gotError
void gotError(int code)
This signal is emitted when this object finds an error.
KNetwork::TDEBufferedSocket::bytesWritten
void bytesWritten(int bytes)
This signal is emitted whenever data is written.
KNetwork::TDEBufferedSocket::inputBuffer
TDEIOBufferBase * inputBuffer()
Retrieves the input buffer object.
Definition: kbufferedsocket.cpp:263
KNetwork::KClientSocketBase::setSocketOptions
virtual bool setSocketOptions(int opts)
Sets the socket options.
Definition: kclientsocketbase.cpp:83
KNetwork::TDEBufferedSocket::enableWrite
virtual void enableWrite(bool enable)
Catch changes.
Definition: kbufferedsocket.cpp:219
KNetwork::KClientSocketBase::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data from the socket.
Definition: kclientsocketbase.cpp:338
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36
KNetwork::TDEBufferedSocket::slotReadActivity
virtual void slotReadActivity()
Slot called when there's read activity.
Definition: kbufferedsocket.cpp:330
KNetwork::KClientSocketBase::copyError
void copyError()
Convenience function to set this object's error code to match that of the socket device.
Definition: kclientsocketbase.cpp:485
KNetwork::TDEBufferedSocket::peekBlock
virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen)
Peeks data from the socket.
Definition: kbufferedsocket.cpp:143
KNetwork::TDEBufferedSocket::setOutputBuffering
void setOutputBuffering(bool enable)
Sets the use of output buffering.
Definition: kbufferedsocket.cpp:268
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::TDEBufferedSocket::tqwriteBlock
virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
Writes data to the socket.
Definition: kbufferedsocket.cpp:165
KNetwork::KClientSocketBase::SocketState
SocketState
Socket states.
Definition: kclientsocketbase.h:81
KNetwork::TDEBufferedSocket::outputBuffer
TDEIOBufferBase * outputBuffer()
Retrieves the output buffer object.
Definition: kbufferedsocket.cpp:282
KNetwork::KClientSocketBase::setState
void setState(SocketState state)
Sets the socket state to state.
Definition: kclientsocketbase.cpp:77
KNetwork::TDEBufferedSocket::setSocketDevice
virtual void setSocketDevice(TDESocketDevice *device)
Be sure to catch new devices.
Definition: kbufferedsocket.cpp:67
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 ...
KNetwork::KClientSocketBase::stateChanged
void stateChanged(int newstate)
This signal is emitted whenever the socket state changes.
KNetwork::TDEBufferedSocket::waitForConnect
void waitForConnect()
Blocks until the connection is either established, or completely failed.
Definition: kbufferedsocket.cpp:320
KNetwork::TDEBufferedSocket::TDEBufferedSocket
TDEBufferedSocket(const TQString &node=TQString::null, const TQString &service=TQString::null, TQObject *parent=0L, const char *name=0L)
Default constructor.
Definition: kbufferedsocket.cpp:50
KNetwork::TDESocketBase::socketDevice
TDESocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
Definition: tdesocketbase.cpp:116
KNetwork::KClientSocketBase::tqwriteBlock
virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
Writes data to the socket.
Definition: kclientsocketbase.cpp:362
KNetwork::TDESocketBase::socketOptions
virtual int socketOptions() const
Retrieves the socket options that have been set.
Definition: tdesocketbase.cpp:71
KNetwork::KClientSocketBase::enableRead
virtual void enableRead(bool enable)
Enables the emission of the readyRead signal.
Definition: kclientsocketbase.cpp:401
KNetwork::KClientSocketBase::close
virtual void close()
Closes the socket.
Definition: kclientsocketbase.cpp:269
KNetwork::TDESocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: tdesocketbase.cpp:76
KNetwork::TDEBufferedSocket::tqreadBlock
virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
Reads data from the socket.
Definition: kbufferedsocket.cpp:121
KNetwork::TDEBufferedSocket::canReadLine
bool canReadLine() const
Returns true if a line can be read with readLine.
Definition: kbufferedsocket.cpp:307
KNetwork::KClientSocketBase::stateChanging
virtual void stateChanging(SocketState newState)
This function is called by setState whenever the state changes.
Definition: kclientsocketbase.cpp:461
KNetwork::KClientSocketBase::waitForMore
virtual TQ_LONG waitForMore(int msecs, bool *timeout=0L)
Returns the number of bytes available on this socket.
Definition: kclientsocketbase.cpp:302
KNetwork::KClientSocketBase::emitsReadyRead
bool emitsReadyRead() const
Returns true if the readyRead signal is set to be emitted.
Definition: kclientsocketbase.cpp:396
KNetwork::TDEBufferedSocket::setInputBuffering
void setInputBuffering(bool enable)
Sets the use of input buffering.
Definition: kbufferedsocket.cpp:249
KNetwork::TDEBufferedSocket::waitForMore
virtual TQ_LONG waitForMore(int msecs, bool *timeout=0L)
Make use of the buffers.
Definition: kbufferedsocket.cpp:109
KNetwork::KClientSocketBase::emitsReadyWrite
bool emitsReadyWrite() const
Returns true if the readyWrite signal is set to be emitted.
Definition: kclientsocketbase.cpp:411
KNetwork::KClientSocketBase::enableWrite
virtual void enableWrite(bool enable)
Enables the emission of the readyWrite signal.
Definition: kclientsocketbase.cpp:416
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:432
KNetwork::KClientSocketBase::tqreadBlock
virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
Reads data from a socket.
Definition: kclientsocketbase.cpp:314
KNetwork::TDEBufferedSocket::closeNow
virtual void closeNow()
Returns the length of the output buffer.
Definition: kbufferedsocket.cpp:300

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.8
This website is maintained by Timothy Pearson.