diff --git a/src/storage/Backend.cc b/src/storage/Backend.cc index a8d951b0dc..566ad56850 100644 --- a/src/storage/Backend.cc +++ b/src/storage/Backend.cc @@ -164,4 +164,26 @@ bool detail::BackendHandleVal::DoUnserializeData(BrokerDataView) { return false; } +namespace detail { + +zeek::expected BackendHandleVal::CastFromAny(Val* handle) { + // Quick exit by checking the type tag. This should be faster than doing the dynamic + // cast below. + if ( handle->GetType() != detail::backend_opaque ) + return zeek::unexpected( + OperationResult{ReturnCode::OPERATION_FAILED, "Invalid storage handle type"}); + + auto b = dynamic_cast(handle); + + if ( ! b ) + return zeek::unexpected( + OperationResult{ReturnCode::OPERATION_FAILED, "Invalid storage handle type"}); + else if ( ! b->backend->IsOpen() ) + return zeek::unexpected(OperationResult{ReturnCode::NOT_CONNECTED, "Backend is closed"}); + + return b; +} + +} // namespace detail + } // namespace zeek::storage diff --git a/src/storage/Backend.h b/src/storage/Backend.h index 17fb5e33bf..ab4156f44d 100644 --- a/src/storage/Backend.h +++ b/src/storage/Backend.h @@ -309,6 +309,16 @@ public: BackendHandleVal(BackendPtr backend) : OpaqueVal(detail::backend_opaque), backend(std::move(backend)) {} ~BackendHandleVal() override = default; + /** + * Attempts to cast a handle passed from script-land into a BackendHandleVal. Used by + * various BIF methods. + * + * @param handle The handle passed from script-land. + * @return A zeek::expected with either the correctly-casted handle, or an OperationResult + * containing error information. + */ + static zeek::expected CastFromAny(Val*); + BackendPtr backend; protected: diff --git a/src/storage/storage-async.bif b/src/storage/storage-async.bif index fecfcfe341..f31322a800 100644 --- a/src/storage/storage-async.bif +++ b/src/storage/storage-async.bif @@ -33,20 +33,6 @@ static zeek::detail::trigger::TriggerPtr init_trigger(zeek::detail::Frame* frame return {NewRef{}, trigger}; } -// Utility method to cast the handle val passed into BIF methods into a form that can -// be used to start storage operations. The method is also used by the BIFs in sync.bif. -static zeek::expected cast_handle(Val* handle) { - auto b = static_cast(handle); - - if ( ! b ) - return zeek::unexpected( - OperationResult{ReturnCode::OPERATION_FAILED, "Invalid storage handlle"}); - else if ( ! b->backend->IsOpen() ) - return zeek::unexpected(OperationResult{ReturnCode::NOT_CONNECTED, "Backend is closed"}); - - return b; -} - static void handle_async_result(const IntrusivePtr& backend, ResultCallback* cb, const OperationResult& op_result) { if ( op_result.code != ReturnCode::IN_PROGRESS || ! backend->SupportsAsync() ) { @@ -112,7 +98,7 @@ function Storage::Async::__close_backend%(backend: opaque of Storage::BackendHan return nullptr; auto cb = new ResultCallback(trigger, frame->GetTriggerAssoc()); - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) { cb->Complete(b.error()); delete cb; @@ -133,7 +119,7 @@ function Storage::Async::__put%(backend: opaque of Storage::BackendHandle, key: return nullptr; auto cb = new ResultCallback(trigger, frame->GetTriggerAssoc()); - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) { cb->Complete(b.error()); delete cb; @@ -158,7 +144,7 @@ function Storage::Async::__get%(backend: opaque of Storage::BackendHandle, key: return nullptr; auto cb = new ResultCallback(trigger, frame->GetTriggerAssoc()); - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) { cb->Complete(b.error()); delete cb; @@ -179,7 +165,7 @@ function Storage::Async::__erase%(backend: opaque of Storage::BackendHandle, key return nullptr; auto cb = new ResultCallback(trigger, frame->GetTriggerAssoc()); - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) { cb->Complete(b.error()); delete cb; diff --git a/src/storage/storage-sync.bif b/src/storage/storage-sync.bif index 8c20ff4d3b..e4bf87c31c 100644 --- a/src/storage/storage-sync.bif +++ b/src/storage/storage-sync.bif @@ -7,23 +7,6 @@ using namespace zeek; using namespace zeek::storage; - -// Utility method to cast the handle val passed into BIF methods into a form that can -// be used to start storage operations. This is a duplicate of the method in sync.bif -// due to how utility methods are built by bifcl. -/* -static zeek::expected cast_handle(Val* handle) { - auto b = static_cast(handle); - - if ( ! b ) - return zeek::unexpected( - OperationResult{ReturnCode::OPERATION_FAILED, "Invalid storage handlle"}); - else if ( ! b->backend->IsOpen() ) - return zeek::unexpected(OperationResult{ReturnCode::NOT_CONNECTED, "Backend is closed"}); - - return b; -} -*/ %%} module Storage::Sync; @@ -64,7 +47,7 @@ function Storage::Sync::__close_backend%(backend: opaque of Storage::BackendHand %{ OperationResult op_result; - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) op_result = b.error(); else { @@ -89,7 +72,7 @@ function Storage::Sync::__put%(backend: opaque of Storage::BackendHandle, key: a %{ OperationResult op_result; - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) op_result = b.error(); else { @@ -118,7 +101,7 @@ function Storage::Sync::__get%(backend: opaque of Storage::BackendHandle, key: a %{ OperationResult op_result; - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) op_result = b.error(); else { @@ -143,7 +126,7 @@ function Storage::Sync::__erase%(backend: opaque of Storage::BackendHandle, key: %{ OperationResult op_result; - auto b = cast_handle(backend); + auto b = storage::detail::BackendHandleVal::CastFromAny(backend); if ( ! b ) op_result = b.error(); else {