QXmpp Version: 1.12.0
Loading...
Searching...
No Matches
QXmppDiscoveryManager_p.h
1// SPDX-FileCopyrightText: 2025 Linus Jahn <lnj@kaidan.im>
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4
5#ifndef QXMPPDISCOVERYMANAGER_P_H
6#define QXMPPDISCOVERYMANAGER_P_H
7
8#include "QXmppDiscoveryManager.h"
9#include "QXmppPromise.h"
10
11#include "Iq.h"
12
13#include <QCache>
14
15using namespace QXmpp::Private;
16
17namespace QXmpp::Private {
18
19template<typename Params, typename Response>
20struct AttachableRequests {
21 struct Request {
22 Params params;
23 std::vector<QXmppPromise<Response>> promises;
24 };
25
26 std::vector<Request> requests;
27
29 std::optional<QXmppTask<Response>> attach(const Params &key)
30 {
31 auto itr = std::ranges::find(requests, key, &Request::params);
32 if (itr != requests.end()) {
34 auto task = p.task();
35 itr->promises.push_back(std::move(p));
36 return task;
37 }
38
39 return std::nullopt;
40 }
41
42 QXmppTask<Response> makeNew(Params key)
43 {
44 Q_ASSERT(!contains(requests, key, &Request::params));
45
47 auto task = p.task();
48 requests.push_back(Request { key, { std::move(p) } });
49 return task;
50 }
51
52 void finish(const Params &key, Response &&response)
53 {
54 auto itr = std::ranges::find(requests, key, &Request::params);
55 Q_ASSERT(itr != requests.end());
56 if (itr == requests.end()) {
57 return;
58 }
59
60 auto promises = std::move(itr->promises);
61 requests.erase(itr);
62
63 for (auto it = promises.begin(); it != promises.end(); ++it) {
64 // copy unless this is the last iteration (then do move)
65 it->finish(std::next(it) == promises.end() ? std::move(response) : response);
66 }
67 }
68
69 QXmppTask<Response> produce(Params key, std::function<QXmppTask<Response>(Params)> requestFunction, QObject *context)
70 {
71 if (auto task = attach(key)) {
72 return *task;
73 }
74 auto task = makeNew(key);
75 requestFunction(key).then(context, [this, key](auto &&response) {
76 finish(key, std::move(response));
77 });
78 return task;
79 }
80};
81
82} // namespace QXmpp::Private
83
84class QXmppDiscoveryManagerPrivate
85{
86public:
88
89 QXmppDiscoveryManager *q = nullptr;
90 QString clientCapabilitiesNode;
91 QList<QXmppDiscoIdentity> identities;
92 QList<QXmppDataForm> dataForms;
93
94 // cached data
95 QCache<std::tuple<QString, QString>, QXmppDiscoInfo> infoCache;
96 QCache<std::tuple<QString, QString>, QList<QXmppDiscoItem>> itemsCache;
97
98 // outgoing requests
99 AttachableRequests<std::tuple<QString, QString>, QXmpp::Result<QXmppDiscoInfo>> infoRequests;
100 AttachableRequests<std::tuple<QString, QString>, QXmpp::Result<QList<QXmppDiscoItem>>> itemsRequests;
101
102 explicit QXmppDiscoveryManagerPrivate(QXmppDiscoveryManager *q) : q(q) { }
103
104 static QString defaultApplicationName();
105 static QXmppDiscoIdentity defaultIdentity();
106
107 std::variant<CompatIq<QXmppDiscoInfo>, StanzaError> handleIq(GetIq<QXmppDiscoInfo> &&iq);
108 std::variant<CompatIq<QXmppDiscoItems>, StanzaError> handleIq(GetIq<QXmppDiscoItems> &&iq);
109};
110
111#endif // QXMPPDISCOVERYMANAGER_P_H
Definition QXmppDiscoveryIq.h:83
Definition QXmppDiscoveryIq.h:142
The QXmppDiscoveryManager class makes it possible to discover information about other entities as def...
Definition QXmppDiscoveryManager.h:23
Create and update QXmppTask objects to communicate results of asynchronous operations.
Definition QXmppPromise.h:23
QXmppTask< T > task()
Definition QXmppPromise.h:86
The Error class represents a stanza error.
Definition QXmppStanza.h:96
Definition QXmppTask.h:46
std::variant< T, QXmppError > Result
Definition QXmppGlobal.h:205