• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • kdecore
  • network
k3bufferedsocket.cpp
Go to the documentation of this file.
1 /* -*- C++ -*-
2  * Copyright (C) 2003-2005 Thiago Macieira <thiago@kde.org>
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 "k3bufferedsocket.h"
26 
27 #include <config.h>
28 #include <config-network.h>
29 
30 #include <QMutex>
31 #include <QTimer>
32 
33 #include "k3socketdevice.h"
34 #include "k3socketaddress.h"
35 #include "k3socketbuffer_p.h"
36 
37 using namespace KNetwork;
38 using namespace KNetwork::Internal;
39 
40 class KNetwork::KBufferedSocketPrivate
41 {
42 public:
43  mutable KSocketBuffer *input, *output;
44 
45  KBufferedSocketPrivate()
46  {
47  input = 0L;
48  output = 0L;
49  }
50 };
51 
52 KBufferedSocket::KBufferedSocket(const QString& host, const QString& service,
53  QObject *parent)
54  : KStreamSocket(host, service, parent),
55  d(new KBufferedSocketPrivate)
56 {
57  setInputBuffering(true);
58  setOutputBuffering(true);
59 }
60 
61 KBufferedSocket::~KBufferedSocket()
62 {
63  closeNow();
64  delete d->input;
65  delete d->output;
66  delete d;
67 }
68 
69 void KBufferedSocket::setSocketDevice(KSocketDevice* device)
70 {
71  KStreamSocket::setSocketDevice(device);
72  device->setBlocking(false);
73  KActiveSocketBase::open(openMode() & ~Unbuffered);
74 }
75 
76 bool KBufferedSocket::setSocketOptions(int opts)
77 {
78  if (opts == Blocking)
79  return false;
80 
81  opts &= ~Blocking;
82  return KStreamSocket::setSocketOptions(opts);
83 }
84 
85 void KBufferedSocket::close()
86 {
87  if (!d->output || d->output->isEmpty())
88  closeNow();
89  else
90  {
91  setState(Closing);
92  QSocketNotifier *n = socketDevice()->readNotifier();
93  if (n)
94  n->setEnabled(false);
95  emit stateChanged(Closing);
96  }
97 }
98 
99 qint64 KBufferedSocket::bytesAvailable() const
100 {
101  if (!d->input)
102  return KStreamSocket::bytesAvailable();
103 
104  return d->input->length();
105 }
106 
107 qint64 KBufferedSocket::waitForMore(int msecs, bool *timeout)
108 {
109  qint64 retval = KStreamSocket::waitForMore(msecs, timeout);
110  if (d->input)
111  {
112  resetError();
113  slotReadActivity();
114  return bytesAvailable();
115  }
116  return retval;
117 }
118 
119 qint64 KBufferedSocket::readData(char *data, qint64 maxlen, KSocketAddress* from)
120 {
121  if (from)
122  *from = peerAddress();
123  if (d->input)
124  {
125  if (d->input->isEmpty())
126  {
127  return 0;
128  }
129  resetError();
130  return d->input->consumeBuffer(data, maxlen);
131  }
132  return KStreamSocket::readData(data, maxlen, 0L);
133 }
134 
135 qint64 KBufferedSocket::peekData(char *data, qint64 maxlen, KSocketAddress* from)
136 {
137  if (from)
138  *from = peerAddress();
139  if (d->input)
140  {
141  if (d->input->isEmpty())
142  {
143  return 0;
144  }
145  resetError();
146  return d->input->consumeBuffer(data, maxlen, false);
147  }
148  return KStreamSocket::peekData(data, maxlen, 0L);
149 }
150 
151 qint64 KBufferedSocket::writeData(const char *data, qint64 len,
152  const KSocketAddress*)
153 {
154  // ignore the third parameter
155  if (state() != Connected)
156  {
157  // cannot write now!
158  setError(NotConnected);
159  return -1;
160  }
161 
162  if (d->output)
163  {
164  if (d->output->isFull())
165  {
166  setError(WouldBlock);
167  emit gotError(WouldBlock);
168  return -1;
169  }
170  resetError();
171 
172  // enable notifier to send data
173  QSocketNotifier *n = socketDevice()->writeNotifier();
174  if (n)
175  n->setEnabled(true);
176 
177  return d->output->feedBuffer(data, len);
178  }
179 
180  return KStreamSocket::writeData(data, len, 0L);
181 }
182 
183 void KBufferedSocket::enableRead(bool enable)
184 {
185  KStreamSocket::enableRead(enable);
186  if (!enable && d->input)
187  {
188  // reenable it
189  QSocketNotifier *n = socketDevice()->readNotifier();
190  if (n)
191  n->setEnabled(true);
192  }
193 
194  if (enable && state() != Connected && d->input && !d->input->isEmpty())
195  // this means the buffer is still dirty
196  // allow the signal to be emitted
197  QTimer::singleShot(0, this, SLOT(slotReadActivity()));
198 }
199 
200 void KBufferedSocket::enableWrite(bool enable)
201 {
202  KStreamSocket::enableWrite(enable);
203  if (!enable && d->output && !d->output->isEmpty())
204  {
205  // reenable it
206  QSocketNotifier *n = socketDevice()->writeNotifier();
207  if (n)
208  n->setEnabled(true);
209  }
210 }
211 
212 void KBufferedSocket::stateChanging(SocketState newState)
213 {
214  if (newState == Connecting || newState == Connected)
215  {
216  // we're going to connect
217  // make sure the buffers are clean
218  if (d->input)
219  d->input->clear();
220  if (d->output)
221  d->output->clear();
222 
223  // also, turn on notifiers
224  enableRead(emitsReadyRead());
225  enableWrite(emitsReadyWrite());
226  }
227  KStreamSocket::stateChanging(newState);
228 }
229 
230 void KBufferedSocket::setInputBuffering(bool enable)
231 {
232  QMutexLocker locker(mutex());
233  if (!enable)
234  {
235  delete d->input;
236  d->input = 0L;
237  }
238  else if (d->input == 0L)
239  {
240  d->input = new KSocketBuffer;
241  }
242 }
243 
244 void KBufferedSocket::setOutputBuffering(bool enable)
245 {
246  QMutexLocker locker(mutex());
247  if (!enable)
248  {
249  delete d->output;
250  d->output = 0L;
251  }
252  else if (d->output == 0L)
253  {
254  d->output = new KSocketBuffer;
255  }
256 }
257 
258 qint64 KBufferedSocket::bytesToWrite() const
259 {
260  if (!d->output)
261  return 0;
262 
263  return d->output->length();
264 }
265 
266 void KBufferedSocket::closeNow()
267 {
268  KStreamSocket::close();
269  if (d->output)
270  d->output->clear();
271 }
272 
273 bool KBufferedSocket::canReadLine() const
274 {
275  if (!d->input)
276  return false;
277 
278  return d->input->canReadLine();
279 }
280 
281 qint64 KBufferedSocket::readLineData(char* data, qint64 maxSize)
282 {
283  return d->input->readLine(data, maxSize);
284 }
285 
286 void KBufferedSocket::waitForConnect()
287 {
288  if (state() != Connecting)
289  return; // nothing to be waited on
290 
291  KStreamSocket::setSocketOptions(socketOptions() | Blocking);
292  connectionEvent();
293  KStreamSocket::setSocketOptions(socketOptions() & ~Blocking);
294 }
295 
296 void KBufferedSocket::slotReadActivity()
297 {
298  if (d->input && state() == Connected)
299  {
300  mutex()->lock();
301  qint64 len = d->input->receiveFrom(socketDevice());
302 
303  if (len == -1)
304  {
305  if (socketDevice()->error() != WouldBlock)
306  {
307  // nope, another error!
308  copyError();
309  mutex()->unlock();
310  emit gotError(error());
311  closeNow(); // emits closed
312  return;
313  }
314  }
315  else if (len == 0)
316  {
317  // remotely closed
318  setError(RemotelyDisconnected);
319  mutex()->unlock();
320  emit gotError(error());
321  closeNow(); // emits closed
322  return;
323  }
324 
325  // no error
326  mutex()->unlock();
327  }
328 
329  if (state() == Connected)
330  KStreamSocket::slotReadActivity(); // this emits readyRead
331  else if (emitsReadyRead()) // state() != Connected
332  {
333  if (d->input && !d->input->isEmpty())
334  {
335  // buffer isn't empty
336  // keep emitting signals till it is
337  QTimer::singleShot(0, this, SLOT(slotReadActivity()));
338  emit readyRead();
339  }
340  }
341 }
342 
343 void KBufferedSocket::slotWriteActivity()
344 {
345  if (d->output && !d->output->isEmpty() &&
346  (state() == Connected || state() == Closing))
347  {
348  mutex()->lock();
349  qint64 len = d->output->sendTo(socketDevice());
350 
351  if (len == -1)
352  {
353  if (socketDevice()->error() != WouldBlock)
354  {
355  // nope, another error!
356  copyError();
357  mutex()->unlock();
358  emit gotError(error());
359  closeNow();
360  return;
361  }
362  }
363  else if (len == 0)
364  {
365  // remotely closed
366  setError(RemotelyDisconnected);
367  mutex()->unlock();
368  emit gotError(error());
369  closeNow();
370  return;
371  }
372 
373  if (d->output->isEmpty())
374  // deactivate the notifier until we have something to send
375  // writeNotifier can't return NULL here
376  socketDevice()->writeNotifier()->setEnabled(false);
377 
378  mutex()->unlock();
379  emit bytesWritten(len);
380  }
381 
382  if (state() != Closing)
383  KStreamSocket::slotWriteActivity();
384  else if (d->output && d->output->isEmpty() && state() == Closing)
385  {
386  KStreamSocket::close(); // finished sending data
387  }
388 }
389 
390 #include "k3bufferedsocket.moc"
k3socketaddress.h
qint64
KNetwork::KSocketBase::socketDevice
KSocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
Definition: k3socketbase.cpp:148
KNetwork::KStreamSocket
Simple stream socket.
Definition: k3streamsocket.h:98
k3socketdevice.h
KNetwork::KClientSocketBase::state
SocketState state() const
Returns the current state for this socket.
Definition: k3clientsocketbase.cpp:66
KNetwork::KBufferedSocket::close
virtual void close()
Closes the socket for new data, but allow data that had been buffered for output with writeData() to ...
Definition: k3bufferedsocket.cpp:85
QSocketNotifier
k3socketbuffer_p.h
KNetwork::KBufferedSocket::slotReadActivity
virtual void slotReadActivity()
Slot called when there's read activity.
Definition: k3bufferedsocket.cpp:296
KNetwork::KBufferedSocket::waitForMore
virtual qint64 waitForMore(int msecs, bool *timeout=0L)
Make use of buffers.
Definition: k3bufferedsocket.cpp:107
KNetwork::KBufferedSocket::setSocketDevice
virtual void setSocketDevice(KSocketDevice *device)
Be sure to catch new devices.
Definition: k3bufferedsocket.cpp:69
KNetwork::KBufferedSocket::readData
virtual qint64 readData(char *data, qint64 maxlen, KSocketAddress *from)
Reads data from a socket.
Definition: k3bufferedsocket.cpp:119
KNetwork::KBufferedSocket::setSocketOptions
virtual bool setSocketOptions(int opts)
Buffered sockets can only operate in non-blocking mode.
Definition: k3bufferedsocket.cpp:76
timeout
int timeout
Definition: kkernel_mac.cpp:46
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: k3socketbase.cpp:441
KNetwork::KSocketDevice::writeNotifier
QSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
Definition: k3socketdevice.cpp:665
KNetwork::KBufferedSocket::canReadLine
virtual bool canReadLine() const
Returns true if a line can be read with readLine()
Definition: k3bufferedsocket.cpp:273
KNetwork::KClientSocketBase::slotReadActivity
virtual void slotReadActivity()
This slot is connected to the read notifier's signal meaning the socket can read more data...
Definition: k3clientsocketbase.cpp:394
KNetwork::KSocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: k3socketbase.cpp:197
QMutex::unlock
void unlock()
KNetwork::KSocketAddress
A generic socket address.
Definition: k3socketaddress.h:414
KNetwork::KBufferedSocket::bytesToWrite
virtual qint64 bytesToWrite() const
Returns the length of the output buffer.
Definition: k3bufferedsocket.cpp:258
KNetwork::KClientSocketBase::gotError
void gotError(int code)
This signal is emitted when this object finds an error.
KNetwork::KClientSocketBase::setSocketOptions
virtual bool setSocketOptions(int opts)
Sets the socket options.
Definition: k3clientsocketbase.cpp:77
KNetwork::KBufferedSocket::bytesAvailable
virtual qint64 bytesAvailable() const
Make use of the buffers.
Definition: k3bufferedsocket.cpp:99
k3bufferedsocket.h
KNetwork::KActiveSocketBase::open
virtual bool open(OpenMode mode)
Reimplemented from QIODevice.
Definition: k3socketbase.cpp:339
KNetwork::KSocketBase::NotConnected
Definition: k3socketbase.h:151
KNetwork::KClientSocketBase::writeData
virtual qint64 writeData(const char *data, qint64 len, const KSocketAddress *to)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: k3clientsocketbase.cpp:340
KNetwork::KSocketBase::WouldBlock
Definition: k3socketbase.h:154
KNetwork::KSocketDevice::readNotifier
QSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
Definition: k3socketdevice.cpp:647
KNetwork::KSocketBase::RemotelyDisconnected
Definition: k3socketbase.h:162
KNetwork::KBufferedSocket::closeNow
virtual void closeNow()
Closes the socket and discards any output data that had been buffered with writeData() but that had n...
Definition: k3bufferedsocket.cpp:266
KNetwork::KClientSocketBase::readData
virtual qint64 readData(char *data, qint64 maxlen, KSocketAddress *from)
Reads data from a socket.
Definition: k3clientsocketbase.cpp:316
KNetwork::KClientSocketBase::copyError
void copyError()
Convenience function to set this object's error code to match that of the socket device.
Definition: k3clientsocketbase.cpp:453
KNetwork::KClientSocketBase::Closing
Definition: k3clientsocketbase.h:80
QObject
KNetwork::KClientSocketBase::peerAddress
virtual KSocketAddress peerAddress() const
Returns the peer socket address.
Definition: k3clientsocketbase.cpp:359
KNetwork::KSocketBase::mutex
QMutex * mutex() const
Returns the internal mutex for this class.
Definition: k3socketbase.cpp:320
KNetwork::KBufferedSocket::waitForConnect
void waitForConnect()
Blocks until the connection is either established, or completely failed.
Definition: k3bufferedsocket.cpp:286
KNetwork::KClientSocketBase::SocketState
SocketState
Socket states.
Definition: k3clientsocketbase.h:72
KNetwork::KBufferedSocket::peekData
virtual qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from)
Peeks data from the socket.
Definition: k3bufferedsocket.cpp:135
QString
KNetwork::KBufferedSocket::slotWriteActivity
virtual void slotWriteActivity()
Slot called when there's write activity.
Definition: k3bufferedsocket.cpp:343
QIODevice::bytesWritten
void bytesWritten(qint64 bytes)
KNetwork::KClientSocketBase::setState
void setState(SocketState state)
Sets the socket state to state.
Definition: k3clientsocketbase.cpp:71
KNetwork::KClientSocketBase::Connected
Definition: k3clientsocketbase.h:83
KNetwork::KBufferedSocket::KBufferedSocket
KBufferedSocket(const QString &node=QString(), const QString &service=QString(), QObject *parent=0L)
Default constructor.
Definition: k3bufferedsocket.cpp:52
KNetwork::KClientSocketBase::stateChanged
void stateChanged(int newstate)
This signal is emitted whenever the socket state changes.
KNetwork::KActiveSocketBase::setError
void setError(SocketError error)
Sets the socket's error code.
Definition: k3socketbase.cpp:435
KNetwork::KClientSocketBase::bytesAvailable
virtual qint64 bytesAvailable() const
Returns the number of bytes available on this socket.
Definition: k3clientsocketbase.cpp:296
QIODevice::openMode
OpenMode openMode() const
KNetwork::KClientSocketBase::peekData
virtual qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from)
Peeks data from the socket.
Definition: k3clientsocketbase.cpp:328
QMutex::lock
void lock()
KNetwork::KActiveSocketBase::setSocketDevice
virtual void setSocketDevice(KSocketDevice *device)
Definition: k3socketbase.cpp:347
KNetwork::KBufferedSocket::setOutputBuffering
void setOutputBuffering(bool enable)
Sets the use of output buffering.
Definition: k3bufferedsocket.cpp:244
QSocketNotifier::setEnabled
void setEnabled(bool enable)
KNetwork::KClientSocketBase::enableRead
virtual void enableRead(bool enable)
Enables the emission of the readyRead signal.
Definition: k3clientsocketbase.cpp:369
output
void output(QList< Action > actions, QHash< QString, QString > domain)
Definition: fake/kauth-policy-gen-polkit.cpp:41
KNetwork::KClientSocketBase::close
virtual void close()
Closes the socket.
Definition: k3clientsocketbase.cpp:270
KNetwork::KClientSocketBase::Connecting
Definition: k3clientsocketbase.h:78
QMutexLocker
KNetwork::KClientSocketBase::stateChanging
virtual void stateChanging(SocketState newState)
This function is called by setState() whenever the state changes.
Definition: k3clientsocketbase.cpp:429
KNetwork::KBufferedSocket::setInputBuffering
void setInputBuffering(bool enable)
Sets the use of input buffering.
Definition: k3bufferedsocket.cpp:230
KNetwork::KBufferedSocket::enableRead
virtual void enableRead(bool enable)
Catch changes.
Definition: k3bufferedsocket.cpp:183
KNetwork::KClientSocketBase::emitsReadyRead
bool emitsReadyRead() const
Returns true if the readyRead signal is set to be emitted.
Definition: k3clientsocketbase.cpp:364
KNetwork::KSocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: k3socketbase.cpp:97
KNetwork::KSocketDevice
Low-level socket functionality.
Definition: k3socketdevice.h:51
KNetwork::KClientSocketBase::waitForMore
virtual qint64 waitForMore(int msecs, bool *timeout=0L)
Waits for more data.
Definition: k3clientsocketbase.cpp:304
KNetwork::KBufferedSocket::~KBufferedSocket
virtual ~KBufferedSocket()
Destructor.
Definition: k3bufferedsocket.cpp:61
KNetwork::KSocketBase::Blocking
Definition: k3socketbase.h:110
KNetwork::KBufferedSocket::enableWrite
virtual void enableWrite(bool enable)
Catch changes.
Definition: k3bufferedsocket.cpp:200
KNetwork::KBufferedSocket::stateChanging
virtual void stateChanging(SocketState newState)
Catch connection to clear the buffers.
Definition: k3bufferedsocket.cpp:212
KNetwork::Internal::KSocketBuffer
generic socket buffering code
Definition: k3socketbuffer_p.h:48
KNetwork::KClientSocketBase::emitsReadyWrite
bool emitsReadyWrite() const
Returns true if the readyWrite signal is set to be emitted.
Definition: k3clientsocketbase.cpp:379
KNetwork::KSocketBase::socketOptions
virtual int socketOptions() const
Retrieves the socket options that have been set.
Definition: k3socketbase.cpp:92
QIODevice::readyRead
void readyRead()
KNetwork::KClientSocketBase::enableWrite
virtual void enableWrite(bool enable)
Enables the emission of the readyWrite signal.
Definition: k3clientsocketbase.cpp:384
KNetwork::KBufferedSocket::readLineData
virtual qint64 readLineData(char *data, qint64 maxSize)
Improve the readLine performance.
Definition: k3bufferedsocket.cpp:281
KNetwork::KClientSocketBase::slotWriteActivity
virtual void slotWriteActivity()
This slot is connected to the write notifier's signal meaning the socket can write more data...
Definition: k3clientsocketbase.cpp:400
QTimer::singleShot
singleShot
KNetwork::KBufferedSocket::writeData
virtual qint64 writeData(const char *data, qint64 len, const KSocketAddress *to)
Writes data to the socket.
Definition: k3bufferedsocket.cpp:151
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal