Skip to content

Commit

Permalink
Avoid implicit conversions in Zeek utility classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Neverlord committed Sep 24, 2023
1 parent 2121956 commit 1840fd2
Show file tree
Hide file tree
Showing 9 changed files with 430 additions and 166 deletions.
11 changes: 7 additions & 4 deletions doc/_examples/ping.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ int main() {
// Do five ping / pong.
for (int n = 0; n < 5; n++) {
// Send event "ping(n)".
zeek::Event ping("ping", {n});
ep.publish("/topic/test", ping);
ep.publish("/topic/test", zeek::Event{"ping", {n}});

// Wait for "pong" reply event.
auto msg = sub.get();
zeek::Event pong(move_data(msg));
std::cout << "received " << pong.name() << pong.args() << std::endl;
auto pong = zeek::Event{std::move(msg)};
if (pong.valid())
std::cout << "received " << pong.name() << pong.args() << std::endl;
else
std::cout << "received invalid pong message: " << to_string(pong)
<< std::endl;
}
}
11 changes: 7 additions & 4 deletions doc/_examples/pong.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@ int main() {
for (int n = 0; n < 5; n++) {
// Wait for a "ping" event.
auto msg = sub.get();
zeek::Event ping(move_data(msg));
std::cout << "received " << ping.name() << ping.args() << std::endl;
auto ping = zeek::Event{std::move(msg)};
if (ping.valid())
std::cout << "received " << ping.name() << ping.args() << std::endl;
else
std::cout << "received invalid ping message: " << to_string(ping)
<< std::endl;

// Send event "pong" response.
zeek::Event pong("pong", {n});
ep.publish("/topic/test", pong);
ep.publish("/topic/test", zeek::Event{"pong", {n}});
}
}
167 changes: 167 additions & 0 deletions include/broker/data.hh
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ public:
return *this;
}

// -- properties -------------------------------------------------------------

/// Returns a string representation of the stored type.
const char* get_type_name() const;

Expand All @@ -156,6 +158,171 @@ public:
return data_;
}

/// Checks whether this view contains the `nil` value.
bool is_none() const noexcept {
return get_type() == type::none;
}

/// Checks whether this view contains a boolean.
bool is_boolean() const noexcept {
return get_type() == type::boolean;
}

/// Checks whether this view contains a count.
bool is_count() const noexcept {
return get_type() == type::count;
}

/// Checks whether this view contains a integer.
bool is_integer() const noexcept {
return get_type() == type::integer;
}

/// Checks whether this view contains a real.
bool is_real() const noexcept {
return get_type() == type::real;
}

/// Checks whether this view contains a count.
bool is_string() const noexcept {
return get_type() == type::string;
}

/// Checks whether this view contains a count.
bool is_address() const noexcept {
return get_type() == type::address;
}

/// Checks whether this view contains a count.
bool is_subnet() const noexcept {
return get_type() == type::subnet;
}

/// Checks whether this view contains a count.
bool is_port() const noexcept {
return get_type() == type::port;
}

/// Checks whether this view contains a count.
bool is_timestamp() const noexcept {
return get_type() == type::timestamp;
}

/// Checks whether this view contains a count.
bool is_timespan() const noexcept {
return get_type() == type::timespan;
}

/// Checks whether this view contains a count.
bool is_enum_value() const noexcept {
return get_type() == type::enum_value;
}

/// Checks whether this view contains a set.
bool is_set() const noexcept {
return get_type() == type::set;
}

/// Checks whether this view contains a table.
bool is_table() const noexcept {
return get_type() == type::table;
}

/// Checks whether this view contains a list.
bool is_list() const noexcept {
return get_type() == type::vector;
}

// -- conversions ------------------------------------------------------------

/// Retrieves the @c boolean value or returns @p fallback if this object does
/// not contain a @c boolean.
bool to_boolean(bool fallback = false) const noexcept {
if (auto* val = std::get_if<boolean>(&data_))
return *val;
return fallback;
}

