// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. #ifndef CALLOUT_HANDLE_H #define CALLOUT_HANDLE_H #include #include #include #include #include #include namespace isc { namespace util { class CalloutHandle; // Forward declaration for CalloutHandle /// Typedef for a callout pointer extern "C" { typedef int (*CalloutPtr)(const CalloutHandle&); }; /// @brief No Such Context /// /// Thrown if an attempt is made to obtain context that has not been previously /// set. class NoSuchContext : public Exception { public: NoSuchContext(const char* file, size_t line, const char* what) : isc::Exception(file, line, what) {} }; /// @brief Global Callout Handle /// @todo Change name to Library Handle? /// /// This class is used to manage a loaded library. It is used by the user /// library to register callouts and by the HookManager to call them. The /// class also contains storage for library-specific context. /// /// Although there is an argument for the class to load unload the user /// library, that is handled by the HookManager to prevent the user library /// from accessing those functions. class LibraryHandle { private: /// Typedef to allow abbreviation of iterator specification in methods typedef std::map ContextCollection; public: /// @brief Constructor /// /// This is passed the ServerHooks object and an index number: the former /// allows for the sizing of the internal hook vector, and the latter /// is used by the CalloutHandle object to access appropriate context /// /// @param hooks Pointer to the hooks registered by the server. /// @param index Index of this library in the list of loaded libraries. LibraryHandle(boost::shared_ptr hooks, int index) : context_(), hooks_(hooks), index_(index) {} /// @brief Set Context /// /// Sets an element in the library context. If an element of the name /// is already present, it is replaced. /// /// @param name Name of the element in the context to set /// @param value Value to set template void setContext(const std::string& name, T value) { context_[name] = value; } /// @brief Get Context /// /// Sets an element in the library context. If the name does not exist, /// a "NoSuchContext" exception is thrown. /// /// @param name Name of the element in the context to set. /// @param value [out] Value to set. The type of "value" is important: /// it must match the type of the value set. /// /// @throw NoSuchContext Thrown if no context element with the name /// "name" is present. /// @throw boost::bad_any_cast Thrown if the context element is present, /// but the type of the element is not that expected template void getContext(const std::string& name, T& value) const { ContextCollection::const_iterator element_ptr = context_.find(name); if (element_ptr == context_.end()) { isc_throw(NoSuchContext, "unable to find library context datum " << name << " in library at index " << index_); } value = boost::any_cast(element_ptr->second); } private: /// Context - mapping of names variables that can be of different types. ContextCollection context_; /// Pointer to the list of hooks registered by the server boost::shared_ptr hooks_; ///< Pointer to hooks /// Index of this library in the list of libraries int index_; }; } // namespace util } // namespace isc #endif // CALLOUT_HANDLE_H