From 62e2248c30d72ff9c8e2a9acc265d8c39f3c83ca Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Thu, 7 Apr 2022 16:22:34 +0200 Subject: Add MessageHandler interface --- src/client/QXmppClient.cpp | 43 ++++++++++++++++++++++++++++++++++++- src/client/QXmppClient.h | 1 + src/client/QXmppClientExtension.cpp | 13 +++++++++++ src/client/QXmppClientExtension.h | 2 ++ src/client/QXmppMessageHandler.cpp | 19 ++++++++++++++++ src/client/QXmppMessageHandler.h | 21 ++++++++++++++++++ 6 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 src/client/QXmppMessageHandler.cpp create mode 100644 src/client/QXmppMessageHandler.h (limited to 'src/client') diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp index a90fafed..104d94e4 100644 --- a/src/client/QXmppClient.cpp +++ b/src/client/QXmppClient.cpp @@ -14,6 +14,7 @@ #include "QXmppFutureUtils_p.h" #include "QXmppLogger.h" #include "QXmppMessage.h" +#include "QXmppMessageHandler.h" #include "QXmppOutgoingClient.h" #include "QXmppPacket_p.h" #include "QXmppRosterManager.h" @@ -126,6 +127,32 @@ bool process(const QList &extensions, const QDomElement } +namespace QXmpp::Private::MessagePipeline { + +bool process(QXmppClient *client, const QList &extensions, QXmppMessage &&message) +{ + for (auto *extension : extensions) { + if (auto *messageHandler = dynamic_cast(extension)) { + if (messageHandler->handleMessage(message)) { + return true; + } + } + } + return false; +} + +bool process(QXmppClient *client, const QList &extensions, const QDomElement &element) +{ + if (element.tagName() != "message") { + return false; + } + QXmppMessage message; + message.parse(element); + return process(client, extensions, std::move(message)); +} + +} + /// /// \typedef QXmppClient::IqResult /// @@ -807,6 +834,19 @@ void QXmppClient::injectIq(const QDomElement &element, const std::optionalextensions, std::move(message)); + if (!handled) { + // no extension handled the message + emit messageReceived(message); + } + return handled; +} + /// /// Give extensions a chance to handle incoming stanzas. /// @@ -814,7 +854,8 @@ void QXmppClient::_q_elementReceived(const QDomElement &element, bool &handled) { // The stanza comes directly from the XMPP stream, so it's not end-to-end // encrypted and there's no e2ee metadata (std::nullopt). - handled = StanzaPipeline::process(d->extensions, element, std::nullopt); + handled = StanzaPipeline::process(d->extensions, element, std::nullopt) || + MessagePipeline::process(this, d->extensions, element); } void QXmppClient::_q_reconnect() diff --git a/src/client/QXmppClient.h b/src/client/QXmppClient.h index 47b71706..82ac7d7b 100644 --- a/src/client/QXmppClient.h +++ b/src/client/QXmppClient.h @@ -309,6 +309,7 @@ public Q_SLOTS: private: void injectIq(const QDomElement &element, const std::optional &e2eeMetadata); + bool injectMessage(QXmppMessage &&message); private Q_SLOTS: void _q_elementReceived(const QDomElement &element, bool &handled); diff --git a/src/client/QXmppClientExtension.cpp b/src/client/QXmppClientExtension.cpp index 67f79889..f71e9163 100644 --- a/src/client/QXmppClientExtension.cpp +++ b/src/client/QXmppClientExtension.cpp @@ -119,3 +119,16 @@ void QXmppClientExtension::injectIq(const QDomElement &element, const std::optio { client()->injectIq(element, e2eeMetadata); } + +/// +/// Injects a message stanza into the client. +/// +/// The stanza is processed by the client with all extensions implementing +/// MessageHandler. +/// +/// \since QXmpp 1.5 +/// +bool QXmppClientExtension::injectMessage(QXmppMessage &&message) +{ + return client()->injectMessage(std::move(message)); +} diff --git a/src/client/QXmppClientExtension.h b/src/client/QXmppClientExtension.h index 3ba348d9..6dd1607a 100644 --- a/src/client/QXmppClientExtension.h +++ b/src/client/QXmppClientExtension.h @@ -13,6 +13,7 @@ class QDomElement; class QXmppClient; class QXmppClientExtensionPrivate; +class QXmppMessage; class QXmppStream; /// @@ -45,6 +46,7 @@ protected: virtual void setClient(QXmppClient *client); void injectIq(const QDomElement &element, const std::optional &e2eeMetadata); + bool injectMessage(QXmppMessage &&message); private: QXmppClientExtensionPrivate *const d; diff --git a/src/client/QXmppMessageHandler.cpp b/src/client/QXmppMessageHandler.cpp new file mode 100644 index 00000000..b6e4505c --- /dev/null +++ b/src/client/QXmppMessageHandler.cpp @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2022 Linus Jahn +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +/// +/// \class QXmppMessageHandler +/// +/// Interface for handling messages. +/// +/// \since QXmpp 1.5 +/// + +/// +/// \fn QXmppMessageHandler::handleMessage() +/// +/// Handles the message. +/// +/// \returns Whether the message has been handled and no other extensions should process it. +/// diff --git a/src/client/QXmppMessageHandler.h b/src/client/QXmppMessageHandler.h new file mode 100644 index 00000000..2335e56e --- /dev/null +++ b/src/client/QXmppMessageHandler.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2022 Linus Jahn +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPMESSAGEHANDLER_H +#define QXMPPMESSAGEHANDLER_H + +#include "QXmppExtension.h" +#include "QXmppMessage.h" + +#include + +#include + +class QXMPP_EXPORT QXmppMessageHandler : public QXmppExtension +{ +public: + virtual bool handleMessage(const QXmppMessage &) = 0; +}; + +#endif // QXMPPMESSAGEHANDLER_H -- cgit v1.2.3