/// Retrieves the @c count value or returns @p fallback if this object does
/// not contain a @c count.
count to_count(count fallback = 0) const noexcept {
if (auto* val = std::get_if<count>(&data_))
return *val;
return fallback;
}

/// Retrieves the @c integer value or returns @p fallback if this object does
/// not contain a @c integer.
integer to_integer(integer fallback = 0) const noexcept {
if (auto* val = std::get_if<integer>(&data_))
return *val;
return fallback;
}

/// Retrieves the @c real value or returns @p fallback if this object does
/// not contain a @c real.
real to_real(real fallback = 0) const noexcept {
if (auto* val = std::get_if<real>(&data_))
return *val;
return fallback;
}

/// Retrieves the string value or returns an empty string if this object does
/// not contain a string.
std::string_view to_string() const noexcept {
if (auto* val = std::get_if<std::string>(&data_))
return *val;
return std::string_view{};
}

/// Retrieves the @c address value or returns @p fallback if this object does
/// not contain a @c address.
address to_address(const address& fallback = {}) const noexcept {
if (auto* val = std::get_if<address>(&data_))
return *val;
return fallback;
}

/// Retrieves the @c subnet value or returns @p fallback if this object does
/// not contain a @c subnet.
subnet to_subnet(const subnet& fallback = {}) const noexcept {
if (auto* val = std::get_if<subnet>(&data_))
return *val;
return fallback;
}

/// Retrieves the @c port value or returns @p fallback if this object does
/// not contain a @c port.
port to_port(port fallback = {}) const noexcept {
if (auto* val = std::get_if<port>(&data_))
return *val;
return fallback;
}

/// Retrieves the @c timestamp value or returns @p fallback if this object
/// does not contain a @c timestamp.
timestamp to_timestamp(timestamp fallback = {}) const noexcept {
if (auto* val = std::get_if<timestamp>(&data_))
return *val;
return fallback;
}

/// Retrieves the @c timespan value or returns @p fallback if this object does
/// not contain a @c timespan.
timespan to_timespan(timespan fallback = {}) const noexcept {
if (auto* val = std::get_if<timespan>(&data_))
return *val;
return fallback;
}

/// Retrieves the enum_value value or returns @p fallback if this object does
/// not contain a enum_value.
const enum_value& to_enum_value() const noexcept;

/// Converts the stored data as a list (`vector`). If the stored data is
/// not a list, the result is an empty list.
[[nodiscard]] const vector& to_list() const;

private:
data_variant data_;
};
Expand Down
17 changes: 17 additions & 0 deletions include/broker/endpoint.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ struct endpoint_context;

} // namespace broker::internal

namespace broker::zeek {

class Message;

} // namespace broker::zeek

namespace broker {

/// The main publish/subscribe abstraction. Endpoints can *peer* with each
Expand Down Expand Up @@ -258,6 +264,17 @@ public:
/// @param d The message data.
void publish(const endpoint_info& dst, topic t, data d);

/// Publishes a message.
/// @param t The topic of the message.
/// @param d The message data.
void publish(std::string_view t, zeek::Message&& d);

/// Publishes a message to a specific peer endpoint only.
/// @param dst The destination endpoint.
/// @param t The topic of the message.
/// @param d The message data.
void publish(const endpoint_info& dst, std::string_view t, zeek::Message&& d);

/// Publishes a message as vector.
/// @param t The topic of the messages.
/// @param xs The contents of the messages.
Expand Down
6 changes: 6 additions & 0 deletions include/broker/message.hh
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ inline const topic& get_topic(const data_message& x) {
return get<0>(x);
}

/// Retrieves the topic from a ::command_message as a string.
/// @relates data_message
inline std::string get_topic_str(const data_message& x) {
return get_topic(x).string();
}

/// Retrieves the topic from a ::command_message.
/// @relates data_message
inline const topic& get_topic(const command_message& x) {
Expand Down
Loading

0 comments on commit 1840fd2

Please sign in to comment.