/** * The following are some structures used to decide at compile-time which handlers in * the lighttpd plugin structure to be set, based on a list of handler interface types * i.e. calling a handlers_setter< list< UriRawHandler, UriCleanHandler > >( p ) object * will set p->handle_uri_raw and p->handle_uri_clean hooks. * A list of handler types supported: * - UriRawHandler * - UriCleanHandler * - DocRootHandler * - PhysicalHandler * - StartBackendHandler */ #ifndef _LIGHTTPD_HANDLER_HELPERS_HPP_ #define _LIGHTTPD_HANDLER_HELPERS_HPP_ #include #include #include #include #include // Forward declarations for handlers_setter to use template < typename PluginType, typename Handler, typename HandlerList > struct handlers_setter_impl; struct handlers_setter_end; template < typename PluginType, typename HandlerList > struct handlers_setter_choose { typedef handlers_setter_impl< PluginType, typename boost::mpl::front< HandlerList >::type, typename boost::mpl::pop_front< HandlerList >::type > type; }; // calling handlers_setters type will set the hooks in p to // the appropriate functions according to HandlerList template < typename PluginType, typename HandlerList = typename PluginType::handlers > struct handlers_setter { typedef typename boost::mpl::empty< HandlerList >::type is_empty; typedef boost::mpl::identity< handlers_setter_end > handlers_setter_choose_end; typedef typename boost::mpl::eval_if< is_empty, handlers_setter_choose_end, handlers_setter_choose< PluginType, HandlerList > >::type type; }; /** * handlers_setter_base will decide which our next setter will be */ template < typename PluginType, typename HandlerList > struct handlers_setter_base { typedef typename handlers_setter< PluginType, HandlerList >::type next; }; /** * When we reach handlers_setter_end, we are at the end of the HandlerList */ struct handlers_setter_end { static void set( plugin& p ){} }; /** * Here we can partial specialize for Handler such that the right * hook will be set. */ template < typename PluginType, typename Handler, typename HandlerList > struct handlers_setter_impl : handlers_setter_base< PluginType, HandlerList > {}; // Macro for defining interfaces for handler classes, wrapper functions for // the calls to the appropriate handlers in class( p_d ) and metafunction // specializations of the handlers_setter_impl type. #define MAKE_HANDLER( TypedefHandle, handler_name ) \ struct TypedefHandle { handler_t handler_name( connection& ); }; \ template < typename PluginType, typename HandlerList > \ struct handlers_setter_impl< PluginType, TypedefHandle, HandlerList > \ : handlers_setter_base< PluginType, HandlerList > \ { \ typedef handlers_setter_base< PluginType, HandlerList > super_type; \ static handler_t handler_wrapper( server* srv, connection* con, void* p ) \ { \ PluginType* P = reinterpret_cast< PluginType* >( p ); \ return P->handler_name( *con ); \ } \ static void set( plugin& p ) \ { \ p.handler_name = &handler_wrapper; \ super_type::next::set( p ); \ } \ }; #endif // _LIGHTTPD_HANDLER_HELPERS_HPP_