From a94fcad957273a190c0cbd2eb65a58d3815da6cb Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 3 Dec 2020 14:25:18 -0700 Subject: [PATCH] Add templated As() method to Val, use in various places we were using dynamic_cast --- src/Expr.cc | 4 ++-- src/ID.cc | 4 ++-- src/Sessions.cc | 2 +- src/Val.h | 14 ++++++++++++++ src/option.bif | 2 +- src/strings.bif | 4 ++-- src/zeek.bif | 12 ++++++------ 7 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index f5caed4db2..f1431a1f25 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -1853,7 +1853,7 @@ ValPtr EqExpr::Fold(Val* v1, Val* v2) const { if ( op1->GetType()->Tag() == TYPE_PATTERN ) { - auto re = dynamic_cast(v1); + auto re = v1->As(); const String* s = v2->AsString(); if ( tag == EXPR_EQ ) return val_mgr->Bool(re->MatchExactly(s)); @@ -4151,7 +4151,7 @@ ValPtr InExpr::Fold(Val* v1, Val* v2) const { if ( v1->GetType()->Tag() == TYPE_PATTERN ) { - auto re = dynamic_cast(v1); + auto re = v1->As(); const String* s = v2->AsString(); return val_mgr->Bool(re->MatchAnywhere(s) != 0); } diff --git a/src/ID.cc b/src/ID.cc index 45695a16d8..9fa665f0de 100644 --- a/src/ID.cc +++ b/src/ID.cc @@ -87,7 +87,7 @@ FuncPtr id::find_func(std::string_view name) reporter->InternalError("Expected variable '%s' to be a function", std::string(name).data()); - return dynamic_cast(v.get())->AsFuncPtr(); + return v.get()->As()->AsFuncPtr(); } void id::detail::init_types() @@ -162,7 +162,7 @@ void ID::SetVal(ValPtr v) type->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT ) { EventHandler* handler = event_registry->Lookup(name); - auto func = dynamic_cast(val.get())->AsFuncPtr(); + auto func = val.get()->As()->AsFuncPtr(); if ( ! handler ) { handler = new EventHandler(name); diff --git a/src/Sessions.cc b/src/Sessions.cc index 30d2686a6e..b12e01a8e5 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -318,7 +318,7 @@ Connection* NetSessions::FindConnection(Val* v) return nullptr; RecordType* vr = vt->AsRecordType(); - auto vl = dynamic_cast(v); + auto vl = v->As(); int orig_h, orig_p; // indices into record's value list int resp_h, resp_p; diff --git a/src/Val.h b/src/Val.h index ec662c25bf..3e50088533 100644 --- a/src/Val.h +++ b/src/Val.h @@ -12,6 +12,7 @@ #include "zeek/Type.h" #include "zeek/Timer.h" #include "zeek/Notifier.h" +#include "zeek/Reporter.h" #include "zeek/net_util.h" // We have four different port name spaces: TCP, UDP, ICMP, and UNKNOWN. @@ -209,6 +210,19 @@ UNDERLYING_ACCESSOR_DECL(TypeVal, zeek::Type*, AsType) StringValPtr ToJSON(bool only_loggable=false, RE_Matcher* re=nullptr); + template + T As() + { + // Since we're converting from "this", make sure the type requested is a pointer. + static_assert(std::is_pointer()); + + auto v = dynamic_cast(this); + if ( ! v ) + reporter->InternalError("Failed dynamic_cast between Val types"); + + return v; + } + protected: // Friends with access to Clone(). diff --git a/src/option.bif b/src/option.bif index 6ced7a00dd..496baae0cc 100644 --- a/src/option.bif +++ b/src/option.bif @@ -209,7 +209,7 @@ function Option::set_change_handler%(ID: string, on_change: any, priority: int & return zeek::val_mgr->False(); } - auto func = dynamic_cast(on_change)->AsFuncPtr(); + auto func = on_change->As()->AsFuncPtr(); i->AddOptionHandler(func, -priority); return zeek::val_mgr->True(); %} diff --git a/src/strings.bif b/src/strings.bif index 13f14c5770..2f775bb990 100644 --- a/src/strings.bif +++ b/src/strings.bif @@ -707,7 +707,7 @@ function str_smith_waterman%(s1: string, s2: string, params: sw_params%) : sw_su ## .. zeek:see:: split_string split_string1 split_string_all split_string_n function str_split%(s: string, idx: index_vec%): string_vec &deprecated="Remove in v4.1. Use str_split_indices." %{ - auto idx_v = dynamic_cast(idx); + auto idx_v = idx->As(); auto n = idx_v->Size(); zeek::String::IdxVec indices(n); unsigned int i; @@ -746,7 +746,7 @@ function str_split%(s: string, idx: index_vec%): string_vec &deprecated="Remove ## .. zeek:see:: split_string split_string1 split_string_all split_string_n function str_split_indices%(s: string, idx: index_vec%): string_vec %{ - auto idx_v = dynamic_cast(idx); + auto idx_v = idx->As(); auto n = idx_v->Size(); zeek::String::IdxVec indices(n); unsigned int i; diff --git a/src/zeek.bif b/src/zeek.bif index 8f21cebde2..cb0dbc1cd9 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -1432,7 +1432,7 @@ function sort%(v: any, ...%) : any if ( ! comp && ! IsIntegral(elt_type->Tag()) ) zeek::emit_builtin_error("comparison function required for sort() with non-integral types"); - auto vv = dynamic_cast(v); + auto vv = v->As(); if ( comp ) { @@ -1502,7 +1502,7 @@ function order%(v: any, ...%) : index_vec if ( ! comp && ! IsIntegral(elt_type->Tag()) ) zeek::emit_builtin_error("comparison function required for order() with non-integral types"); - auto vv = dynamic_cast(v); + auto vv = v->As(); auto n = vv->Size(); // Set up initial mapping of indices directly to corresponding @@ -2410,7 +2410,7 @@ function addr_to_counts%(a: addr%): index_vec ## .. zeek:see:: addr_to_counts function counts_to_addr%(v: index_vec%): addr %{ - auto vv = dynamic_cast(v); + auto vv = v->As(); if ( vv->Size() == 1 ) { @@ -3528,8 +3528,8 @@ function lookup_connection%(cid: conn_id%): connection %%{ const char* conn_id_string(zeek::Val* c) { - auto id = dynamic_cast(c)->GetField(0); - auto id_r = dynamic_cast(id.get()); + auto id = c->As()->GetField(0); + auto id_r = id->As(); const zeek::IPAddr& orig_h = id_r->GetAddrField(0); uint32_t orig_p = id_r->GetPortValField(1)->Port(); @@ -3654,7 +3654,7 @@ function dump_packet%(pkt: pcap_packet, file_name: string%) : bool uint32_t caplen, len, link_type; u_char *data; - auto pkt_r = dynamic_cast(pkt); + auto pkt_r = pkt->As(); ts.tv_sec = pkt_r->GetCountField(0); ts.tv_usec = pkt_r->GetCountField(1);