lazy snote matching

This commit is contained in:
Eric Mertens 2023-11-28 11:34:27 -08:00
parent 1c3b9eb50f
commit 7458c8278c
3 changed files with 44 additions and 20 deletions

View File

@ -62,6 +62,14 @@ auto start(boost::asio::io_context & io, Settings const& settings) -> void
CommandThread::start(*connection); CommandThread::start(*connection);
echo_thread(*connection); echo_thread(*connection);
connection->add_listener<SnoteEvent>([](SnoteEvent& event) {
std::cout << "SNOTE " << static_cast<int>(event.get_tag()) << std::endl;
for (auto c : event.get_results())
{
std::cout << " " << std::string_view{c.first, c.second} << std::endl;
}
});
boost::asio::co_spawn( boost::asio::co_spawn(
io, io,
connection->connect(io, settings.host, settings.service), connection->connect(io, settings.host, settings.service),

View File

@ -155,19 +155,7 @@ auto SnoteThread::start(Connection& connection) -> std::shared_ptr<SnoteThread>
case HS_SCAN_TERMINATED: case HS_SCAN_TERMINATED:
{ {
auto& pattern = patterns[match_id]; auto& pattern = patterns[match_id];
std::match_results<std::string_view::const_iterator> results; connection.make_event<SnoteEvent>(pattern.tag, pattern.regex, message);
if (not std::regex_match(message.begin(), message.end(), results, pattern.regex))
{
// something went wrong - hyperscan disagrees with std::regex
abort();
}
std::vector<std::string_view> parts;
for (auto const sub : results)
{
parts.push_back(std::string_view{sub.first, sub.second});
}
connection.make_event<SnoteEvent>(pattern.tag, std::move(parts));
break; break;
} }
@ -180,6 +168,28 @@ auto SnoteThread::start(Connection& connection) -> std::shared_ptr<SnoteThread>
return thread; return thread;
} }
auto SnoteEvent::get_tag() const -> SnoteTag
{
return tag_;
}
auto SnoteEvent::get_results() -> std::match_results<std::string_view::const_iterator> const&
{
if (auto results = std::get_if<1>(&components_)) {
return *results;
}
auto& regex = std::get<0>(components_).first;
auto message = std::get<0>(components_).second;
auto& results = components_.emplace<1>();
if (not std::regex_match(message.begin(), message.end(), results, regex))
{
// something went wrong - hyperscan disagrees with std::regex
abort();
}
return results;
}
auto SnoteThread::DbDeleter::operator()(hs_database_t * db) const -> void auto SnoteThread::DbDeleter::operator()(hs_database_t * db) const -> void
{ {
if (HS_SUCCESS != hs_free_database(db)) if (HS_SUCCESS != hs_free_database(db))

View File

@ -3,8 +3,9 @@
#include "event.hpp" #include "event.hpp"
#include <memory> #include <memory>
#include <regex>
#include <string_view> #include <string_view>
#include <vector> #include <variant>
class Connection; class Connection;
struct hs_database; struct hs_database;
@ -27,15 +28,20 @@ enum class SnoteTag
Killed, Killed,
}; };
struct SnoteEvent : Event class SnoteEvent : public Event
{ {
SnoteEvent(SnoteTag tag, std::vector<std::string_view> parts) public:
: tag{tag} SnoteEvent(SnoteTag tag, std::regex const& regex, std::string_view full)
, parts{std::move(parts)} : tag_{tag}
, components_{std::make_pair(std::ref(regex), full)}
{} {}
SnoteTag tag; auto get_tag() const -> SnoteTag;
std::vector<std::string_view> parts; auto get_results() -> std::match_results<std::string_view::const_iterator> const&;
private:
SnoteTag tag_;
std::variant<std::pair<std::regex const&, std::string_view>, std::match_results<std::string_view::const_iterator>> components_;
}; };
struct SnoteThread struct SnoteThread