well hey it works

master
bqv 3 years ago
parent b5c0417f14
commit c5c197c562
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

@ -103,17 +103,16 @@ int connection__presence_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void
clientid = fmt::format("{}#{}", node, ver); clientid = fmt::format("{}#{}", node, ver);
std::string to = binding.to ? binding.to->full : ""; xmpp_send(conn, stanza::iq()
char *uuid = xmpp_uuid_gen(account->context); .from(binding.to ? binding.to->full : "")
.to(binding.from
xmpp_stanza_t *children[2] = {NULL}; .transform([](auto& x) { return x.full; })
children[0] = stanza__iq_query(account->context, NULL, .value_or(std::string()))
with_noop("http://jabber.org/protocol/disco#info"), NULL); .type("get")
children[0] = stanza__iq(account->context, NULL, children, NULL, .id(stanza::uuid(account->context))
uuid, to.size() ? strdup(to.data()) : NULL, .query()
binding.from ? strdup(binding.from->full.data()) : NULL, strdup("get")); .build(account->context)
xmpp_send(conn, children[0]); .get());
xmpp_stanza_release(children[0]);
} }
channel = channel__search(account, binding.from->bare.data()); channel = channel__search(account, binding.from->bare.data());
@ -1170,21 +1169,14 @@ int connection__iq_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userd
intext = xmpp_stanza_get_text(text); intext = xmpp_stanza_get_text(text);
} }
{ xmpp_send(conn, stanza::iq()
xmpp_stanza_t *children[2] = {0}; .from(to)
char *uuid = xmpp_uuid_gen(account->context); .to(jid)
.type("get")
children[0] = stanza__iq_query(account->context, NULL, .id(stanza::uuid(account->context))
with_noop("http://jabber.org/protocol/disco#info"), NULL); .query()
children[0] = .build(account->context)
stanza__iq(account->context, NULL, children, .get());
NULL, uuid,
strdup(to), strdup(jid),
strdup("get"));
xmpp_send(conn, children[0]);
xmpp_stanza_release(children[0]);
}
if (weechat_strcasecmp(autojoin, "true") == 0) if (weechat_strcasecmp(autojoin, "true") == 0)
{ {
char **command = weechat_string_dyn_alloc(256); char **command = weechat_string_dyn_alloc(256);

@ -9,6 +9,14 @@
#include "ns.hh" #include "ns.hh"
#pragma GCC visibility pop #pragma GCC visibility pop
std::string stanza::uuid(xmpp_ctx_t *context) {
std::shared_ptr<char> uuid {
xmpp_uuid_gen(context),
[=](auto x) { xmpp_free(context, x); }
};
return uuid.get();
}
std::string get_name(xmpp_stanza_t *stanza) { std::string get_name(xmpp_stanza_t *stanza) {
const char *result = NULL; const char *result = NULL;
result = xmpp_stanza_get_name(stanza); result = xmpp_stanza_get_name(stanza);

@ -44,6 +44,8 @@ public:
bool is_bare() const; bool is_bare() const;
}; };
class xmlns;
namespace xml { namespace xml {
class node { class node {
@ -77,7 +79,7 @@ namespace xml {
return {}; return {};
} }
template<typename xmlns> template<typename X, std::enable_if_t<std::is_base_of<xmlns,X>::value, int> = 0>
inline std::vector<std::reference_wrapper<node>> inline std::vector<std::reference_wrapper<node>>
get_children(std::string_view name) { get_children(std::string_view name) {
std::vector<std::reference_wrapper<node>> list; std::vector<std::reference_wrapper<node>> list;
@ -85,7 +87,7 @@ namespace xml {
std::back_inserter(list), std::back_inserter(list),
[&](node& x) { [&](node& x) {
return x.name == name return x.name == name
&& x.ns == std::string_view(xmlns()); && x.ns == std::string_view(X());
}); });
return list; return list;
} }
@ -102,9 +104,13 @@ namespace xml {
} }
}; };
namespace builder { }
namespace stanza {
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
extern std::string uuid(xmpp_ctx_t *context);
class spec { class spec {
protected: protected:
explicit spec(std::string_view tag): tag(tag) {} explicit spec(std::string_view tag): tag(tag) {}
@ -117,10 +123,15 @@ namespace xml {
attributes[k] = v; attributes[k] = v;
} }
inline void text(std::string_view s) { void text(std::string_view s) {
children.push_back(std::string(s)); children.push_back(std::string(s));
} }
template<typename X, std::enable_if_t<std::is_base_of<xmlns,X>::value, int> = 0>
void xmlns() {
attr("xmlns", X().ns());
}
private: private:
const std::string tag; const std::string tag;
std::map<std::string, std::string> attributes; std::map<std::string, std::string> attributes;
@ -149,15 +160,23 @@ namespace xml {
return { stanza, &xmpp_stanza_release }; return { stanza, &xmpp_stanza_release };
} }
}; };
};
#include "xep-0027.inl"
#include "xep-0030.inl"
#include "xep-0045.inl"
#include "xep-0115.inl"
#include "xep-0319.inl"
struct body : public spec { namespace stanza {
struct body : virtual public spec {
body() : body("") {} body() : body("") {}
body(std::string_view s) : spec("body") { body(std::string_view s) : spec("body") {
text(s); text(s);
} }
}; };
struct message : public spec { struct message : virtual public spec {
message() : spec("message") {} message() : spec("message") {}
message& id(std::string_view s) { attr("id", s); return *this; } message& id(std::string_view s) { attr("id", s); return *this; }
@ -165,30 +184,29 @@ namespace xml {
message& to(std::string_view s) { attr("to", s); return *this; } message& to(std::string_view s) { attr("to", s); return *this; }
message& type(std::string_view s) { attr("type", s); return *this; } message& type(std::string_view s) { attr("type", s); return *this; }
message& body(builder::body b) { child(b); return *this; } message& body(stanza::body b) { child(b); return *this; }
message& body(std::string_view s) { return body(builder::body(s)); } message& body(std::string_view s) { return body(stanza::body(s)); }
}; };
struct presence : public spec { struct presence : virtual public spec {
presence() : spec("presence") {} presence() : spec("presence") {}
}; };
struct iq : public spec { struct iq : virtual public spec,
public xep0030::iq {
iq() : spec("iq") {} iq() : spec("iq") {}
iq& id(std::string_view s) { attr("id", s); return *this; }
iq& from(std::string_view s) { attr("from", s); return *this; }
iq& to(std::string_view s) { attr("to", s); return *this; }
iq& type(std::string_view s) { attr("type", s); return *this; }
}; };
struct error : public spec { struct error : virtual public spec {
error() : spec("error") {} error() : spec("error") {}
}; };
}
} }
#include "xep-0027.inl"
#include "xep-0045.inl"
#include "xep-0115.inl"
#include "xep-0319.inl"
namespace xml { namespace xml {
class message : virtual public node, class message : virtual public node,

@ -0,0 +1,32 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#pragma once
#include <optional>
#include <string>
#include "node.hh"
#pragma GCC visibility push(default)
#include "ns.hh"
#pragma GCC visibility pop
namespace stanza {
/* Service Discovery */
struct xep0030 {
struct query : virtual public spec {
query() : spec("query") {
xmlns<jabber_org::protocol::disco::info>();
}
};
struct iq : virtual public spec {
iq() : spec("iq") {}
iq& query(query q = xep0030::query()) { child(q); return *this; }
};
};
}
Loading…
Cancel
Save