]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3314] Add optional handle context member fetch
authorThomas Markwalder <tmark@isc.org>
Tue, 23 Apr 2024 14:38:51 +0000 (10:38 -0400)
committerThomas Markwalder <tmark@isc.org>
Wed, 24 Apr 2024 11:35:49 +0000 (11:35 +0000)
modified:   src/lib/hooks/callout_handle.h
modified:   src/lib/hooks/tests/callout_handle_unittest.cc

src/lib/hooks/callout_handle.h
src/lib/hooks/tests/callout_handle_unittest.cc

index fb4b30aa9369f258b5a997990ab07ce8f8557a2d..8dc934d0b64025e3176fc3255ccead7b9efed00c 100644 (file)
@@ -281,6 +281,39 @@ public:
         value = boost::any_cast<T>(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 <typename T>
+    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<T>(element_ptr->second);
+        return (true);
+    }
+
     /// @brief Get context names
     ///
     /// Returns a vector holding the names of items in the context associated
index bb20e0c51307a470899e0d8e00f90bf49df25d01..b34c41760ed654ba5f00159db429c36b1a166cd6 100644 (file)
@@ -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.