From 0fd5514d496d3313634f953a321ffc46f3cc8147 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 18 Feb 2023 10:53:26 -0800 Subject: [PATCH] ircd::m: Add m::member(event) convenience inline interface. ircd::m::membership: Assertions for event type; optimize branch. --- include/ircd/m/m.h | 1 + include/ircd/m/member.h | 42 +++++++++++++++++++++++++++++++++++++ include/ircd/m/membership.h | 2 +- matrix/membership.cc | 36 +++++++++++++++++++------------ 4 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 include/ircd/m/member.h diff --git a/include/ircd/m/m.h b/include/ircd/m/m.h index 7b8a34040..a2fde5c5f 100644 --- a/include/ircd/m/m.h +++ b/include/ircd/m/m.h @@ -73,6 +73,7 @@ namespace ircd::m #include "rooms_summary.h" #include "groups.h" #include "membership.h" +#include "member.h" #include "filter.h" #include "events.h" #include "node.h" diff --git a/include/ircd/m/member.h b/include/ircd/m/member.h new file mode 100644 index 000000000..4d272a49b --- /dev/null +++ b/include/ircd/m/member.h @@ -0,0 +1,42 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2023 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_M_MEMBER_H + +namespace ircd::m +{ + bool member(const event &, const string_view &membership); + bool member(const event &, const vector_view &); +} + +/// Events that are not type=m.room.member will return false; the rest will be +/// passed to the analogous m::membership function which does not check type. +inline bool +ircd::m::member(const event &event, + const vector_view &membership) +{ + if(json::get<"type"_>(event) != "m.room.member") + return false; + + return m::membership(event, membership); +} + +/// Events that are not type=m.room.member will return false; the rest will be +/// passed to the analogous m::membership function which does not check type. +inline bool +ircd::m::member(const event &event, + const string_view &membership) +{ + if(json::get<"type"_>(event) != "m.room.member") + return false; + + return m::membership(event) == membership; +} diff --git a/include/ircd/m/membership.h b/include/ircd/m/membership.h index 2bbfb8155..92d7fdc7e 100644 --- a/include/ircd/m/membership.h +++ b/include/ircd/m/membership.h @@ -14,7 +14,7 @@ namespace ircd::m { // Extract membership string from event data. - string_view membership(const event &); + [[gnu::pure]] string_view membership(const event &); // Query and copy membership string to buffer. Note that the event type // is not checked here, only content.membership is sought. diff --git a/matrix/membership.cc b/matrix/membership.cc index 4babaa244..bbafdd10d 100644 --- a/matrix/membership.cc +++ b/matrix/membership.cc @@ -82,9 +82,14 @@ bool ircd::m::membership(const m::event &event, const vector_view &membership) { + const auto matching + { + m::membership(event) + }; + const auto it { - std::find(begin(membership), end(membership), m::membership(event)) + std::find(begin(membership), end(membership), matching) }; return it != end(membership); @@ -125,23 +130,28 @@ ircd::m::membership(const mutable_buffer &out, ircd::string_view ircd::m::membership(const event &event) { - const json::object &content - { - json::get<"content"_>(event) - }; + // The caller should check event type; empty is allowed if they only have content. + assert(!json::get<"type"_>(event) || json::get<"type"_>(event) == "m.room.member"); - const string_view &membership + const auto &membership { json::get<"membership"_>(event) }; - if(membership) - return membership; - - const json::string &content_membership + if(likely(!membership)) { - content.get("membership") - }; + const auto &content + { + json::get<"content"_>(event) + }; - return content_membership; + const json::string &membership + { + content.get("membership") + }; + + return membership; + } + + return membership; }