Skip to content

Commit

Permalink
Add MessageHandler interface
Browse files Browse the repository at this point in the history
  • Loading branch information
lnjX committed May 20, 2022
1 parent f10146c commit 62e2248
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ set(INSTALL_HEADER_FILES
client/QXmppEntityTimeManager.h
client/QXmppInvokable.h
client/QXmppMamManager.h
client/QXmppMessageHandler.h
client/QXmppMessageReceiptManager.h
client/QXmppMucManager.h
client/QXmppOutgoingClient.h
Expand Down
43 changes: 42 additions & 1 deletion src/client/QXmppClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -126,6 +127,32 @@ bool process(const QList<QXmppClientExtension *> &extensions, const QDomElement

}

namespace QXmpp::Private::MessagePipeline {

bool process(QXmppClient *client, const QList<QXmppClientExtension *> &extensions, QXmppMessage &&message)
{
for (auto *extension : extensions) {
if (auto *messageHandler = dynamic_cast<QXmppMessageHandler *>(extension)) {
if (messageHandler->handleMessage(message)) {
return true;
}
}
}
return false;
}

bool process(QXmppClient *client, const QList<QXmppClientExtension *> &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
///
Expand Down Expand Up @@ -807,14 +834,28 @@ void QXmppClient::injectIq(const QDomElement &element, const std::optional<QXmpp
}
}

///
/// Processes the message with message handlers and emits messageReceived as a fallback.
///
bool QXmppClient::injectMessage(QXmppMessage &&message)
{
auto handled = MessagePipeline::process(this, d->extensions, std::move(message));
if (!handled) {
// no extension handled the message
emit messageReceived(message);
}
return handled;
}

///
/// Give extensions a chance to handle incoming stanzas.
///
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()
Expand Down
1 change: 1 addition & 0 deletions src/client/QXmppClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ public Q_SLOTS:

private:
void injectIq(const QDomElement &element, const std::optional<QXmppE2eeMetadata> &e2eeMetadata);
bool injectMessage(QXmppMessage &&message);

private Q_SLOTS:
void _q_elementReceived(const QDomElement &element, bool &handled);
Expand Down
13 changes: 13 additions & 0 deletions src/client/QXmppClientExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
2 changes: 2 additions & 0 deletions src/client/QXmppClientExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class QDomElement;

class QXmppClient;
class QXmppClientExtensionPrivate;
class QXmppMessage;
class QXmppStream;

///
Expand Down Expand Up @@ -45,6 +46,7 @@ class QXMPP_EXPORT QXmppClientExtension : public QXmppLoggable, public QXmppExte
virtual void setClient(QXmppClient *client);

void injectIq(const QDomElement &element, const std::optional<QXmppE2eeMetadata> &e2eeMetadata);
bool injectMessage(QXmppMessage &&message);

private:
QXmppClientExtensionPrivate *const d;
Expand Down
19 changes: 19 additions & 0 deletions src/client/QXmppMessageHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2022 Linus Jahn <[email protected]>
//
// 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.
///
21 changes: 21 additions & 0 deletions src/client/QXmppMessageHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: 2022 Linus Jahn <[email protected]>
//
// SPDX-License-Identifier: LGPL-2.1-or-later

#ifndef QXMPPMESSAGEHANDLER_H
#define QXMPPMESSAGEHANDLER_H

#include "QXmppExtension.h"
#include "QXmppMessage.h"

#include <variant>

#include <QFuture>

class QXMPP_EXPORT QXmppMessageHandler : public QXmppExtension
{
public:
virtual bool handleMessage(const QXmppMessage &) = 0;
};

#endif // QXMPPMESSAGEHANDLER_H

0 comments on commit 62e2248

Please sign in to comment.