diff options
| author | Linus Jahn <lnj@kaidan.im> | 2021-09-05 16:02:37 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2021-09-28 17:08:08 +0200 |
| commit | 22be2464b5d253e840d4731fbc86e9633a394e8c (patch) | |
| tree | 341eea345bd621cd4ef045a79aca57129075ee8d /src/base | |
| parent | 21a198fd66e7c35622fce0b08c306553a4e4ff5a (diff) | |
| download | qxmpp-22be2464b5d253e840d4731fbc86e9633a394e8c.tar.gz | |
QXmppStream: Allow to use existing future interface
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/QXmppPacket.cpp | 26 | ||||
| -rw-r--r-- | src/base/QXmppPacket_p.h | 4 | ||||
| -rw-r--r-- | src/base/QXmppStream.cpp | 62 | ||||
| -rw-r--r-- | src/base/QXmppStream.h | 8 |
4 files changed, 84 insertions, 16 deletions
diff --git a/src/base/QXmppPacket.cpp b/src/base/QXmppPacket.cpp index 3676c269..3269369c 100644 --- a/src/base/QXmppPacket.cpp +++ b/src/base/QXmppPacket.cpp @@ -27,13 +27,31 @@ #include <QFuture> #include <QXmlStreamWriter> +inline QByteArray serialize(const QXmppNonza &nonza) +{ + QByteArray out; + QXmlStreamWriter xmlStream(&out); + nonza.toXml(&xmlStream); + return out; +} + /// \cond QXmppPacket::QXmppPacket(const QXmppNonza &nonza) - : m_interface(std::make_shared<QFutureInterface<QXmpp::SendResult>>(QFutureInterfaceBase::Started)), - m_isXmppStanza(nonza.isXmppStanza()) + : QXmppPacket(nonza, std::make_shared<QFutureInterface<QXmpp::SendResult>>()) { - QXmlStreamWriter xmlStream(&m_data); - nonza.toXml(&xmlStream); +} + +QXmppPacket::QXmppPacket(const QXmppNonza &nonza, std::shared_ptr<QFutureInterface<QXmpp::SendResult>> interface) + : QXmppPacket(serialize(nonza), nonza.isXmppStanza(), std::move(interface)) +{ +} + +QXmppPacket::QXmppPacket(const QByteArray &data, bool isXmppStanza, std::shared_ptr<QFutureInterface<QXmpp::SendResult>> interface) + : m_interface(std::move(interface)), + m_data(data), + m_isXmppStanza(isXmppStanza) +{ + m_interface->reportStarted(); } QByteArray QXmppPacket::data() const diff --git a/src/base/QXmppPacket_p.h b/src/base/QXmppPacket_p.h index a99752bb..0ce80760 100644 --- a/src/base/QXmppPacket_p.h +++ b/src/base/QXmppPacket_p.h @@ -36,7 +36,9 @@ class QXmppNonza; class QXmppPacket { public: - QXmppPacket(const QXmppNonza &); + QXmppPacket(const QXmppNonza &nonza); + QXmppPacket(const QXmppNonza &nonza, std::shared_ptr<QFutureInterface<QXmpp::SendResult>>); + QXmppPacket(const QByteArray &data, bool isXmppStanza, std::shared_ptr<QFutureInterface<QXmpp::SendResult>>); QByteArray data() const; bool isXmppStanza() const; diff --git a/src/base/QXmppStream.cpp b/src/base/QXmppStream.cpp index 1cac8740..895705a8 100644 --- a/src/base/QXmppStream.cpp +++ b/src/base/QXmppStream.cpp @@ -172,13 +172,13 @@ bool QXmppStream::sendData(const QByteArray &data) /// /// Sends an XMPP packet to the peer. /// -/// \param stanza +/// \param nonza /// -bool QXmppStream::sendPacket(const QXmppNonza &stanza) +bool QXmppStream::sendPacket(const QXmppNonza &nonza) { bool success; -// send(stanza, success); - return false; + send(nonza, success); + return success; } /// @@ -189,12 +189,24 @@ bool QXmppStream::sendPacket(const QXmppNonza &stanza) QFuture<QXmpp::SendResult> QXmppStream::send(QXmppNonza &&nonza) { bool success; - return send(std::move(nonza), success); + return send(QXmppPacket(nonza), success); +} + +/// +/// Sends an XMPP packet to the peer. +/// +/// \since QXmpp 1.5 +/// +QFuture<QXmpp::SendResult> QXmppStream::send(QXmppPacket &&packet) +{ + bool success; + return send(std::move(packet), success); } -QFuture<QXmpp::SendResult> QXmppStream::send(QXmppNonza &&nonza, bool &writtenToSocket) +QFuture<QXmpp::SendResult> QXmppStream::send(QXmppPacket &&packet, bool &writtenToSocket) { - QXmppPacket packet(nonza); + // the writtenToSocket parameter is just for backwards compat (see + // QXmppStream::sendPacket()) writtenToSocket = sendData(packet.data()); // handle stream management @@ -225,8 +237,28 @@ QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppIq &&iq) iq.setId(QXmppUtils::generateStanzaUuid()); } - const auto id = iq.id(); - auto sendFuture = send(std::move(iq)); + return sendIq(QXmppPacket(iq), iq.id()); +} + +/// +/// Sends an IQ packet and returns the response asynchronously. +/// +/// \warning THIS API IS NOT FINALIZED YET! +/// +/// \since QXmpp 1.5 +/// +QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppPacket &&packet, const QString &id) +{ + using namespace QXmpp; + + if (id.isEmpty() || d->runningIqs.contains(id)) { + return makeReadyFuture<IqResult>(QXmpp::SendError { + QStringLiteral("Invalid IQ id: empty or in use."), + SendError::Disconnected + }); + } + + auto sendFuture = send(std::move(packet)); if (sendFuture.isFinished()) { if (std::holds_alternative<SendError>(sendFuture.result())) { // early exit (saves QFutureWatcher) @@ -246,7 +278,7 @@ QFuture<QXmppStream::IqResult> QXmppStream::sendIq(QXmppIq &&iq) } IqState interface(IqState::Started); - d->runningIqs.insert(iq.id(), interface); + d->runningIqs.insert(id, interface); return interface.future(); } @@ -268,6 +300,16 @@ void QXmppStream::cancelOngoingIqs() } /// +/// Returns whether the IQ ID is currently in use. +/// +/// \since QXmpp 1.5 +/// +bool QXmppStream::hasIqId(const QString &id) const +{ + return d->runningIqs.contains(id); +} + +/// /// Resets the stream management packages cache. /// /// This can be done to prevent that packages from the last connection are being diff --git a/src/base/QXmppStream.h b/src/base/QXmppStream.h index e1fd31ac..3c321921 100644 --- a/src/base/QXmppStream.h +++ b/src/base/QXmppStream.h @@ -29,6 +29,7 @@ #include "QXmppSendResult.h" #include <variant> +#include <memory> #include <QAbstractSocket> #include <QObject> @@ -36,6 +37,8 @@ class QDomElement; template<typename T> class QFuture; +template<typename T> +class QFutureInterface; class QSslSocket; class QXmppIq; class QXmppNonza; @@ -58,10 +61,13 @@ public: bool sendPacket(const QXmppNonza &); QFuture<QXmpp::SendResult> send(QXmppNonza &&); + QFuture<QXmpp::SendResult> send(QXmppPacket &&); using IqResult = std::variant<QDomElement, QXmpp::SendError>; QFuture<IqResult> sendIq(QXmppIq &&); + QFuture<IqResult> sendIq(QXmppPacket &&, const QString &id); void cancelOngoingIqs(); + bool hasIqId(const QString &id) const; void resetPacketCache(); @@ -110,7 +116,7 @@ private: friend class tst_QXmppStream; friend class TestClient; - QFuture<QXmpp::SendResult> send(QXmppNonza &&, bool &); + QFuture<QXmpp::SendResult> send(QXmppPacket &&, bool &); void processData(const QString &data); bool handleIqResponse(const QDomElement &); |
