From d17ac6a8bb2b600d7aa050027665dea0953553df Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 30 Mar 2019 16:35:05 -0700 Subject: [PATCH] ircd::m::id: Add id part-swapping interface. --- include/ircd/m/id.h | 6 ++++++ ircd/m_id.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/ircd/m/id.h b/include/ircd/m/id.h index e91c72374..5e6ade1da 100644 --- a/include/ircd/m/id.h +++ b/include/ircd/m/id.h @@ -74,6 +74,12 @@ struct ircd::m::id uint16_t port() const; // Just the port number or 0 if none bool literal() const; // Whether the hostname() is IP literal + // Rewrites the ID so the local and host parts are swapped; for indexing. + // e.g. `$foo:bar.com` becomes `bar.com$foo`; unswap() reverses to normal. + static id unswap(const string_view &, const mutable_buffer &); + static string_view swap(const id &, const mutable_buffer &); + string_view swap(const mutable_buffer &) const; + IRCD_USING_OVERLOAD(generate, m::generate); id(const enum sigil &, const mutable_buffer &, const generate_t &, const string_view &host); diff --git a/ircd/m_id.cc b/ircd/m_id.cc index d4b0f54e7..2e43afb2b 100644 --- a/ircd/m_id.cc +++ b/ircd/m_id.cc @@ -456,6 +456,48 @@ ircd::m::id::id(const enum sigil &sigil, { } +ircd::string_view +ircd::m::id::swap(const mutable_buffer &buf) +const +{ + return swap(*this, buf); +} + +ircd::string_view +ircd::m::id::swap(const id &id, + const mutable_buffer &buf_) +{ + using buffer::consume; + using buffer::copy; + using buffer::data; + + mutable_buffer buf(buf_); + consume(buf, copy(buf, id.host())); + consume(buf, copy(buf, id.local())); + return { data(buf_), data(buf) }; +} + +ircd::m::id +ircd::m::id::unswap(const string_view &str, + const mutable_buffer &buf) +{ + size_t i(0); + for(; i < str.size(); ++i) + if(is_sigil(str[i])) + break; + + if(unlikely(!i || i >= str.size())) + throw m::INVALID_MXID + { + "Failed to reconstruct any MXID out of '%s'", str + }; + + return id + { + sigil(str[i]), buf, str.substr(i), str.substr(0, i) + }; +} + bool ircd::m::id::literal() const