1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #include "qabstractsocketengine_p.h"
41
42 #ifndef Q_OS_WINRT
43 #include "qnativesocketengine_p.h"
44 #else
45 #include "qnativesocketengine_winrt_p.h"
46 #endif
47
48 #include "qmutex.h"
49 #include "qnetworkproxy.h"
50
51 QT_BEGIN_NAMESPACE
52
53 class QSocketEngineHandlerList : public QList<QSocketEngineHandler*>
54 {
55 public:
56 QMutex mutex;
57 };
58
Q_GLOBAL_STATIC(QSocketEngineHandlerList,socketHandlers)59 Q_GLOBAL_STATIC(QSocketEngineHandlerList, socketHandlers)
60
61 QSocketEngineHandler::QSocketEngineHandler()
62 {
63 if (!socketHandlers())
64 return;
65 QMutexLocker locker(&socketHandlers()->mutex);
66 socketHandlers()->prepend(this);
67 }
68
~QSocketEngineHandler()69 QSocketEngineHandler::~QSocketEngineHandler()
70 {
71 if (!socketHandlers())
72 return;
73 QMutexLocker locker(&socketHandlers()->mutex);
74 socketHandlers()->removeAll(this);
75 }
76
QAbstractSocketEnginePrivate()77 QAbstractSocketEnginePrivate::QAbstractSocketEnginePrivate()
78 : socketError(QAbstractSocket::UnknownSocketError)
79 , hasSetSocketError(false)
80 , socketErrorString(QLatin1String(QT_TRANSLATE_NOOP(QSocketLayer, "Unknown error")))
81 , socketState(QAbstractSocket::UnconnectedState)
82 , socketType(QAbstractSocket::UnknownSocketType)
83 , socketProtocol(QAbstractSocket::UnknownNetworkLayerProtocol)
84 , localPort(0)
85 , peerPort(0)
86 , inboundStreamCount(0)
87 , outboundStreamCount(0)
88 , receiver(nullptr)
89 {
90 }
91
QAbstractSocketEngine(QObject * parent)92 QAbstractSocketEngine::QAbstractSocketEngine(QObject *parent)
93 : QObject(*new QAbstractSocketEnginePrivate(), parent)
94 {
95 }
96
QAbstractSocketEngine(QAbstractSocketEnginePrivate & dd,QObject * parent)97 QAbstractSocketEngine::QAbstractSocketEngine(QAbstractSocketEnginePrivate &dd, QObject* parent)
98 : QObject(dd, parent)
99 {
100 }
101
createSocketEngine(QAbstractSocket::SocketType socketType,const QNetworkProxy & proxy,QObject * parent)102 QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &proxy, QObject *parent)
103 {
104 #ifndef QT_NO_NETWORKPROXY
105 // proxy type must have been resolved by now
106 if (proxy.type() == QNetworkProxy::DefaultProxy)
107 return nullptr;
108 #endif
109
110 QMutexLocker locker(&socketHandlers()->mutex);
111 for (int i = 0; i < socketHandlers()->size(); i++) {
112 if (QAbstractSocketEngine *ret = socketHandlers()->at(i)->createSocketEngine(socketType, proxy, parent))
113 return ret;
114 }
115
116 #ifndef QT_NO_NETWORKPROXY
117 // only NoProxy can have reached here
118 if (proxy.type() != QNetworkProxy::NoProxy)
119 return nullptr;
120 #endif
121
122 return new QNativeSocketEngine(parent);
123 }
124
createSocketEngine(qintptr socketDescripter,QObject * parent)125 QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(qintptr socketDescripter, QObject *parent)
126 {
127 QMutexLocker locker(&socketHandlers()->mutex);
128 for (int i = 0; i < socketHandlers()->size(); i++) {
129 if (QAbstractSocketEngine *ret = socketHandlers()->at(i)->createSocketEngine(socketDescripter, parent))
130 return ret;
131 }
132 return new QNativeSocketEngine(parent);
133 }
134
error() const135 QAbstractSocket::SocketError QAbstractSocketEngine::error() const
136 {
137 return d_func()->socketError;
138 }
139
errorString() const140 QString QAbstractSocketEngine::errorString() const
141 {
142 return d_func()->socketErrorString;
143 }
144
setError(QAbstractSocket::SocketError error,const QString & errorString) const145 void QAbstractSocketEngine::setError(QAbstractSocket::SocketError error, const QString &errorString) const
146 {
147 Q_D(const QAbstractSocketEngine);
148 d->socketError = error;
149 d->socketErrorString = errorString;
150 }
151
setReceiver(QAbstractSocketEngineReceiver * receiver)152 void QAbstractSocketEngine::setReceiver(QAbstractSocketEngineReceiver *receiver)
153 {
154 d_func()->receiver = receiver;
155 }
156
readNotification()157 void QAbstractSocketEngine::readNotification()
158 {
159 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
160 receiver->readNotification();
161 }
162
writeNotification()163 void QAbstractSocketEngine::writeNotification()
164 {
165 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
166 receiver->writeNotification();
167 }
168
exceptionNotification()169 void QAbstractSocketEngine::exceptionNotification()
170 {
171 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
172 receiver->exceptionNotification();
173 }
174
closeNotification()175 void QAbstractSocketEngine::closeNotification()
176 {
177 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
178 receiver->closeNotification();
179 }
180
connectionNotification()181 void QAbstractSocketEngine::connectionNotification()
182 {
183 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
184 receiver->connectionNotification();
185 }
186
187 #ifndef QT_NO_NETWORKPROXY
proxyAuthenticationRequired(const QNetworkProxy & proxy,QAuthenticator * authenticator)188 void QAbstractSocketEngine::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
189 {
190 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
191 receiver->proxyAuthenticationRequired(proxy, authenticator);
192 }
193 #endif
194
195
state() const196 QAbstractSocket::SocketState QAbstractSocketEngine::state() const
197 {
198 return d_func()->socketState;
199 }
200
setState(QAbstractSocket::SocketState state)201 void QAbstractSocketEngine::setState(QAbstractSocket::SocketState state)
202 {
203 d_func()->socketState = state;
204 }
205
socketType() const206 QAbstractSocket::SocketType QAbstractSocketEngine::socketType() const
207 {
208 return d_func()->socketType;
209 }
210
setSocketType(QAbstractSocket::SocketType socketType)211 void QAbstractSocketEngine::setSocketType(QAbstractSocket::SocketType socketType)
212 {
213 d_func()->socketType = socketType;
214 }
215
protocol() const216 QAbstractSocket::NetworkLayerProtocol QAbstractSocketEngine::protocol() const
217 {
218 return d_func()->socketProtocol;
219 }
220
setProtocol(QAbstractSocket::NetworkLayerProtocol protocol)221 void QAbstractSocketEngine::setProtocol(QAbstractSocket::NetworkLayerProtocol protocol)
222 {
223 d_func()->socketProtocol = protocol;
224 }
225
localAddress() const226 QHostAddress QAbstractSocketEngine::localAddress() const
227 {
228 return d_func()->localAddress;
229 }
230
setLocalAddress(const QHostAddress & address)231 void QAbstractSocketEngine::setLocalAddress(const QHostAddress &address)
232 {
233 d_func()->localAddress = address;
234 }
235
localPort() const236 quint16 QAbstractSocketEngine::localPort() const
237 {
238 return d_func()->localPort;
239 }
240
setLocalPort(quint16 port)241 void QAbstractSocketEngine::setLocalPort(quint16 port)
242 {
243 d_func()->localPort = port;
244 }
245
peerAddress() const246 QHostAddress QAbstractSocketEngine::peerAddress() const
247 {
248 return d_func()->peerAddress;
249 }
250
setPeerAddress(const QHostAddress & address)251 void QAbstractSocketEngine::setPeerAddress(const QHostAddress &address)
252 {
253 d_func()->peerAddress = address;
254 }
255
peerPort() const256 quint16 QAbstractSocketEngine::peerPort() const
257 {
258 return d_func()->peerPort;
259 }
260
setPeerPort(quint16 port)261 void QAbstractSocketEngine::setPeerPort(quint16 port)
262 {
263 d_func()->peerPort = port;
264 }
265
inboundStreamCount() const266 int QAbstractSocketEngine::inboundStreamCount() const
267 {
268 return d_func()->inboundStreamCount;
269 }
270
outboundStreamCount() const271 int QAbstractSocketEngine::outboundStreamCount() const
272 {
273 return d_func()->outboundStreamCount;
274 }
275
276 QT_END_NAMESPACE
277