--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2008 by Gerd v. Egidy and Reinhard Pfau *
+ * gve@intra2net.com *
+ * *
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef __LIBT2N_CLIENT_WRAPPER
+#define __LIBT2N_CLIENT_WRAPPER
+
+#include <functional>
+
+#include <boost/config.hpp>
+#include <boost/any.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/preprocessor.hpp>
+
+#include <client.hxx>
+#include <command_client.hxx>
+
+#ifndef T2NWRAPPER_MAX_ARGS
+#define T2NWRAPPER_MAX_ARGS 9
+#endif
+
+namespace libt2n
+{
+
+class ConnectionInitData
+{
+ public:
+
+ virtual std::auto_ptr<client_connection> createConnection()=0;
+
+ virtual ~ConnectionInitData()
+ { }
+};
+
+class TrivialHandler
+{
+ public:
+ static void handle( boost::function< void() > f)
+ {
+ f();
+ }
+};
+
+// contains the internal stuff needed for T2nWrapper
+namespace detail
+{
+
+ template< typename T >
+ struct TypeWrap
+ {
+ typedef T type;
+ };
+
+ template< >
+ struct TypeWrap< void >
+ {
+ typedef int type;
+ };
+
+ template< typename R >
+ struct Call
+ {
+ typedef boost::function< R() > FuncType;
+
+ FuncType function;
+ R& result;
+
+ Call( FuncType f, R& res ) : function(f), result( res ) {}
+
+ void operator()()
+ {
+ result= function();
+ }
+ };
+
+ template< >
+ struct Call<void>
+ {
+ typedef boost::function< void() > FuncType;
+ typedef TypeWrap< void >::type ResultType;
+
+ FuncType function;
+ ResultType& result;
+
+ Call( FuncType f, ResultType& res ) : function(f), result( res ) {}
+
+ void operator()()
+ {
+ function();
+ result= ResultType();
+ }
+ };
+} // eo namespace detail
+
+template<
+ class Client,
+ class Handler = TrivialHandler
+>
+class T2nWrapper
+{
+ private:
+
+ std::auto_ptr<client_connection> conndConn;
+ std::auto_ptr<Client> client;
+
+ static std::auto_ptr<T2nWrapper> singletonObject;
+ static std::auto_ptr<ConnectionInitData> initData;
+
+ // create a prep-method for each possible number of parameters
+#define _GEN_ARG(z,n,d) Arg ## n arg ##n
+#define _GEN_PREP(z,n,d) \
+ template< typename R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,typename Arg) > \
+ static boost::function< R(Client*) > prep \
+ ( \
+ R(Client::*f)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \
+ BOOST_PP_COMMA_IF(n) \
+ BOOST_PP_ENUM( n, _GEN_ARG, ~ ) \
+ ) \
+ { \
+ return boost::bind< R > \
+ ( \
+ f, _1 BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,arg) \
+ ); \
+ } // eo prep
+
+ BOOST_PP_REPEAT( BOOST_PP_ADD(T2NWRAPPER_MAX_ARGS,1) , _GEN_PREP, ~ )
+
+#undef _GEN_PREP
+#undef _GEN_ARG
+
+ static void ensureSingletonThere(void)
+ {
+ if (singletonObject.get() == NULL)
+ {
+ // we need to initialize
+
+ if (initData.get() == NULL)
+ throw std::logic_error("T2nWrapper singleton used before setting initData");
+
+ std::auto_ptr<client_connection> myConndConn=initData->createConnection();
+
+ }
+ }
+
+ template< typename R >
+ static
+ typename detail::TypeWrap<R>::type real_exec( boost::function< R(Client*) > f)
+ {
+ ensureSingletonThere();
+
+ typename detail::TypeWrap<R>::type result;
+ detail::Call<R> call( boost::bind( f, &(*(singletonObject->client))), result );
+ Handler::handle( call );
+ return result;
+ }
+
+ public:
+
+ static void setInitData(std::auto_ptr<ConnectionInitData> newInitData)
+ { initData=newInitData; }
+ static ConnectionInitData* getInitData(void)
+ { return initData.get(); }
+
+ T2nWrapper()
+ {
+ client=std::auto_ptr<Client>(new Client(*conndConn));
+ }
+
+ // create an exec-method for each possible number of parameters
+#define _GEN_PLACEHOLDER(z,n,d) BOOST_PP_CAT(_,BOOST_PP_ADD(n,1))
+#define _GEN_EXEC(z,n,d) \
+ template< typename R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,typename Arg) > \
+ static boost::function< R( BOOST_PP_ENUM_PARAMS(n,Arg) ) > exec \
+ ( \
+ R(Client::*f)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \
+ ) \
+ { \
+ boost::function<R(Client*)>(*p)(R(Client::*)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \
+ BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,Arg)) \
+ = &T2nWrapper::template prep<R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,Arg) >; \
+ return boost::bind \
+ ( \
+ T2nWrapper::template real_exec<R>, \
+ boost::bind( p, f BOOST_PP_COMMA_IF(n) \
+ BOOST_PP_ENUM(n, _GEN_PLACEHOLDER, ~ ) ) \
+ ); \
+ } // eo exec
+
+ BOOST_PP_REPEAT( BOOST_PP_ADD(T2NWRAPPER_MAX_ARGS,1), _GEN_EXEC, ~ )
+
+#undef _GEN_EXEC
+#undef _GEN_PLACEHOLDER
+
+};
+
+}
+#endif