// 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 #include #include #include #include #include #include #include #include #include #include std::string get_name(xmpp_stanza_t *stanza); std::optional get_attribute(xmpp_stanza_t *stanza, const char *name); std::string get_text(xmpp_stanza_t *stanza); std::chrono::system_clock::time_point get_time(const std::string& text); class jid { private: static const std::regex pattern; public: jid(xmpp_ctx_t *context, std::string s); operator std::string&() { return full; } std::string full; std::string_view bare; std::string_view local; std::string_view domain; std::string_view resource; bool is_bare() const; }; namespace xml { class node { protected: explicit node(); public: inline node(xmpp_ctx_t *context, xmpp_stanza_t *stanza) : context(context) { bind(context, stanza); } xmpp_ctx_t *context; std::optional name; std::optional id; std::optional ns; std::map attributes; std::vector children; std::string text; virtual void bind(xmpp_ctx_t *context, xmpp_stanza_t *stanza); inline std::optional get_attr(const std::string& name) { auto attribute = attributes.find(name); if (attribute != attributes.end()) return attribute->second; return {}; } template inline std::vector> get_children(std::string_view name) { std::vector> list; std::copy_if(children.begin(), children.end(), std::back_inserter(list), [&](node& x) { return x.name == name && x.ns == std::string_view(xmlns()); }); return list; } inline std::vector> get_children(std::string_view name) { std::vector> list; std::copy_if(children.begin(), children.end(), std::back_inserter(list), [&](node& x) { return x.name == name; }); return list; } }; } #include "xep-0027.inl" #include "xep-0045.inl" #include "xep-0115.inl" #include "xep-0319.inl" namespace xml { class message : virtual public node, public xep0027 { public: inline message(xmpp_ctx_t *context, xmpp_stanza_t *stanza) : node(context, stanza) { bind(context, stanza); } std::optional from; std::optional to; std::optional type; void bind(xmpp_ctx_t *context, xmpp_stanza_t *stanza) override; }; class presence : virtual public node, public xep0027, public xep0045, public xep0115, public xep0319 { public: inline presence(xmpp_ctx_t *context, xmpp_stanza_t *stanza) : node(context, stanza) { bind(context, stanza); } std::optional from; std::optional to; std::optional type; std::optional show(); std::optional status(); void bind(xmpp_ctx_t *context, xmpp_stanza_t *stanza) override; }; class iq : virtual public node { public: inline iq(xmpp_ctx_t *context, xmpp_stanza_t *stanza) : node(context, stanza) { bind(context, stanza); } std::optional from; std::optional to; std::optional type; void bind(xmpp_ctx_t *context, xmpp_stanza_t *stanza) override; }; class error : virtual public node { public: inline error(xmpp_ctx_t *context, xmpp_stanza_t *stanza) : node(context, stanza) { bind(context, stanza); } std::optional from; std::optional to; void bind(xmpp_ctx_t *context, xmpp_stanza_t *stanza) override; }; }