diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 4d5c641247..3f226a77dc 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -142,6 +142,7 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_http access/qnetworkrequestfactory.h access/qrestaccessmanager.cpp access/qrestaccessmanager.h access/qrestaccessmanager_p.h access/qrestreply.cpp access/qrestreply.h access/qrestreply_p.h + access/qsocketabstraction_p.h socket/qhttpsocketengine.cpp socket/qhttpsocketengine_p.h ) diff --git a/src/network/access/qsocketabstraction_p.h b/src/network/access/qsocketabstraction_p.h new file mode 100644 index 0000000000..2b40b80244 --- /dev/null +++ b/src/network/access/qsocketabstraction_p.h @@ -0,0 +1,91 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QSOCKETABSTRACTION_P_H +#define QSOCKETABSTRACTION_P_H + +#include + +#include +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Network Access API. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +// Helper functions to deal with a QIODevice that is either a socket or a local +// socket. +namespace QSocketAbstraction { +template +auto visit(Fn &&fn, QIODevice *socket, Args &&...args) +{ + if (auto *s = qobject_cast(socket)) + return std::forward(fn)(s, std::forward(args)...); + if (auto *s = qobject_cast(socket)) + return std::forward(fn)(s, std::forward(args)...); + Q_UNREACHABLE(); +} + +// Since QLocalSocket's LocalSocketState's values are defined as being equal +// to some of QAbstractSocket's SocketState's values, we can use the superset +// of the two as the return type. +inline QAbstractSocket::SocketState socketState(QIODevice *device) +{ + auto getState = [](auto *s) { + using T = std::remove_pointer_t; + if constexpr (std::is_same_v) { + return s->state(); + } else if constexpr (std::is_same_v) { + QLocalSocket::LocalSocketState st = s->state(); + return static_cast(st); + } + Q_UNREACHABLE(); + }; + return visit(getState, device); +} + +// Same as for socketState(), but for the errors +inline QAbstractSocket::SocketError socketError(QIODevice *device) +{ + auto getError = [](auto *s) { + using T = std::remove_pointer_t; + if constexpr (std::is_same_v) { + return s->error(); + } else if constexpr (std::is_same_v) { + QLocalSocket::LocalSocketError st = s->error(); + return static_cast(st); + } + Q_UNREACHABLE(); + }; + return visit(getError, device); +} + +inline QString socketPeerName(QIODevice *device) +{ + auto getPeerName = [](auto *s) { + using T = std::remove_pointer_t; + if constexpr (std::is_same_v) { + return s->peerName(); + } else if constexpr (std::is_same_v) { + return s->serverName(); + } + Q_UNREACHABLE(); + }; + return visit(getPeerName, device); +} +} // namespace QSocketAbstraction + +QT_END_NAMESPACE + +#endif // QSOCKETABSTRACTION_P_H