Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid implicit conversions in Zeek utility classes #376

Merged
merged 2 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ set(BROKER_SRC
src/topic.cc
src/version.cc
src/worker.cc
src/zeek.cc
)

if (ENABLE_SHARED)
Expand Down
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
Loading