mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 07:08:19 +00:00
support for transmitting of capture-semantics closures via Broker, while keeping deprecated functionality
This commit is contained in:
parent
e531b2a7ca
commit
80f7d36582
5 changed files with 166 additions and 35 deletions
108
src/Frame.cc
108
src/Frame.cc
|
@ -302,24 +302,25 @@ Frame* Frame::SelectiveClone(const IDPList& selection, ScriptFunc* func) const
|
|||
return other;
|
||||
}
|
||||
|
||||
broker::expected<broker::data> Frame::Serialize(const Frame* target, const IDPList& selection)
|
||||
broker::expected<broker::data> Frame::SerializeClosureFrame(const IDPList& selection)
|
||||
{
|
||||
broker::vector rval;
|
||||
|
||||
if ( selection.length() == 0 )
|
||||
// Easy - no captures, so frame is irrelvant.
|
||||
return {std::move(rval)};
|
||||
|
||||
IDPList us;
|
||||
// and
|
||||
IDPList them;
|
||||
|
||||
std::unordered_map<std::string, int> new_map;
|
||||
if ( target->offset_map )
|
||||
new_map = *(target->offset_map);
|
||||
OffsetMap new_map;
|
||||
if ( offset_map )
|
||||
new_map = *offset_map;
|
||||
|
||||
for (const auto& we : selection)
|
||||
for ( const auto& we : selection )
|
||||
{
|
||||
if ( target->IsOuterID(we) )
|
||||
if ( IsOuterID(we) )
|
||||
them.append(we);
|
||||
else
|
||||
{
|
||||
|
@ -330,18 +331,18 @@ broker::expected<broker::data> Frame::Serialize(const Frame* target, const IDPLi
|
|||
|
||||
if ( them.length() )
|
||||
{
|
||||
if ( ! target->closure )
|
||||
if ( ! closure )
|
||||
reporter->InternalError("Attempting to serialize values from a frame that does not exist.");
|
||||
|
||||
rval.emplace_back(std::string("ClosureFrame"));
|
||||
|
||||
auto ids = SerializeIDList(target->outer_ids);
|
||||
auto ids = SerializeIDList(outer_ids);
|
||||
if ( ! ids )
|
||||
return broker::ec::invalid_data;
|
||||
|
||||
rval.emplace_back(*ids);
|
||||
|
||||
auto serialized = Frame::Serialize(target->closure, them);
|
||||
auto serialized = closure->SerializeClosureFrame(them);
|
||||
if ( ! serialized )
|
||||
return broker::ec::invalid_data;
|
||||
|
||||
|
@ -358,7 +359,7 @@ broker::expected<broker::data> Frame::Serialize(const Frame* target, const IDPLi
|
|||
|
||||
broker::vector body;
|
||||
|
||||
for ( int i = 0; i < target->size; ++i )
|
||||
for ( int i = 0; i < size; ++i )
|
||||
body.emplace_back(broker::none());
|
||||
|
||||
for ( const auto& id : us )
|
||||
|
@ -366,10 +367,10 @@ broker::expected<broker::data> Frame::Serialize(const Frame* target, const IDPLi
|
|||
int location = id->Offset();
|
||||
|
||||
auto where = new_map.find(std::string(id->Name()));
|
||||
if (where != new_map.end())
|
||||
if ( where != new_map.end() )
|
||||
location = where->second;
|
||||
|
||||
const auto& val = target->frame[location].val;
|
||||
const auto& val = frame[location].val;
|
||||
|
||||
TypeTag tag = val->GetType()->Tag();
|
||||
|
||||
|
@ -386,15 +387,38 @@ broker::expected<broker::data> Frame::Serialize(const Frame* target, const IDPLi
|
|||
return {std::move(rval)};
|
||||
}
|
||||
|
||||
std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data)
|
||||
broker::expected<broker::data> Frame::SerializeCopyFrame()
|
||||
{
|
||||
broker::vector rval;
|
||||
rval.emplace_back(std::string("CopyFrame"));
|
||||
|
||||
broker::vector body;
|
||||
|
||||
for ( int i = 0; i < size; ++i )
|
||||
{
|
||||
const auto& val = frame[i].val;
|
||||
auto expected = Broker::detail::val_to_data(val.get());
|
||||
if ( ! expected )
|
||||
return broker::ec::invalid_data;
|
||||
|
||||
TypeTag tag = val->GetType()->Tag();
|
||||
broker::vector val_tuple {std::move(*expected),
|
||||
static_cast<broker::integer>(tag)};
|
||||
body.emplace_back(broker::none());
|
||||
body[i] = val_tuple;
|
||||
}
|
||||
|
||||
rval.emplace_back(body);
|
||||
|
||||
return {std::move(rval)};
|
||||
}
|
||||
|
||||
std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data,
|
||||
const std::vector<FuncType::Capture*>* captures)
|
||||
{
|
||||
if ( data.size() == 0 )
|
||||
return std::make_pair(true, nullptr);
|
||||
|
||||
IDPList outer_ids;
|
||||
OffsetMap offset_map;
|
||||
FramePtr closure;
|
||||
|
||||
auto where = data.begin();
|
||||
|
||||
auto has_name = broker::get_if<std::string>(*where);
|
||||
|
@ -403,6 +427,54 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data)
|
|||
|
||||
std::advance(where, 1);
|
||||
|
||||
if ( captures || *has_name == "CopyFrame" )
|
||||
{
|
||||
ASSERT(captures && *has_name == "CopyFrame");
|
||||
|
||||
auto has_body = broker::get_if<broker::vector>(*where);
|
||||
if ( ! has_body )
|
||||
return std::make_pair(false, nullptr);
|
||||
|
||||
broker::vector body = *has_body;
|
||||
int frame_size = body.size();
|
||||
auto rf = make_intrusive<Frame>(frame_size, nullptr, nullptr);
|
||||
|
||||
rf->closure = nullptr;
|
||||
|
||||
for ( int i = 0; i < frame_size; ++i )
|
||||
{
|
||||
auto has_vec = broker::get_if<broker::vector>(body[i]);
|
||||
if ( ! has_vec )
|
||||
continue;
|
||||
|
||||
broker::vector val_tuple = *has_vec;
|
||||
if ( val_tuple.size() != 2 )
|
||||
return std::make_pair(false, nullptr);
|
||||
|
||||
auto has_type = broker::get_if<broker::integer>(val_tuple[1]);
|
||||
if ( ! has_type )
|
||||
return std::make_pair(false, nullptr);
|
||||
|
||||
broker::integer g = *has_type;
|
||||
Type t( static_cast<TypeTag>(g) );
|
||||
|
||||
auto val = Broker::detail::data_to_val(std::move(val_tuple[0]), &t);
|
||||
if ( ! val )
|
||||
return std::make_pair(false, nullptr);
|
||||
|
||||
rf->frame[i].val = std::move(val);
|
||||
}
|
||||
|
||||
return std::make_pair(true, std::move(rf));
|
||||
}
|
||||
|
||||
|
||||
// Code to support deprecated semantics:
|
||||
|
||||
IDPList outer_ids;
|
||||
OffsetMap offset_map;
|
||||
FramePtr closure;
|
||||
|
||||
if ( *has_name == "ClosureFrame" )
|
||||
{
|
||||
auto has_vec = broker::get_if<broker::vector>(*where);
|
||||
|
@ -428,7 +500,7 @@ std::pair<bool, FramePtr> Frame::Unserialize(const broker::vector& data)
|
|||
|
||||
std::advance(where, 1);
|
||||
|
||||
auto closure_pair = Frame::Unserialize(*has_vec);
|
||||
auto closure_pair = Frame::Unserialize(*has_vec, nullptr);
|
||||
if ( ! closure_pair.first )
|
||||
{
|
||||
for ( auto& i : outer_ids )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue