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

KDECore

  • 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
37using namespace KNetwork;
38using namespace KNetwork::Internal;
39
40class KNetwork::KBufferedSocketPrivate
41{
42public:
43 mutable KSocketBuffer *input, *output;
44
45 KBufferedSocketPrivate()
46 {
47 input = 0L;
48 output = 0L;
49 }
50};
51
52KBufferedSocket::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
61KBufferedSocket::~KBufferedSocket()
62{
63 closeNow();
64 delete d->input;
65 delete d->output;
66 delete d;
67}
68
69void KBufferedSocket::setSocketDevice(KSocketDevice* device)
70{
71 KStreamSocket::setSocketDevice(device);
72 device->setBlocking(false);
73 KActiveSocketBase::open(openMode() & ~Unbuffered);
74}
75
76bool KBufferedSocket::setSocketOptions(int opts)
77{
78 if (opts == Blocking)
79 return false;
80
81 opts &= ~Blocking;
82 return KStreamSocket::setSocketOptions(opts);
83}
84
85void 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
99qint64 KBufferedSocket::bytesAvailable() const
100{
101 if (!d->input)
102 return KStreamSocket::bytesAvailable();
103
104 return d->input->length();
105}
106
107qint64 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
119qint64 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
135qint64 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
151qint64 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
183void 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
200void 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
212void 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
230void 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
244void 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
258qint64 KBufferedSocket::bytesToWrite() const
259{
260 if (!d->output)
261 return 0;
262
263 return d->output->length();
264}
265
266void KBufferedSocket::closeNow()
267{
268 KStreamSocket::close();
269 if (d->output)
270 d->output->clear();
271}
272
273bool KBufferedSocket::canReadLine() const
274{
275 if (!d->input)
276 return false;
277
278 return d->input->canReadLine();
279}
280
281qint64 KBufferedSocket::readLineData(char* data, qint64 maxSize)
282{
283 return d->input->readLine(data, maxSize);
284}
285
286void 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
296void 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
343void 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"
KNetwork::Internal::KSocketBuffer
generic socket buffering code
Definition: k3socketbuffer_p.h:49
KNetwork::KActiveSocketBase::resetError
void resetError()
Resets the socket error code and the I/O Device's status.
Definition: k3socketbase.cpp:441
KNetwork::KActiveSocketBase::open
virtual bool open(OpenMode mode)
Reimplemented from QIODevice.
Definition: k3socketbase.cpp:339
KNetwork::KActiveSocketBase::setError
void setError(SocketError error)
Sets the socket's error code.
Definition: k3socketbase.cpp:435
KNetwork::KBufferedSocket::peekData
virtual qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from)
Peeks data from the socket.
Definition: k3bufferedsocket.cpp:135
KNetwork::KBufferedSocket::setSocketDevice
virtual void setSocketDevice(KSocketDevice *device)
Be sure to catch new devices.
Definition: k3bufferedsocket.cpp:69
KNetwork::KBufferedSocket::slotReadActivity
virtual void slotReadActivity()
Slot called when there's read activity.
Definition: k3bufferedsocket.cpp:296
KNetwork::KBufferedSocket::slotWriteActivity
virtual void slotWriteActivity()
Slot called when there's write activity.
Definition: k3bufferedsocket.cpp:343
KNetwork::KBufferedSocket::stateChanging
virtual void stateChanging(SocketState newState)
Catch connection to clear the buffers.
Definition: k3bufferedsocket.cpp:212
KNetwork::KBufferedSocket::enableRead
virtual void enableRead(bool enable)
Catch changes.
Definition: k3bufferedsocket.cpp:183
KNetwork::KBufferedSocket::writeData
virtual qint64 writeData(const char *data, qint64 len, const KSocketAddress *to)
Writes data to the socket.
Definition: k3bufferedsocket.cpp:151
KNetwork::KBufferedSocket::~KBufferedSocket
virtual ~KBufferedSocket()
Destructor.
Definition: k3bufferedsocket.cpp:61
KNetwork::KBufferedSocket::setInputBuffering
void setInputBuffering(bool enable)
Sets the use of input buffering.
Definition: k3bufferedsocket.cpp:230
KNetwork::KBufferedSocket::readData
virtual qint64 readData(char *data, qint64 maxlen, KSocketAddress *from)
Reads data from a socket.
Definition: k3bufferedsocket.cpp:119
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::KBufferedSocket::bytesAvailable
virtual qint64 bytesAvailable() const
Make use of the buffers.
Definition: k3bufferedsocket.cpp:99
KNetwork::KBufferedSocket::enableWrite
virtual void enableWrite(bool enable)
Catch changes.
Definition: k3bufferedsocket.cpp:200
KNetwork::KBufferedSocket::waitForMore
virtual qint64 waitForMore(int msecs, bool *timeout=0L)
Make use of buffers.
Definition: k3bufferedsocket.cpp:107
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
KNetwork::KBufferedSocket::waitForConnect
void waitForConnect()
Blocks until the connection is either established, or completely failed.
Definition: k3bufferedsocket.cpp:286
KNetwork::KBufferedSocket::setSocketOptions
virtual bool setSocketOptions(int opts)
Buffered sockets can only operate in non-blocking mode.
Definition: k3bufferedsocket.cpp:76
KNetwork::KBufferedSocket::setOutputBuffering
void setOutputBuffering(bool enable)
Sets the use of output buffering.
Definition: k3bufferedsocket.cpp:244
KNetwork::KBufferedSocket::bytesToWrite
virtual qint64 bytesToWrite() const
Returns the length of the output buffer.
Definition: k3bufferedsocket.cpp:258
KNetwork::KBufferedSocket::canReadLine
virtual bool canReadLine() const
Returns true if a line can be read with readLine()
Definition: k3bufferedsocket.cpp:273
KNetwork::KBufferedSocket::readLineData
virtual qint64 readLineData(char *data, qint64 maxSize)
Improve the readLine performance.
Definition: k3bufferedsocket.cpp:281
KNetwork::KBufferedSocket::KBufferedSocket
KBufferedSocket(const QString &node=QString(), const QString &service=QString(), QObject *parent=0L)
Default constructor.
Definition: k3bufferedsocket.cpp:52
KNetwork::KClientSocketBase::readData
virtual qint64 readData(char *data, qint64 maxlen, KSocketAddress *from)
Reads data from a socket.
Definition: k3clientsocketbase.cpp:316
KNetwork::KClientSocketBase::waitForMore
virtual qint64 waitForMore(int msecs, bool *timeout=0L)
Waits for more data.
Definition: k3clientsocketbase.cpp:304
KNetwork::KClientSocketBase::emitsReadyWrite
bool emitsReadyWrite() const
Returns true if the readyWrite signal is set to be emitted.
Definition: k3clientsocketbase.cpp:379
KNetwork::KClientSocketBase::SocketState
SocketState
Socket states.
Definition: k3clientsocketbase.h:73
KNetwork::KClientSocketBase::Connected
@ Connected
Definition: k3clientsocketbase.h:83
KNetwork::KClientSocketBase::Connecting
@ Connecting
Definition: k3clientsocketbase.h:78
KNetwork::KClientSocketBase::Closing
@ Closing
Definition: k3clientsocketbase.h:80
KNetwork::KClientSocketBase::stateChanging
virtual void stateChanging(SocketState newState)
This function is called by setState() whenever the state changes.
Definition: k3clientsocketbase.cpp:429
KNetwork::KClientSocketBase::enableRead
virtual void enableRead(bool enable)
Enables the emission of the readyRead signal.
Definition: k3clientsocketbase.cpp:369
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::KClientSocketBase::enableWrite
virtual void enableWrite(bool enable)
Enables the emission of the readyWrite signal.
Definition: k3clientsocketbase.cpp:384
KNetwork::KClientSocketBase::setState
void setState(SocketState state)
Sets the socket state to state.
Definition: k3clientsocketbase.cpp:71
KNetwork::KClientSocketBase::close
virtual void close()
Closes the socket.
Definition: k3clientsocketbase.cpp:270
KNetwork::KClientSocketBase::emitsReadyRead
bool emitsReadyRead() const
Returns true if the readyRead signal is set to be emitted.
Definition: k3clientsocketbase.cpp:364
KNetwork::KClientSocketBase::state
SocketState state() const
Returns the current state for this socket.
Definition: k3clientsocketbase.cpp:66
KNetwork::KClientSocketBase::bytesAvailable
virtual qint64 bytesAvailable() const
Returns the number of bytes available on this socket.
Definition: k3clientsocketbase.cpp:296
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::KClientSocketBase::peerAddress
virtual KSocketAddress peerAddress() const
Returns the peer socket address.
Definition: k3clientsocketbase.cpp:359
KNetwork::KClientSocketBase::gotError
void gotError(int code)
This signal is emitted when this object finds an error.
KNetwork::KClientSocketBase::peekData
virtual qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from)
Peeks data from the socket.
Definition: k3clientsocketbase.cpp:328
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::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
KNetwork::KClientSocketBase::setSocketOptions
virtual bool setSocketOptions(int opts)
Sets the socket options.
Definition: k3clientsocketbase.cpp:77
KNetwork::KClientSocketBase::stateChanged
void stateChanged(int newstate)
This signal is emitted whenever the socket state changes.
KNetwork::KSocketAddress
A generic socket address.
Definition: k3socketaddress.h:415
KNetwork::KSocketBase::socketOptions
virtual int socketOptions() const
Retrieves the socket options that have been set.
Definition: k3socketbase.cpp:92
KNetwork::KSocketBase::setSocketDevice
virtual void setSocketDevice(KSocketDevice *device)
Sets the socket implementation to be used on this socket.
Definition: k3socketbase.cpp:168
KNetwork::KSocketBase::Blocking
@ Blocking
Definition: k3socketbase.h:110
KNetwork::KSocketBase::RemotelyDisconnected
@ RemotelyDisconnected
Definition: k3socketbase.h:162
KNetwork::KSocketBase::NotConnected
@ NotConnected
Definition: k3socketbase.h:151
KNetwork::KSocketBase::WouldBlock
@ WouldBlock
Definition: k3socketbase.h:154
KNetwork::KSocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: k3socketbase.cpp:197
KNetwork::KSocketBase::setBlocking
virtual bool setBlocking(bool enable)
Sets this socket's blocking mode.
Definition: k3socketbase.cpp:97
KNetwork::KSocketBase::socketDevice
KSocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
Definition: k3socketbase.cpp:148
KNetwork::KSocketBase::mutex
QMutex * mutex() const
Returns the internal mutex for this class.
Definition: k3socketbase.cpp:320
KNetwork::KSocketDevice
Low-level socket functionality.
Definition: k3socketdevice.h:52
KNetwork::KSocketDevice::readNotifier
QSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
Definition: k3socketdevice.cpp:647
KNetwork::KSocketDevice::writeNotifier
QSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
Definition: k3socketdevice.cpp:665
KNetwork::KStreamSocket
Simple stream socket.
Definition: k3streamsocket.h:99
KNetwork::KStreamSocket::timeout
int timeout() const
Retrieves the timeout value (in milliseconds).
Definition: k3streamsocket.cpp:75
QObject
QString
qint64
output
void output(QList< Action > actions, QHash< QString, QString > domain)
Definition: fake/kauth-policy-gen-polkit.cpp:41
k3bufferedsocket.h
k3socketaddress.h
k3socketbuffer_p.h
k3socketdevice.h
timeout
int timeout
Definition: kkernel_mac.cpp:46
KNetwork::Internal
Definition: k3resolver.h:48
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: k3bufferedsocket.h:35
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
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