diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index dec03afb8e..2b7aa9bbb8 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -853,16 +853,29 @@ bool Manager::AutoUnpublishEvent(const string& topic, Val* event) { } RecordVal* Manager::MakeEvent(ValPList* args, zeek::detail::Frame* frame) { - auto rval = new RecordVal(BifType::Record::Broker::Event); + // Deprecated MakeEvent() version using ValPList - requires extra copy. + zeek::Args cargs; + cargs.reserve(args->size()); + for ( auto* a : *args ) + cargs.push_back({zeek::NewRef{}, a}); + + return MakeEvent(ArgsSpan{cargs}, frame)->Ref()->AsRecordVal(); +} + +zeek::RecordValPtr Manager::MakeEvent(ArgsSpan args, zeek::detail::Frame* frame) { + scoped_reporter_location srl{frame}; + return MakeEvent(args); +} + +zeek::RecordValPtr Manager::MakeEvent(ArgsSpan args) { + auto rval = zeek::make_intrusive(BifType::Record::Broker::Event); auto arg_vec = make_intrusive(vector_of_data_type); rval->Assign(1, arg_vec); - Func* func = nullptr; - scoped_reporter_location srl{frame}; + const Func* func = nullptr; - for ( auto i = 0; i < args->length(); ++i ) { - auto arg_val = (*args)[i]; - - if ( i == 0 ) { + for ( size_t index = 0; index < args.size(); index++ ) { + const auto& arg_val = args[index]; + if ( index == 0 ) { // Event val must come first. if ( arg_val->GetType()->Tag() != TYPE_FUNC ) { @@ -877,10 +890,10 @@ RecordVal* Manager::MakeEvent(ValPList* args, zeek::detail::Frame* frame) { return rval; } - auto num_args = func->GetType()->Params()->NumFields(); + auto num_args = static_cast(func->GetType()->Params()->NumFields()); - if ( num_args != args->length() - 1 ) { - Error("bad # of arguments: got %d, expect %d", args->length(), num_args + 1); + if ( num_args != args.size() - 1 ) { + Error("bad # of arguments: got %zu, expect %zu", args.size() - 1, num_args + 1); return rval; } @@ -888,12 +901,12 @@ RecordVal* Manager::MakeEvent(ValPList* args, zeek::detail::Frame* frame) { continue; } - const auto& got_type = (*args)[i]->GetType(); - const auto& expected_type = func->GetType()->ParamList()->GetTypes()[i - 1]; + const auto& got_type = arg_val->GetType(); + const auto& expected_type = func->GetType()->ParamList()->GetTypes()[index - 1]; if ( ! same_type(got_type, expected_type) ) { rval->Remove(0); - Error("event parameter #%d type mismatch, got %s, expect %s", i, type_name(got_type->Tag()), + Error("event parameter #%zu type mismatch, got %s, expect %s", index, type_name(got_type->Tag()), type_name(expected_type->Tag())); return rval; } @@ -901,17 +914,17 @@ RecordVal* Manager::MakeEvent(ValPList* args, zeek::detail::Frame* frame) { RecordValPtr data_val; if ( same_type(got_type, detail::DataVal::ScriptDataType()) ) - data_val = {NewRef{}, (*args)[i]->AsRecordVal()}; + data_val = {NewRef{}, arg_val->AsRecordVal()}; else - data_val = BrokerData::ToRecordVal((*args)[i]); + data_val = BrokerData::ToRecordVal(arg_val); if ( ! data_val->HasField(0) ) { rval->Remove(0); - Error("failed to convert param #%d of type %s to broker data", i, type_name(got_type->Tag())); + Error("failed to convert param #%zu of type %s to broker data", index, type_name(got_type->Tag())); return rval; } - arg_vec->Assign(i - 1, std::move(data_val)); + arg_vec->Assign(index - 1, std::move(data_val)); } return rval; diff --git a/src/broker/Manager.h b/src/broker/Manager.h index 43bd00fbc9..f748f4c5b0 100644 --- a/src/broker/Manager.h +++ b/src/broker/Manager.h @@ -14,6 +14,7 @@ #include #include "zeek/IntrusivePtr.h" +#include "zeek/Span.h" #include "zeek/broker/Data.h" #include "zeek/iosource/IOSource.h" #include "zeek/logging/WriterBackend.h" @@ -262,7 +263,27 @@ public: * @return an `Event` record value. If an invalid event or arguments * were supplied the optional "name" field will not be set. */ - RecordVal* MakeEvent(ValPList* args, zeek::detail::Frame* frame); + [[deprecated("Remove in v8.1: Use the ArgsSpan version instead")]] RecordVal* MakeEvent(ValPList* args, + zeek::detail::Frame* frame); + + using ArgsSpan = Span; + + /** + * Create an `Event` record value from an event and its arguments. + * @param args A span pointing at the event arguments. + * @return an `Event` record value. If an invalid event or arguments + * were supplied the optional "name" field will not be set. + */ + zeek::RecordValPtr MakeEvent(ArgsSpan args); + + /** + * Create an `Event` record value from an event and its arguments. + * @param args A span pointing at the event arguments. + * @param frame the calling frame, used to report location info upon error + * @return an `Event` record value. If an invalid event or arguments + * were supplied the optional "name" field will not be set. + */ + zeek::RecordValPtr MakeEvent(ArgsSpan args, zeek::detail::Frame* frame); /** * Register interest in peer event messages that use a certain topic prefix. diff --git a/src/broker/messaging.bif b/src/broker/messaging.bif index e647928190..92bb625dd8 100644 --- a/src/broker/messaging.bif +++ b/src/broker/messaging.bif @@ -5,9 +5,16 @@ #include #include +#include "zeek/Span.h" #include "zeek/broker/Manager.h" #include "zeek/logging/Manager.h" +namespace { + +using ArgsSpan = zeek::Span; + +} + static bool is_string_set(const zeek::Type* type) { if ( ! type->IsSet() ) @@ -46,7 +53,7 @@ std::set val_to_topic_set(zeek::Val* val) return rval; } -static bool publish_event_args(zeek::ValPList& args, const zeek::String* topic, +static bool publish_event_args(ArgsSpan args, const zeek::String* topic, zeek::detail::Frame* frame) { zeek::Broker::Manager::ScriptScopeGuard ssg; @@ -57,9 +64,8 @@ static bool publish_event_args(zeek::ValPList& args, const zeek::String* topic, args[0]->AsRecordVal()); else { - auto ev = zeek::broker_mgr->MakeEvent(&args, frame); - rval = zeek::broker_mgr->PublishEvent(topic->CheckString(), ev); - Unref(ev); + auto ev = zeek::broker_mgr->MakeEvent(args, frame); + rval = zeek::broker_mgr->PublishEvent(topic->CheckString(), ev->AsRecordVal()); } return rval; @@ -92,13 +98,9 @@ type Broker::Event: record; function Broker::make_event%(...%): Broker::Event %{ zeek::Broker::Manager::ScriptScopeGuard ssg; - const auto& bif_args = @ARGS@; - ValPList args(bif_args->size()); - for ( auto i = 0u; i < bif_args->size(); ++i ) - args.push_back((*bif_args)[i].get()); - - return RecordValPtr{zeek::AdoptRef{}, zeek::broker_mgr->MakeEvent(&args, frame)}; + auto ev = zeek::broker_mgr->MakeEvent(ArgsSpan{*@ARGS@}); + return zeek::cast_intrusive(ev); %} ## Publishes an event at a given topic. @@ -112,13 +114,8 @@ function Broker::make_event%(...%): Broker::Event ## Returns: true if the message is sent. function Broker::publish%(topic: string, ...%): bool %{ - const auto& bif_args = @ARGS@; - ValPList args(bif_args->size() - 1); - - for ( auto i = 1u; i < bif_args->size(); ++i ) - args.push_back((*bif_args)[i].get()); - - auto rval = publish_event_args(args, topic->AsString(), frame); + auto rval = publish_event_args(ArgsSpan{*@ARGS@}.subspan(1), + topic->AsString(), frame); return zeek::val_mgr->Bool(rval); %} @@ -208,13 +205,8 @@ function Cluster::publish_rr%(pool: Pool, key: string, ...%): bool if ( ! topic->AsString()->Len() ) return zeek::val_mgr->False(); - const auto& bif_args = @ARGS@; - ValPList args(bif_args->size() - 2); - - for ( auto i = 2u; i < bif_args->size(); ++i ) - args.push_back((*bif_args)[i].get()); - - auto rval = publish_event_args(args, topic->AsString(), frame); + auto rval = publish_event_args(ArgsSpan{*@ARGS@}.subspan(2), + topic->AsString(), frame); return zeek::val_mgr->Bool(rval); %} @@ -251,12 +243,7 @@ function Cluster::publish_hrw%(pool: Pool, key: any, ...%): bool if ( ! topic->AsString()->Len() ) return zeek::val_mgr->False(); - const auto& bif_args = @ARGS@; - ValPList args(bif_args->size() - 2); - - for ( auto i = 2u; i < bif_args->size(); ++i ) - args.push_back((*bif_args)[i].get()); - - auto rval = publish_event_args(args, topic->AsString(), frame); + auto rval = publish_event_args(ArgsSpan{*@ARGS@}.subspan(2), + topic->AsString(), frame); return zeek::val_mgr->Bool(rval); %}