well hey it works

master
bqv 2 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);
std::string to = binding.to ? binding.to->full : "";
char *uuid = xmpp_uuid_gen(account->context);
xmpp_stanza_t *children[2] = {NULL};
children[0] = stanza__iq_query(account->context, NULL,
with_noop("http://jabber.org/protocol/disco#info"), NULL);
children[0] = stanza__iq(account->context, NULL, children, NULL,
uuid, to.size() ? strdup(to.data()) : NULL,
binding.from ? strdup(binding.from->full.data()) : NULL, strdup("get"));
xmpp_send(conn, children[0]);
xmpp_stanza_release(children[0]);
xmpp_send(conn, stanza::iq()
.from(binding.to ? binding.to->full : "")
.to(binding.from
.transform([](auto& x) { return x.full; })
.value_or(std::string()))
.type("get")
.id(stanza::uuid(account->context))
.query()
.build(account->context)
.get());
}
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);
}
{
xmpp_stanza_t *children[2] = {0};
char *uuid = xmpp_uuid_gen(account->context);
children[0] = stanza__iq_query(account->context, NULL,
with_noop("http://jabber.org/protocol/disco#info"), NULL);
children[0] =
stanza__iq(account->context, NULL, children,
NULL, uuid,
strdup(to), strdup(jid),
strdup("get"));
xmpp_send(conn, children[0]);
xmpp_stanza_release(children[0]);
}
xmpp_send(conn, stanza::iq()
.from(to)
.to(jid)
.type("get")
.id(stanza::uuid(account->context))
.query()
.build(account->context)
.get());
if (weechat_strcasecmp(autojoin, "true") == 0)
{
char **command = weechat_string_dyn_alloc(256);

@ -9,6 +9,14 @@
#include "ns.hh"
#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) {
const char *result = NULL;
result = xmpp_stanza_get_name(stanza);

@ -44,6 +44,8 @@ public:
bool is_bare() const;
};
class xmlns;
namespace xml {
class node {
@ -77,7 +79,7 @@ namespace xml {
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>>
get_children(std::string_view name) {
std::vector<std::reference_wrapper<node>> list;
@ -85,7 +87,7 @@ namespace xml {
std::back_inserter(list),
[&](node& x) {
return x.name == name
&& x.ns == std::string_view(xmlns());
&& x.ns == std::string_view(X());
});
return list;
}
@ -102,93 +104,109 @@ namespace xml {
}
};
namespace builder {
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
}
class spec {
protected:
explicit spec(std::string_view tag): tag(tag) {}
namespace stanza {
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
void child(spec& ch) {
children.push_back(ch);
}
extern std::string uuid(xmpp_ctx_t *context);
void attr(std::string k, std::string_view v) {
attributes[k] = v;
}
class spec {
protected:
explicit spec(std::string_view tag): tag(tag) {}
inline void text(std::string_view s) {
children.push_back(std::string(s));
}
void child(spec& ch) {
children.push_back(ch);
}
private:
const std::string tag;
std::map<std::string, std::string> attributes;
std::vector<std::variant<spec, std::string>> children;
public:
std::shared_ptr<xmpp_stanza_t> build(xmpp_ctx_t *context) {
auto stanza = xmpp_stanza_new(context);
xmpp_stanza_set_name(stanza, tag.data());
for (auto& at : attributes) {
xmpp_stanza_set_attribute(stanza, at.first.data(), at.second.data());
}
for (auto& ch : children) {
std::visit(overloaded {
[&](spec& child) {
xmpp_stanza_add_child(stanza, child.build(context).get());
},
[&](std::string s) {
auto child = xmpp_stanza_new(context);
xmpp_stanza_set_text(child, s.data());
xmpp_stanza_add_child(stanza, child);
xmpp_stanza_release(child);
}
}, ch);
}
return { stanza, &xmpp_stanza_release };
}
};
void attr(std::string k, std::string_view v) {
attributes[k] = v;
}
struct body : public spec {
body() : body("") {}
body(std::string_view s) : spec("body") {
text(s);
void text(std::string_view 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:
const std::string tag;
std::map<std::string, std::string> attributes;
std::vector<std::variant<spec, std::string>> children;
public:
std::shared_ptr<xmpp_stanza_t> build(xmpp_ctx_t *context) {
auto stanza = xmpp_stanza_new(context);
xmpp_stanza_set_name(stanza, tag.data());
for (auto& at : attributes) {
xmpp_stanza_set_attribute(stanza, at.first.data(), at.second.data());
}
for (auto& ch : children) {
std::visit(overloaded {
[&](spec& child) {
xmpp_stanza_add_child(stanza, child.build(context).get());
},
[&](std::string s) {
auto child = xmpp_stanza_new(context);
xmpp_stanza_set_text(child, s.data());
xmpp_stanza_add_child(stanza, child);
xmpp_stanza_release(child);
}
}, ch);
}
};
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"
namespace stanza {
struct body : virtual public spec {
body() : body("") {}
body(std::string_view s) : spec("body") {
text(s);
}
};
struct message : public spec {
message() : spec("message") {}
struct message : virtual public spec {
message() : spec("message") {}
message& id(std::string_view s) { attr("id", s); return *this; }
message& from(std::string_view s) { attr("from", 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& id(std::string_view s) { attr("id", s); return *this; }
message& from(std::string_view s) { attr("from", 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& body(builder::body b) { child(b); return *this; }
message& body(std::string_view s) { return body(builder::body(s)); }
};
message& body(stanza::body b) { child(b); return *this; }
message& body(std::string_view s) { return body(stanza::body(s)); }
};
struct presence : public spec {
presence() : spec("presence") {}
};
struct presence : virtual public spec {
presence() : spec("presence") {}
};
struct iq : public spec {
iq() : spec("iq") {}
};
struct iq : virtual public spec,
public xep0030::iq {
iq() : spec("iq") {}
struct error : public spec {
error() : spec("error") {}
};
}
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 : virtual public spec {
error() : spec("error") {}
};
}
#include "xep-0027.inl"
#include "xep-0045.inl"
#include "xep-0115.inl"
#include "xep-0319.inl"
namespace xml {
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