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#include "qnativesocketengine_p.h"
43
44#include "qmutex.h"
45#include "qnetworkproxy.h"
46
47QT_BEGIN_NAMESPACE
48
49class QSocketEngineHandlerList : public QList<QSocketEngineHandler*>
50{
51public:
52 QMutex mutex;
53};
54
55Q_GLOBAL_STATIC(QSocketEngineHandlerList, socketHandlers)
56
57QSocketEngineHandler::QSocketEngineHandler()
58{
59 if (!socketHandlers())
60 return;
61 QMutexLocker locker(&socketHandlers()->mutex);
62 socketHandlers()->prepend(this);
63}
64
65QSocketEngineHandler::~QSocketEngineHandler()
66{
67 if (!socketHandlers())
68 return;
69 QMutexLocker locker(&socketHandlers()->mutex);
70 socketHandlers()->removeAll(this);
71}
72
73QAbstractSocketEnginePrivate::QAbstractSocketEnginePrivate()
74 : socketError(QAbstractSocket::UnknownSocketError)
75 , hasSetSocketError(false)
76 , socketErrorString(QLatin1String(QT_TRANSLATE_NOOP(QSocketLayer, "Unknown error")))
77 , socketState(QAbstractSocket::UnconnectedState)
78 , socketType(QAbstractSocket::UnknownSocketType)
79 , socketProtocol(QAbstractSocket::UnknownNetworkLayerProtocol)
80 , localPort(0)
81 , peerPort(0)
82 , inboundStreamCount(0)
83 , outboundStreamCount(0)
84 , receiver(nullptr)
85{
86}
87
88QAbstractSocketEngine::QAbstractSocketEngine(QObject *parent)
89 : QObject(*new QAbstractSocketEnginePrivate(), parent)
90{
91}
92
93QAbstractSocketEngine::QAbstractSocketEngine(QAbstractSocketEnginePrivate &dd, QObject* parent)
94 : QObject(dd, parent)
95{
96}
97
98QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &proxy, QObject *parent)
99{
100#ifndef QT_NO_NETWORKPROXY
101 // proxy type must have been resolved by now
102 if (proxy.type() == QNetworkProxy::DefaultProxy)
103 return nullptr;
104#endif
105
106 QMutexLocker locker(&socketHandlers()->mutex);
107 for (int i = 0; i < socketHandlers()->size(); i++) {
108 if (QAbstractSocketEngine *ret = socketHandlers()->at(i)->createSocketEngine(socketType, proxy, parent))
109 return ret;
110 }
111
112#ifndef QT_NO_NETWORKPROXY
113 // only NoProxy can have reached here
114 if (proxy.type() != QNetworkProxy::NoProxy)
115 return nullptr;
116#endif
117
118 return new QNativeSocketEngine(parent);
119}
120
121QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(qintptr socketDescripter, QObject *parent)
122{
123 QMutexLocker locker(&socketHandlers()->mutex);
124 for (int i = 0; i < socketHandlers()->size(); i++) {
125 if (QAbstractSocketEngine *ret = socketHandlers()->at(i)->createSocketEngine(socketDescripter, parent))
126 return ret;
127 }
128 return new QNativeSocketEngine(parent);
129}
130
131QAbstractSocket::SocketError QAbstractSocketEngine::error() const
132{
133 return d_func()->socketError;
134}
135
136QString QAbstractSocketEngine::errorString() const
137{
138 return d_func()->socketErrorString;
139}
140
141void QAbstractSocketEngine::setError(QAbstractSocket::SocketError error, const QString &errorString) const
142{
143 Q_D(const QAbstractSocketEngine);
144 d->socketError = error;
145 d->socketErrorString = errorString;
146}
147
148void QAbstractSocketEngine::setReceiver(QAbstractSocketEngineReceiver *receiver)
149{
150 d_func()->receiver = receiver;
151}
152
153void QAbstractSocketEngine::readNotification()
154{
155 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
156 receiver->readNotification();
157}
158
159void QAbstractSocketEngine::writeNotification()
160{
161 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
162 receiver->writeNotification();
163}
164
165void QAbstractSocketEngine::exceptionNotification()
166{
167 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
168 receiver->exceptionNotification();
169}
170
171void QAbstractSocketEngine::closeNotification()
172{
173 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
174 receiver->closeNotification();
175}
176
177void QAbstractSocketEngine::connectionNotification()
178{
179 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
180 receiver->connectionNotification();
181}
182
183#ifndef QT_NO_NETWORKPROXY
184void QAbstractSocketEngine::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
185{
186 if (QAbstractSocketEngineReceiver *receiver = d_func()->receiver)
187 receiver->proxyAuthenticationRequired(proxy, authenticator);
188}
189#endif
190
191
192QAbstractSocket::SocketState QAbstractSocketEngine::state() const
193{
194 return d_func()->socketState;
195}
196
197void QAbstractSocketEngine::setState(QAbstractSocket::SocketState state)
198{
199 d_func()->socketState = state;
200}
201
202QAbstractSocket::SocketType QAbstractSocketEngine::socketType() const
203{
204 return d_func()->socketType;
205}
206
207void QAbstractSocketEngine::setSocketType(QAbstractSocket::SocketType socketType)
208{
209 d_func()->socketType = socketType;
210}
211
212QAbstractSocket::NetworkLayerProtocol QAbstractSocketEngine::protocol() const
213{
214 return d_func()->socketProtocol;
215}
216
217void QAbstractSocketEngine::setProtocol(QAbstractSocket::NetworkLayerProtocol protocol)
218{
219 d_func()->socketProtocol = protocol;
220}
221
222QHostAddress QAbstractSocketEngine::localAddress() const
223{
224 return d_func()->localAddress;
225}
226
227void QAbstractSocketEngine::setLocalAddress(const QHostAddress &address)
228{
229 d_func()->localAddress = address;
230}
231
232quint16 QAbstractSocketEngine::localPort() const
233{
234 return d_func()->localPort;
235}
236
237void QAbstractSocketEngine::setLocalPort(quint16 port)
238{
239 d_func()->localPort = port;
240}
241
242QHostAddress QAbstractSocketEngine::peerAddress() const
243{
244 return d_func()->peerAddress;
245}
246
247void QAbstractSocketEngine::setPeerAddress(const QHostAddress &address)
248{
249 d_func()->peerAddress = address;
250}
251
252quint16 QAbstractSocketEngine::peerPort() const
253{
254 return d_func()->peerPort;
255}
256
257void QAbstractSocketEngine::setPeerPort(quint16 port)
258{
259 d_func()->peerPort = port;
260}
261
262int QAbstractSocketEngine::inboundStreamCount() const
263{
264 return d_func()->inboundStreamCount;
265}
266
267int QAbstractSocketEngine::outboundStreamCount() const
268{
269 return d_func()->outboundStreamCount;
270}
271
272QT_END_NAMESPACE
273
274#include "moc_qabstractsocketengine_p.cpp"
275