From: Thomas Markwalder Date: Tue, 23 Apr 2024 14:38:51 +0000 (-0400) Subject: [#3314] Add optional handle context member fetch X-Git-Tag: Kea-2.5.8~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=81c6ecfcc79f3233fbd8b5973edec14ae018c919;p=thirdparty%2Fkea.git [#3314] Add optional handle context member fetch modified: src/lib/hooks/callout_handle.h modified: src/lib/hooks/tests/callout_handle_unittest.cc --- diff --git a/src/lib/hooks/callout_handle.h b/src/lib/hooks/callout_handle.h index fb4b30aa93..8dc934d0b6 100644 --- a/src/lib/hooks/callout_handle.h +++ b/src/lib/hooks/callout_handle.h @@ -281,6 +281,39 @@ public: value = boost::any_cast(element_ptr->second); } + /// @brief Fetch an optional named element from the current library + /// context. + /// + /// Gets an element from the context associated with the current library. + /// If either context or the named element do not exist, the function + /// returns false. + /// + /// @param name Name of the element in the context to get. + /// @param value [out] Value to set. The type of "value" is important: + /// it must match the type of the value set. + /// + /// @throw boost::bad_any_cast Thrown if the context element is present + /// but the type of the data is not the same as the type of the + /// variable provided to receive its value. + /// @return true if the named element exists, false otherwise. + template + bool getOptionalContext(const std::string& name, T& value) const { + const auto context_iter = context_collection_.find(current_library_); + if (context_iter == context_collection_.end()) { + // No context, punt. + return (false); + } + + auto lib_context = context_iter->second; + ElementCollection::const_iterator element_ptr = lib_context.find(name); + if (element_ptr == lib_context.end()) { + return (false); + } + + value = boost::any_cast(element_ptr->second); + return (true); + } + /// @brief Get context names /// /// Returns a vector holding the names of items in the context associated diff --git a/src/lib/hooks/tests/callout_handle_unittest.cc b/src/lib/hooks/tests/callout_handle_unittest.cc index bb20e0c513..b34c41760e 100644 --- a/src/lib/hooks/tests/callout_handle_unittest.cc +++ b/src/lib/hooks/tests/callout_handle_unittest.cc @@ -377,6 +377,34 @@ TEST_F(CalloutHandleTest, scopedState) { EXPECT_EQ(three, value); } +TEST_F(CalloutHandleTest, getOptionalContext) { + // Create pointer to the handle to be wrapped. + CalloutHandlePtr handle(new CalloutHandle(getCalloutManager())); + + int two = 2; + int three = 3; + int value = 77; + + // Should not find two or three. Value should not change. + EXPECT_FALSE(handle->getOptionalContext("two", value)); + EXPECT_EQ(77, value); + + EXPECT_FALSE(handle->getOptionalContext("three", value)); + EXPECT_EQ(77, value); + + // Set "two" in the context. + handle->setContext("two", two); + + // Should be find two but not three. + EXPECT_TRUE(handle->getOptionalContext("two", value)); + EXPECT_EQ(two, value); + EXPECT_FALSE(handle->getOptionalContext("three", value)); + + // Should find three. + handle->setContext("three", three); + EXPECT_TRUE(handle->getOptionalContext("two", value)); +} + // Further tests of the "skip" flag and tests of getting the name of the // hook to which the current callout is attached is in the "handles_unittest" // module.