KDELibs4Support

k3socketbase.cpp
1 /* -*- C++ -*-
2  * Copyright (C) 2003-2005 Thiago Macieira <[email protected]>
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 "k3socketbase.h"
26 
27 #include <config-network.h>
28 #include <QMutex>
29 #include <klocalizedstring.h>
30 
31 #include "k3socketdevice.h"
32 
33 #ifdef Q_OS_WIN
34 #include <winsock2.h>
35 
36 void KNetwork_initSocket()
37 {
38  static bool hasStarted = false;
39  if (!hasStarted) {
40  WSADATA wsaData;
41  WORD wVersionRequested = MAKEWORD(2, 2);
42  WSAStartup(wVersionRequested, &wsaData);
43  hasStarted = true;
44  }
45 }
46 #endif
47 
48 using namespace KNetwork;
49 
50 class KNetwork::KSocketBasePrivate
51 {
52 public:
53  int socketOptions;
54  int socketError;
55  int capabilities;
56 
57  mutable KSocketDevice *device;
58 
59  QMutex mutex;
60 
61  KSocketBasePrivate()
62  : mutex(QMutex::Recursive) // create recursive
63  { }
64 };
65 
67  : d(new KSocketBasePrivate)
68 {
69  d->socketOptions = Blocking;
70  d->socketError = 0;
71  d->device = nullptr;
72  d->capabilities = 0;
73 #ifdef Q_OS_WIN
74  KNetwork_initSocket();
75 #endif
76 }
77 
79 {
80  delete d->device;
81  delete d;
82 }
83 
85 {
86  d->socketOptions = opts;
87  return true;
88 }
89 
91 {
92  return d->socketOptions;
93 }
94 
95 bool KSocketBase::setBlocking(bool enable)
96 {
97  return setSocketOptions((socketOptions() & ~Blocking) | (enable ? Blocking : 0));
98 }
99 
101 {
102  return socketOptions() & Blocking;
103 }
104 
106 {
107  return setSocketOptions((socketOptions() & ~AddressReuseable) | (enable ? AddressReuseable : 0));
108 }
109 
111 {
112  return socketOptions() & AddressReuseable;
113 }
114 
115 bool KSocketBase::setIPv6Only(bool enable)
116 {
117  return setSocketOptions((socketOptions() & ~IPv6Only) | (enable ? IPv6Only : 0));
118 }
119 
121 {
122  return socketOptions() & IPv6Only;
123 }
124 
125 bool KSocketBase::setBroadcast(bool enable)
126 {
127  return setSocketOptions((socketOptions() & ~Broadcast) | (enable ? Broadcast : 0));
128 }
129 
131 {
132  return socketOptions() & Broadcast;
133 }
134 
135 bool KSocketBase::setNoDelay(bool enable)
136 {
137  return setSocketOptions((socketOptions() & ~NoDelay) | (enable ? NoDelay : 0));
138 }
139 
141 {
142  return socketOptions() & NoDelay;
143 }
144 
146 {
147  if (d->device) {
148  return d->device;
149  }
150 
151  // it doesn't exist, so create it
152  QMutexLocker locker(mutex());
153  if (d->device) {
154  return d->device;
155  }
156 
157  KSocketBase *that = const_cast<KSocketBase *>(this);
158  KSocketDevice *dev = nullptr;
159  if (d->capabilities) {
160  dev = KSocketDevice::createDefault(that, d->capabilities);
161  }
162  if (!dev) {
163  dev = KSocketDevice::createDefault(that);
164  }
165  that->setSocketDevice(dev);
166  return d->device;
167 }
168 
170 {
171  QMutexLocker locker(mutex());
172  if (d->device == nullptr) {
173  d->device = device;
174  }
175 }
176 
178 {
179  d->capabilities |= add;
180  d->capabilities &= ~remove;
181  return d->capabilities;
182 }
183 
185 {
186  return d->device != nullptr;
187 }
188 
190 {
191  d->socketError = error;
192 }
193 
195 {
196  d->socketError = NoError;
197 }
198 
200 {
201  return static_cast<KSocketBase::SocketError>(d->socketError);
202 }
203 
205 {
206  return errorString(error());
207 }
208 
209 // static
211 {
212  QString reason;
213  switch (code) {
214  case NoError:
215  reason = i18nc("Socket error code NoError", "no error");
216  break;
217 
218  case LookupFailure:
219  reason = i18nc("Socket error code LookupFailure",
220  "name lookup has failed");
221  break;
222 
223  case AddressInUse:
224  reason = i18nc("Socket error code AddressInUse",
225  "address already in use");
226  break;
227 
228  case AlreadyBound:
229  reason = i18nc("Socket error code AlreadyBound",
230  "socket is already bound");
231  break;
232 
233  case AlreadyCreated:
234  reason = i18nc("Socket error code AlreadyCreated",
235  "socket is already created");
236  break;
237 
238  case NotBound:
239  reason = i18nc("Socket error code NotBound",
240  "socket is not bound");
241  break;
242 
243  case NotCreated:
244  reason = i18nc("Socket error code NotCreated",
245  "socket has not been created");
246  break;
247 
248  case WouldBlock:
249  reason = i18nc("Socket error code WouldBlock",
250  "operation would block");
251  break;
252 
253  case ConnectionRefused:
254  reason = i18nc("Socket error code ConnectionRefused",
255  "connection actively refused");
256  break;
257 
258  case ConnectionTimedOut:
259  reason = i18nc("Socket error code ConnectionTimedOut",
260  "connection timed out");
261  break;
262 
263  case InProgress:
264  reason = i18nc("Socket error code InProgress",
265  "operation is already in progress");
266  break;
267 
268  case NetFailure:
269  reason = i18nc("Socket error code NetFailure",
270  "network failure occurred");
271  break;
272 
273  case NotSupported:
274  reason = i18nc("Socket error code NotSupported",
275  "operation is not supported");
276  break;
277 
278  case Timeout:
279  reason = i18nc("Socket error code Timeout",
280  "timed operation timed out");
281  break;
282 
283  case UnknownError:
284  reason = i18nc("Socket error code UnknownError",
285  "an unknown/unexpected error has happened");
286  break;
287 
288  case RemotelyDisconnected:
289  reason = i18nc("Socket error code RemotelyDisconnected",
290  "remote host closed connection");
291  break;
292 
293  default:
294  reason.clear();
295  break;
296  }
297 
298  return reason;
299 }
300 
301 // static
303 {
304  switch (code) {
305  case WouldBlock:
306  case InProgress:
307  case NoError:
308  case RemotelyDisconnected:
309  return false;
310  }
311 
312  return true;
313 }
314 
315 void KSocketBase::unsetSocketDevice()
316 {
317  d->device = nullptr;
318 }
319 
321 {
322  return &d->mutex;
323 }
324 
326  : QIODevice(parent)
327 {
328 }
329 
331 {
332 }
333 
335 {
336  return QIODevice::errorString();
337 }
338 
340 {
341  QIODevice::open(mode);
342  if (mode != QIODevice::NotOpen) {
343  QIODevice::seek(0); // clear unget buffers
344  }
345  return true;
346 }
347 
349 {
352 }
353 
355 {
356  return true;
357 }
358 
360 {
361  return 0;
362 }
363 
365 {
366  return 0;
367 }
368 
370 {
371  return false;
372 }
373 
375 {
376  return true;
377 }
378 
379 qint64 KActiveSocketBase::read(char *data, qint64 maxlen)
380 {
381  return QIODevice::read(data, maxlen);
382 }
383 
385 {
386  return QIODevice::read(len);
387 }
388 
389 qint64 KActiveSocketBase::read(char *data, qint64 len, KSocketAddress &from)
390 {
391  // FIXME TODO: implement unget buffers
392  return readData(data, len, &from);
393 }
394 
395 qint64 KActiveSocketBase::peek(char *data, qint64 len)
396 {
397  return peekData(data, len, nullptr);
398 }
399 
400 qint64 KActiveSocketBase::peek(char *data, qint64 len, KSocketAddress &from)
401 {
402  return peekData(data, len, &from);
403 }
404 
405 qint64 KActiveSocketBase::write(const char *data, qint64 len)
406 {
407  return QIODevice::write(data, len);
408 }
409 
411 {
412  return QIODevice::write(data);
413 }
414 
415 qint64 KActiveSocketBase::write(const char *data, qint64 len,
416  const KSocketAddress &to)
417 {
418  return writeData(data, len, &to);
419 }
420 
422 {
423  return;
424 }
425 
426 qint64 KActiveSocketBase::readData(char *data, qint64 len)
427 {
428  return readData(data, len, nullptr);
429 }
430 
431 qint64 KActiveSocketBase::writeData(const char *data, qint64 len)
432 {
433  return writeData(data, len, nullptr);
434 }
435 
437 {
438  KSocketBase::setError(error);
440 }
441 
443 {
444  KSocketBase::setError(NoError);
446 }
447 
449 {
450 }
451 
453 {
454 }
455 
KActiveSocketBase(QObject *parent)
Constructor.
bool blocking() const
Retrieves this socket&#39;s blocking mode.
static bool isFatalError(int code)
Returns true if the given error code is a fatal one, false otherwise.
KSocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
bool addressReuseable() const
Retrieves this socket&#39;s address reuseability flag.
qint64 readData(char *data, qint64 len) override
Reads data from the socket.
virtual bool setAddressReuseable(bool enable)
Sets this socket&#39;s address reuseable flag.
virtual bool seek(qint64 pos)
QString errorString() const const
void ungetChar(char)
This call is not supported on sockets.
bool atEnd() const override
This call is not supported on sockets.
bool broadcast() const
Retrieves this socket&#39;s Broadcast flag.
void resetError()
Resets the socket error code and the I/O Device&#39;s status.
qint64 pos() const override
This call is not supported on sockets.
typedef OpenMode
SocketError error() const
Retrieves the socket error code.
A generic socket address.
qint64 size() const override
This call is not supported on sockets.
virtual ~KSocketBase()
Destructor.
qint64 peek(char *data, qint64 maxlen)
Peeks the data in the socket and the source address.
virtual bool open(QIODevice::OpenMode mode)
virtual ~KPassiveSocketBase()
Destructor.
int setRequestedCapabilities(int add, int remove=0)
Sets the internally requested capabilities for a socket device.
bool isIPv6Only() const
Retrieves this socket&#39;s IPv6 Only flag.
void clear()
qint64 read(char *data, qint64 maxlen)
Reads data from the socket.
KSocketBase()
Default constructor.
A namespace to store all networking-related (socket) classes.
virtual bool setBroadcast(bool enable)
Sets this socket Broadcast flag.
virtual bool setIPv6Only(bool enable)
Sets this socket&#39;s IPv6 Only flag.
void setSocketDevice(KSocketDevice *device) override
QString i18nc(const char *context, const char *text, const TYPE &arg...)
SocketError
Possible socket error codes.
Definition: k3socketbase.h:143
QMutex * mutex() const
Returns the internal mutex for this class.
void setError(SocketError error)
Sets the socket&#39;s error code.
qint64 read(char *data, qint64 maxSize)
bool noDelay() const
Retrieves this socket&#39;s NoDelay flag.
bool seek(qint64) override
This call is not supported on sockets.
virtual bool setSocketOptions(int opts)
Set the given socket options.
void setError(SocketError error)
Sets the socket&#39;s error code.
QIODevice::OpenMode openMode() const const
qint64 write(const char *data, qint64 len)
Writes the given data to the socket.
qint64 writeData(const char *data, qint64 len) override
Writes the given data to the socket.
virtual qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from)=0
Peeks the data in the socket and the source address.
virtual ~KActiveSocketBase()
Destructor.
void resetError()
Resets the socket error code and the I/O Device&#39;s status.
virtual void setSocketDevice(KSocketDevice *device)
Sets the socket implementation to be used on this socket.
KDEGAMES_EXPORT Capabilities capabilities()
QString errorString() const
Unshadow errorString from QIODevice.
qint64 write(const char *data, qint64 maxSize)
bool hasDevice() const
Returns true if the socket device has been initialised in this object, either by calling socketDevice...
virtual bool setBlocking(bool enable)
Sets this socket&#39;s blocking mode.
void setErrorString(const QString &str)
Low-level socket functionality.
QString errorString() const
Returns the error string corresponding to this error condition.
virtual bool setNoDelay(bool enable)
Sets this socket&#39;s NoDelay flag.
virtual int socketOptions() const
Retrieves the socket options that have been set.
Basic socket functionality.
Definition: k3socketbase.h:86
bool isSequential() const override
Sockets are sequential.
static KSocketDevice * createDefault(KSocketBase *parent)
Creates a new default KSocketDevice object given the parent object.
bool open(OpenMode mode) override
Reimplemented from QIODevice.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jul 10 2020 22:56:46 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.