// Copyright (C) 2021 Ford Motor Company // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QCONNECTIONFACTORIES_H #define QCONNECTIONFACTORIES_H // // W A R N I N G // ------------- // // This file is part of the QtRO internal API and is not meant to be used // in applications. It contains "internal" components, which are exported // to allow new QIODevice channels to be added to extend QtRO. Usage of these // APIs may make your code source and binary incompatible with future versions // of Qt. // #include #include #include QT_BEGIN_NAMESPACE class QtROIoDeviceBasePrivate; class QtROClientIoDevicePrivate; class QtROExternalIoDevicePrivate; class Q_REMOTEOBJECTS_EXPORT QtROIoDeviceBase : public QObject { Q_OBJECT Q_DISABLE_COPY(QtROIoDeviceBase) public: explicit QtROIoDeviceBase(QObject *parent = nullptr); ~QtROIoDeviceBase() override; bool read(QtRemoteObjects::QRemoteObjectPacketTypeEnum &, QString &); virtual void write(const QByteArray &data); virtual void write(const QByteArray &data, qint64); virtual bool isOpen() const; virtual void close(); virtual qint64 bytesAvailable() const; virtual QIODevice *connection() const = 0; void initializeDataStream(); bool isClosing() const; void addSource(const QString &); void removeSource(const QString &); QSet remoteObjects() const; Q_SIGNALS: void readyRead(); void disconnected(); protected: explicit QtROIoDeviceBase(QtROIoDeviceBasePrivate &, QObject *parent); virtual QString deviceType() const = 0; virtual void doClose() = 0; private: Q_DECLARE_PRIVATE(QtROIoDeviceBase) friend class QRemoteObjectNodePrivate; friend class QConnectedReplicaImplementation; friend class QRemoteObjectSourceIo; }; class Q_REMOTEOBJECTS_EXPORT QtROServerIoDevice : public QtROIoDeviceBase { Q_OBJECT Q_DISABLE_COPY(QtROServerIoDevice) public: explicit QtROServerIoDevice(QObject *parent = nullptr); protected: QString deviceType() const override; }; class Q_REMOTEOBJECTS_EXPORT QConnectionAbstractServer : public QObject { Q_OBJECT Q_DISABLE_COPY(QConnectionAbstractServer) public: explicit QConnectionAbstractServer(QObject *parent = nullptr); ~QConnectionAbstractServer() override; virtual bool hasPendingConnections() const = 0; QtROServerIoDevice* nextPendingConnection(); virtual QUrl address() const = 0; virtual bool listen(const QUrl &address) = 0; virtual QAbstractSocket::SocketError serverError() const = 0; virtual void close() = 0; protected: virtual QtROServerIoDevice* configureNewConnection() = 0; Q_SIGNALS: void newConnection(); }; class Q_REMOTEOBJECTS_EXPORT QtROClientIoDevice : public QtROIoDeviceBase { Q_OBJECT Q_DISABLE_COPY(QtROClientIoDevice) public: explicit QtROClientIoDevice(QObject *parent = nullptr); ~QtROClientIoDevice() override; void disconnectFromServer(); virtual void connectToServer() = 0; QUrl url() const; Q_SIGNALS: void shouldReconnect(QtROClientIoDevice*); void setError(QRemoteObjectNode::ErrorCode); protected: virtual void doDisconnectFromServer() = 0; QString deviceType() const override; void setUrl(const QUrl &url); private: Q_DECLARE_PRIVATE(QtROClientIoDevice) friend class QtROClientFactory; }; class QtROServerFactory { public: Q_REMOTEOBJECTS_EXPORT static QtROServerFactory *instance(); QConnectionAbstractServer *create(const QUrl &url, QObject *parent = nullptr) { auto creatorFunc = m_creatorFuncs.value(url.scheme()); return creatorFunc ? (*creatorFunc)(parent) : nullptr; } template void registerType(const QString &id) { m_creatorFuncs[id] = [](QObject *parent) -> QConnectionAbstractServer * { return new T(parent); }; } bool isValid(const QUrl &url) { return m_creatorFuncs.contains(url.scheme()); } private: friend class QtROFactoryLoader; QtROServerFactory(); using CreatorFunc = QConnectionAbstractServer * (*)(QObject *); QHash m_creatorFuncs; }; class QtROClientFactory { public: Q_REMOTEOBJECTS_EXPORT static QtROClientFactory *instance(); /// creates an object from a string QtROClientIoDevice *create(const QUrl &url, QObject *parent = nullptr) { auto creatorFunc = m_creatorFuncs.value(url.scheme()); if (!creatorFunc) return nullptr; QtROClientIoDevice *res = (*creatorFunc)(parent); if (res) res->setUrl(url); return res; } template void registerType(const QString &id) { m_creatorFuncs[id] = [](QObject *parent) -> QtROClientIoDevice * { return new T(parent); }; } bool isValid(const QUrl &url) { return m_creatorFuncs.contains(url.scheme()); } private: friend class QtROFactoryLoader; QtROClientFactory(); using CreatorFunc = QtROClientIoDevice * (*)(QObject *); QHash m_creatorFuncs; }; template inline void qRegisterRemoteObjectsClient(const QString &id) { QtROClientFactory::instance()->registerType(id); } template inline void qRegisterRemoteObjectsServer(const QString &id) { QtROServerFactory::instance()->registerType(id); } QT_END_NAMESPACE #endif // QCONNECTIONFACTORIES_H