diff --git a/Socket/AddressingPolicy.hh b/Socket/AddressingPolicy.hh index d18e1db92109d6ee0286b38a8a8d25d9d7fbcbbe..b13ac1d06b7eab4b5f2de11518bba5461958d53a 100644 --- a/Socket/AddressingPolicy.hh +++ b/Socket/AddressingPolicy.hh @@ -33,9 +33,7 @@ namespace satcom { namespace lib { struct NoAddressingPolicy : public AddressingPolicyBase - { - typedef void Address; - }; + {}; }} diff --git a/Socket/ClientSocketHandle.cti b/Socket/ClientSocketHandle.cti index 757bb0e44f856a996d6a401550119524fe5e4cca..ba107c5ff4f7dc4de48173eb6f0b3a22bb11be9f 100644 --- a/Socket/ClientSocketHandle.cti +++ b/Socket/ClientSocketHandle.cti @@ -25,6 +25,7 @@ //#include "ClientSocketHandle.ih" // Custom includes +#include <typeinfo> #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// @@ -46,7 +47,7 @@ prefix_ satcom::lib::ClientSocketHandle<Policy>::ClientSocketHandle(FileHandle o template <class Policy> prefix_ satcom::lib::ClientSocketHandle<Policy>:: ClientSocketHandle(std::auto_ptr<SocketProtocol> protocol, int fd) - : SocketHandle<Policy>(protocol) + : SocketHandle<Policy>(protocol,false) { this->body().fd(fd); } @@ -189,10 +190,19 @@ template <class Policy> prefix_ satcom::lib::ClientSocketHandle<Policy> satcom::lib::ClientSocketHandle<Policy>::cast_static(FileHandle handle) { - // TODO: Add BOOST_ASSERT return ClientSocketHandle(handle, true); } +template <class Policy> +prefix_ satcom::lib::ClientSocketHandle<Policy> +satcom::lib::ClientSocketHandle<Policy>::cast_dynamic(FileHandle handle) +{ + SocketHandle<Policy> h (SocketHandle<Policy>::cast_dynamic(handle)); + if (static_cast<SocketBody&>(FileHandle::body(h)).isServer()) + throw std::bad_cast(); + return cast_static(handle); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/ClientSocketHandle.hh b/Socket/ClientSocketHandle.hh index 1e0f199f9299b1696281979a01b46eec8056b0e4..e30ac4a5c32a0826e96eebc46a0b2551b7a06c02 100644 --- a/Socket/ClientSocketHandle.hh +++ b/Socket/ClientSocketHandle.hh @@ -121,6 +121,7 @@ namespace lib { ///@} static ClientSocketHandle cast_static(FileHandle handle); + static ClientSocketHandle cast_dynamic(FileHandle handle); protected: ClientSocketHandle(FileHandle other, bool isChecked); diff --git a/Socket/ClientSocketHandle.test.cc b/Socket/ClientSocketHandle.test.cc index 69505645ebd98fc70f038ced813039b8b0a68800..16f2a3c1a1d257378b766679f9b5df6ce7cc1071 100644 --- a/Socket/ClientSocketHandle.test.cc +++ b/Socket/ClientSocketHandle.test.cc @@ -29,6 +29,7 @@ #include "SocketPolicy.test.hh" #include "SocketProtocol.test.hh" #include "ClientSocketHandle.hh" +#include "AddressingPolicy.hh" #include <boost/test/auto_unit_test.hpp> #include <boost/test/test_tools.hpp> @@ -69,6 +70,14 @@ BOOST_AUTO_UNIT_TEST(clientSocketHandle) typedef sl::ClientSocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle; SomeSocketHandle ssh = sl::static_socket_cast<SomeSocketHandle>(osh); + + BOOST_CHECK_NO_THROW( sl::dynamic_socket_cast<SomeSocketHandle>(osh) ); + typedef sl::ClientSocketHandle<sl::MakeSocketPolicy< + OtherSocketPolicy, + sl::NoAddressingPolicy + >::policy> SomeOtherSocketHandle; + BOOST_CHECK_THROW( sl::dynamic_socket_cast<SomeOtherSocketHandle>(osh), + std::bad_cast ); } // reading and writing diff --git a/Socket/FileHandle.cci b/Socket/FileHandle.cci index 63ca57b15a2ff87412ec233421351c4f6d1fa543..84250fa9170c4ea2219b17a0808366b086659535 100644 --- a/Socket/FileHandle.cci +++ b/Socket/FileHandle.cci @@ -205,6 +205,17 @@ prefix_ satcom::lib::FileBody const & satcom::lib::FileHandle::body() return *body_; } +prefix_ satcom::lib::FileBody & satcom::lib::FileHandle::body(FileHandle & handle) +{ + return handle.body(); +} + +prefix_ satcom::lib::FileBody const & +satcom::lib::FileHandle::body(FileHandle const & handle) +{ + return handle.body(); +} + prefix_ void satcom::lib::FileHandle::fd(int fd) { body().fd(fd); @@ -216,6 +227,12 @@ satcom::lib::FileHandle::cast_static(FileHandle handle) return handle; } +prefix_ satcom::lib::FileHandle +satcom::lib::FileHandle::cast_dynamic(FileHandle handle) +{ + return handle; +} + ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/FileHandle.hh b/Socket/FileHandle.hh index 85b95824912f37fa1dd2a239c556de98f58177b3..10c69c7fc964df0cd8f48e29cfeeb130162c1ae6 100644 --- a/Socket/FileHandle.hh +++ b/Socket/FileHandle.hh @@ -75,12 +75,15 @@ namespace lib { int fd() const; static FileHandle cast_static(FileHandle handle); + static FileHandle cast_dynamic(FileHandle handle); protected: explicit FileHandle(std::auto_ptr<FileBody> body); FileBody & body(); FileBody const & body() const; + static FileBody & body(FileHandle & handle); + static FileBody const & body(FileHandle const & handle); void fd(int fd); diff --git a/Socket/ProtocolClientSocketHandle.cti b/Socket/ProtocolClientSocketHandle.cti index 30a2d81bdfe4c5c6ffa4ac506eae810e16b4ca25..a88accada46eef47de5f7b0649bf7cfc895133fb 100644 --- a/Socket/ProtocolClientSocketHandle.cti +++ b/Socket/ProtocolClientSocketHandle.cti @@ -58,10 +58,20 @@ template <class SocketProtocol> prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol> satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::cast_static(FileHandle handle) { - // TODO: Add BOOST_ASSERT return ProtocolClientSocketHandle(handle,true); } +template <class SocketProtocol> +prefix_ satcom::lib::ProtocolClientSocketHandle<SocketProtocol> +satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::cast_dynamic(FileHandle handle) +{ + ClientSocketHandle<typename SocketProtocol::Policy> h( + ClientSocketHandle<typename SocketProtocol::Policy>::cast_dynamic(handle)); + // throw std::bad_cast if the protocol is invalid + dynamic_cast<SocketProtocol const &>(static_cast<SocketBody&>(FileHandle::body(h)).protocol()); + return cast_static(handle); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/ProtocolClientSocketHandle.hh b/Socket/ProtocolClientSocketHandle.hh index e9a7160d85bb606db19ae0ebc5a1108effa1833a..cf7ccc136666ae29d09d6d3453542e14371eb0f7 100644 --- a/Socket/ProtocolClientSocketHandle.hh +++ b/Socket/ProtocolClientSocketHandle.hh @@ -61,6 +61,7 @@ namespace lib { Protocol const & protocol(); static ProtocolClientSocketHandle cast_static(FileHandle handle); + static ProtocolClientSocketHandle cast_dynamic(FileHandle handle); protected: ProtocolClientSocketHandle(FileHandle other, bool isChecked); diff --git a/Socket/ProtocolServerSocketHandle.cti b/Socket/ProtocolServerSocketHandle.cti index bf138703214a4a70679cb797c6192777c3de4173..1ab9e71da1b58a85e07b5c05ae2987e12039df92 100644 --- a/Socket/ProtocolServerSocketHandle.cti +++ b/Socket/ProtocolServerSocketHandle.cti @@ -59,10 +59,20 @@ template <class SocketProtocol> prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol> satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::cast_static(FileHandle handle) { - // TODO: Add BOOST_ASSERT return ProtocolServerSocketHandle(handle,true); } +template <class SocketProtocol> +prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol> +satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::cast_dynamic(FileHandle handle) +{ + ServerSocketHandle<typename SocketProtocol::Policy> h( + ServerSocketHandle<typename SocketProtocol::Policy>::cast_dynamic(handle)); + // throw std::bad_cast if the protocol is invalid + dynamic_cast<SocketProtocol const &>(static_cast<SocketBody&>(FileHandle::body(h)).protocol()); + return cast_static(handle); +} + template <class SocketProtocol> prefix_ satcom::lib::ProtocolServerSocketHandle<SocketProtocol>:: ProtocolServerSocketHandle(FileHandle other, bool isChecked) diff --git a/Socket/ProtocolServerSocketHandle.hh b/Socket/ProtocolServerSocketHandle.hh index d02a18d657d22d5f808f1ae18282dbc154fa4618..a14ecf22ab2e3b1979b2bb9b00bc0d44d7f4624b 100644 --- a/Socket/ProtocolServerSocketHandle.hh +++ b/Socket/ProtocolServerSocketHandle.hh @@ -63,6 +63,7 @@ namespace lib { ProtocolClientSocketHandle<SocketProtocol> accept(); static ProtocolServerSocketHandle cast_static(FileHandle handle); + static ProtocolServerSocketHandle cast_dynamic(FileHandle handle); protected: ProtocolServerSocketHandle(FileHandle other, bool isChecked); diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti index c4018343daaa43d44ff7194ba379162f6ddfa9eb..add971bde991b5a3de0a9a3f588fb83a3bcf6bd3 100644 --- a/Socket/ServerSocketHandle.cti +++ b/Socket/ServerSocketHandle.cti @@ -25,6 +25,7 @@ //#include "ServerSocketHandle.ih" // Custom includes +#include <typeinfo> #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// @@ -40,7 +41,7 @@ ServerSocketHandle(ServerSocketHandle<OtherPolicy> other, template <class SocketPolicy> prefix_ satcom::lib::ServerSocketHandle<SocketPolicy>:: ServerSocketHandle(std::auto_ptr<SocketProtocol> protocol) - : SocketHandle<SocketPolicy>(protocol) + : SocketHandle<SocketPolicy>(protocol,true) {} template <class SocketPolicy> @@ -115,10 +116,19 @@ template <class Policy> prefix_ satcom::lib::ServerSocketHandle<Policy> satcom::lib::ServerSocketHandle<Policy>::cast_static(FileHandle handle) { - // TODO: Add BOOST_ASSERT return ServerSocketHandle(handle,true); } +template <class Policy> +prefix_ satcom::lib::ServerSocketHandle<Policy> +satcom::lib::ServerSocketHandle<Policy>::cast_dynamic(FileHandle handle) +{ + SocketHandle<Policy> h (SocketHandle<Policy>::cast_dynamic(handle)); + if (! static_cast<SocketBody&>(FileHandle::body(handle)).isServer()) + throw std::bad_cast(); + return cast_static(handle); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/ServerSocketHandle.hh b/Socket/ServerSocketHandle.hh index 22425cd3ad0f9d0885c1777b4f3823b9d57d5922..ade54cecf8623859adfc3c61b7055cf5bc55c1be 100644 --- a/Socket/ServerSocketHandle.hh +++ b/Socket/ServerSocketHandle.hh @@ -92,6 +92,7 @@ namespace lib { ///@} static ServerSocketHandle cast_static(FileHandle handle); + static ServerSocketHandle cast_dynamic(FileHandle handle); protected: ServerSocketHandle(FileHandle other, bool isChecked); diff --git a/Socket/ServerSocketHandle.test.cc b/Socket/ServerSocketHandle.test.cc index 579f35c78e21e4cc4a34320e3ac02ad2857c49db..299524f8a971290bbc02898aaedef3cdf9e129bb 100644 --- a/Socket/ServerSocketHandle.test.cc +++ b/Socket/ServerSocketHandle.test.cc @@ -29,6 +29,7 @@ #include "ServerSocketHandle.hh" #include "ClientSocketHandle.hh" #include "SocketProtocol.test.hh" +#include "AddressingPolicy.hh" #include <boost/test/auto_unit_test.hpp> #include <boost/test/test_tools.hpp> @@ -67,6 +68,18 @@ BOOST_AUTO_UNIT_TEST(serverSocketHandle) typedef sl::ServerSocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle; SomeSocketHandle ssh = sl::static_socket_cast<SomeSocketHandle>(osh); + typedef sl::ServerSocketHandle<sl::MakeSocketPolicy< + OtherSocketPolicy, + satcom::lib::NoAddressingPolicy + >::policy> SomeOtherSocketHandle; + typedef sl::ClientSocketHandle<OtherSocketPolicy> OtherClientHandle; + + BOOST_CHECK_NO_THROW( sl::dynamic_socket_cast<SomeSocketHandle>(osh) ); + BOOST_CHECK_THROW( sl::dynamic_socket_cast<SomeOtherSocketHandle>(osh), + std::bad_cast ); + BOOST_CHECK_THROW( sl::dynamic_socket_cast<OtherClientHandle>(osh), + std::bad_cast ); + BOOST_CHECK_NO_THROW( myh.bind(0) ); BOOST_CHECK_EQUAL( myh.local(), 2u ); diff --git a/Socket/SocketHandle.cci b/Socket/SocketHandle.cci index db18a754b0d0b37c33f5ba411ac10a08e606ba38..34c6b5da98a70e209ab3e25a8939b3af047652de 100644 --- a/Socket/SocketHandle.cci +++ b/Socket/SocketHandle.cci @@ -30,15 +30,17 @@ #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// -prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol) - : protocol_(protocol) +prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol, + bool isServer) + : protocol_(protocol), isServer_(isServer) { BOOST_ASSERT( ! protocol_->body_ ); protocol_->body_ = this; } -prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol, int fd) - : FileBody(fd), protocol_(protocol) +prefix_ satcom::lib::SocketBody::SocketBody(std::auto_ptr<SocketProtocol> protocol, + bool isServer, int fd) + : FileBody(fd), protocol_(protocol), isServer_(isServer) { BOOST_ASSERT( ! protocol_->body_ ); protocol_->body_ = this; @@ -50,6 +52,11 @@ prefix_ satcom::lib::SocketProtocol const & satcom::lib::SocketBody::protocol() return *protocol_; } +prefix_ bool satcom::lib::SocketBody::isServer() +{ + return isServer_; +} + ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/SocketHandle.cti b/Socket/SocketHandle.cti index 8a4857865bf1dbce0427f27dfc582b206d38c781..bd154e8072d08961d214206fa214c91a74eb8193 100644 --- a/Socket/SocketHandle.cti +++ b/Socket/SocketHandle.cti @@ -25,6 +25,7 @@ #include "SocketHandle.ih" // Custom includes +#include <typeinfo> #define prefix_ inline ///////////////////////////////cti.p/////////////////////////////////////// @@ -47,8 +48,9 @@ satcom::lib::SocketHandle<SocketPolicy>::operator=(SocketHandle<OtherPolicy> oth template <class SocketPolicy> prefix_ -satcom::lib::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtocol> protocol) - : FileHandle(std::auto_ptr<FileBody>(new SocketBody(protocol))) +satcom::lib::SocketHandle<SocketPolicy>::SocketHandle(std::auto_ptr<SocketProtocol> protocol, + bool isServer) + : FileHandle(std::auto_ptr<FileBody>(new SocketBody(protocol,isServer))) {} template <class SocketPolicy> @@ -91,10 +93,20 @@ template <class SocketPolicy> prefix_ satcom::lib::SocketHandle<SocketPolicy> satcom::lib::SocketHandle<SocketPolicy>::cast_static(FileHandle handle) { - // TODO: Add BOOST_ASSERT return SocketHandle(handle,true); } +template <class SocketPolicy> +prefix_ satcom::lib::SocketHandle<SocketPolicy> +satcom::lib::SocketHandle<SocketPolicy>::cast_dynamic(FileHandle handle) +{ + // throws bad_cast if the body is not a SocketBody + SocketBody & body (dynamic_cast<SocketBody&>(FileHandle::body(handle))); + // throws bad_cast if the poplicy is not compatible + SocketPolicy::checkBaseOf(body.protocol().policy()); + return cast_static(handle); +} + template <class Target, class Source> prefix_ Target satcom::lib::static_socket_cast(Source handle) { @@ -103,9 +115,44 @@ prefix_ Target satcom::lib::static_socket_cast(Source handle) boost::is_convertible<Target*,FileHandle*>::value && ( boost::is_convertible<Source,Target>::value || boost::is_convertible<Target,Source>::value ) )); + BOOST_ASSERT( check_socket_cast<Target>(handle) ); return Target::cast_static(handle); } +template <class Target, class Source> +prefix_ Target satcom::lib::dynamic_socket_cast(Source handle) +{ + BOOST_STATIC_ASSERT(( + boost::is_convertible<Source*,FileHandle*>::value && + boost::is_convertible<Target*,FileHandle*>::value && + ( boost::is_convertible<Source,Target>::value || + boost::is_convertible<Target,Source>::value ) )); + return Target::cast_dynamic(handle); +} + +template <class Target, class Source> +prefix_ bool satcom::lib::check_socket_cast(Source handle) +{ + BOOST_STATIC_ASSERT(( + boost::is_convertible<Source*,FileHandle*>::value && + boost::is_convertible<Target*,FileHandle*>::value && + ( boost::is_convertible<Source,Target>::value || + boost::is_convertible<Target,Source>::value ) )); + // we don't have a non-throwing variant of cast_dynamic + // for two reasons: + // a) since the handle is passed back by value, we cannot return + // something like a null handle + // b) it is simpler to implement cast_dynamic throwig bad_cast on + // failure than implementing cast_check + try { + Target::cast_dynamic(handle); + } + catch (std::bad_cast const &) { + return false; + } + return true; +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/SocketHandle.hh b/Socket/SocketHandle.hh index 153e58e25d780916c3247da3f59d99e97e919201..ea0ba928daebb3f56dc5227879d4f7c81b6ddaef 100644 --- a/Socket/SocketHandle.hh +++ b/Socket/SocketHandle.hh @@ -73,9 +73,10 @@ namespace lib { typename IsCompatible<OtherPolicy>::type const & operator=(SocketHandle<OtherPolicy> other); static SocketHandle cast_static(FileHandle handle); - + static SocketHandle cast_dynamic(FileHandle handle); + protected: - explicit SocketHandle(std::auto_ptr<SocketProtocol> protocol); + explicit SocketHandle(std::auto_ptr<SocketProtocol> protocol, bool isServer); SocketHandle(FileHandle other, bool isChecked); SocketBody & body(); @@ -90,6 +91,12 @@ namespace lib { template <class Target, class Source> Target static_socket_cast(Source handle); + + template <class Target, class Source> + Target dynamic_socket_cast(Source handle); + + template <class Target, class Source> + bool check_socket_cast(Source handle); }} ///////////////////////////////hh.e//////////////////////////////////////// diff --git a/Socket/SocketHandle.ih b/Socket/SocketHandle.ih index 103897bb781a3b9eee2dffc119c834b634dd2d4b..2b5f0fb7eb08c28bc19cbd15884050d2a7015d3e 100644 --- a/Socket/SocketHandle.ih +++ b/Socket/SocketHandle.ih @@ -47,8 +47,8 @@ namespace lib { ///\name Structors and default members ///@{ - explicit SocketBody(std::auto_ptr<SocketProtocol> protocol); - SocketBody(std::auto_ptr<SocketProtocol> protocol, int fd); + explicit SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer); + SocketBody(std::auto_ptr<SocketProtocol> protocol, bool isServer, int fd); // no copy // no conversion constructors @@ -57,6 +57,7 @@ namespace lib { /////////////////////////////////////////////////////////////////////////// SocketProtocol const & protocol() const; + bool isServer(); private: virtual void v_close(); @@ -64,6 +65,7 @@ namespace lib { virtual bool v_eof() const; boost::scoped_ptr<SocketProtocol> protocol_; + bool isServer_; }; }} diff --git a/Socket/SocketHandle.test.cc b/Socket/SocketHandle.test.cc index 4f7c90c677d8df4b669bdb05bdcdba36c5dde0e5..c0e40cfd512ed03adf2c6ec388600d6707682989 100644 --- a/Socket/SocketHandle.test.cc +++ b/Socket/SocketHandle.test.cc @@ -28,6 +28,7 @@ // Custom includes #include "SocketHandle.hh" #include "SocketProtocol.test.hh" +#include "AddressingPolicy.hh" #include <boost/test/auto_unit_test.hpp> #include <boost/test/test_tools.hpp> @@ -43,9 +44,19 @@ namespace { { public: MySocketHandle() - : sl::SocketHandle<sl::test::SomeProtocol::Policy>(std::auto_ptr<sl::SocketProtocol>(new sl::test::SomeProtocol())) + : sl::SocketHandle<sl::test::SomeProtocol::Policy>( + std::auto_ptr<sl::SocketProtocol>(new sl::test::SomeProtocol()),false) {} }; + + class FDHandle + : public satcom::lib::FileHandle + { + public: + FDHandle() + : satcom::lib::FileHandle(std::auto_ptr<satcom::lib::FileBody>( + new satcom::lib::FileBody())) {} + }; } BOOST_AUTO_UNIT_TEST(socketHandle) @@ -59,8 +70,22 @@ BOOST_AUTO_UNIT_TEST(socketHandle) MySocketHandle myh; OtherSocketHandle osh (myh); osh = myh; + typedef sl::SocketHandle<sl::test::SomeProtocol::Policy> SomeSocketHandle; SomeSocketHandle ssh = satcom::lib::static_socket_cast<SomeSocketHandle>(osh); + + BOOST_CHECK_NO_THROW( satcom::lib::dynamic_socket_cast<SomeSocketHandle>(osh) ); + + typedef sl::SocketHandle< sl::MakeSocketPolicy< + OtherSocketPolicy, + satcom::lib::NoAddressingPolicy + >::policy> SomeOtherSocketHandle; + + BOOST_CHECK_THROW( satcom::lib::dynamic_socket_cast<SomeOtherSocketHandle>(osh), + std::bad_cast ); + BOOST_CHECK_THROW( satcom::lib::dynamic_socket_cast<SomeSocketHandle>( + satcom::lib::FileHandle(FDHandle())), + std::bad_cast ); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/SocketPolicy.ct b/Socket/SocketPolicy.ct new file mode 100644 index 0000000000000000000000000000000000000000..b2b29448fad78559ee148c8ffd5063fdb20b89eb --- /dev/null +++ b/Socket/SocketPolicy.ct @@ -0,0 +1,54 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU 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. + +// Definition of non-inline template functions + +#include "SocketPolicy.ih" + +// Custom includes + +#define prefix_ +///////////////////////////////ct.p//////////////////////////////////////// + +#define SP_TemplateArgs(x1,x2,n,SomePolicy) BOOST_PP_COMMA_IF(n) class BOOST_PP_CAT(SomePolicy,_) +#define SP_TemplateParams(x1,x2,n,SomePolicy) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(SomePolicy,_) + +template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SATLIB_SOCKET_POLICIES ) > +prefix_ void satcom::lib::SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParams, , SATLIB_SOCKET_POLICIES ) >:: +checkBaseOf(SocketPolicyBase const & other) +{ +# define SP_CheckPolicy(x1,x2,SomePolicy) dynamic_cast<SomePolicy const &>(other.BOOST_PP_CAT(the,SomePolicy)()); + BOOST_PP_SEQ_FOR_EACH( SP_CheckPolicy, , SATLIB_SOCKET_POLICIES ) +# undef SP_CheckPolicy +} + +#undef SP_TemplateArgs +#undef SP_TemplateParams + +///////////////////////////////ct.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/SocketPolicy.hh b/Socket/SocketPolicy.hh index 07c2739fbab7d41cc3d717102ac59559ebd21b9d..a2a0c05ea1445cdf2819bdfdfed6fb08c648cd20 100644 --- a/Socket/SocketPolicy.hh +++ b/Socket/SocketPolicy.hh @@ -31,7 +31,12 @@ namespace satcom { namespace lib { -# define SATCOM_LIB_SocketPolicy_Policies \ + // This may be adapted to change the supported policies (however, + // ClientSocketHandle and ServerSocketHandle will probably have to + // be adjusted accordingly). However, AddressingPolicy MUST always + // be the first Policy member ... + +# define SATLIB_SOCKET_POLICIES \ (AddressingPolicy) \ (FramingPolicy) \ (CommunicationPolicy) \ @@ -54,13 +59,12 @@ namespace lib { // template SocketPolicy< ..policies.. > // template MakeSocketPolicy< ..args.. > // template SocketPolicyIsBaseOf< Base, Derived > - }} //////////////////////////////hh.e//////////////////////////////////////// #include "SocketPolicy.ih" //#include "SocketPolicy.cci" -//#include "SocketPolicy.ct" +#include "SocketPolicy.ct" //#include "SocketPolicy.cti" #endif diff --git a/Socket/SocketPolicy.ih b/Socket/SocketPolicy.ih index e3c2696a9267357c52c28d72aec01d923aed4b2c..58fcba342ecf2b651e734980d19bb760798e1040 100644 --- a/Socket/SocketPolicy.ih +++ b/Socket/SocketPolicy.ih @@ -27,6 +27,7 @@ #include <boost/preprocessor/seq/for_each.hpp> #include <boost/preprocessor/seq/for_each_i.hpp> #include <boost/preprocessor/seq/size.hpp> +#include <boost/preprocessor/seq/pop_front.hpp> #include <boost/preprocessor/punctuation/comma_if.hpp> #include <boost/preprocessor/repetition/enum_params.hpp> #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> @@ -50,39 +51,66 @@ namespace satcom { namespace lib { -# define SP_DeclareBase(x1,x2,SomePolicy) \ +# define SATLIB_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SATLIB_SOCKET_POLICIES ) + + // This REALLY is bad ... but we just need an Address member in + // AddressingPolicyBase as long as ClientSocketHandle / + // ServerSocketHandle don't make use of enable_if for each and + // every member they define ... + + struct AddressingPolicyBase + { + virtual ~ AddressingPolicyBase() {} + + class Address + { + private: + Address(); + }; + }; + +# define SP_DeclareBase(x1,x2,SomePolicy) \ struct BOOST_PP_CAT(SomePolicy,Base) \ { virtual ~ BOOST_PP_CAT(SomePolicy,Base) () {} }; \ typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy); - BOOST_PP_SEQ_FOR_EACH( SP_DeclareBase, nix, SATCOM_LIB_SocketPolicy_Policies ) + BOOST_PP_SEQ_FOR_EACH( SP_DeclareBase, , BOOST_PP_SEQ_POP_FRONT( SATLIB_SOCKET_POLICIES ) ) # undef SP_DeclareBase struct SocketPolicyBase { -# define SP_DeclareTypedef(x1,x2,SomePolicy) \ - typedef BOOST_PP_CAT(SomePolicy,Base) SomePolicy; + virtual ~SocketPolicyBase() {} - BOOST_PP_SEQ_FOR_EACH( SP_DeclareTypedef, nix, SATCOM_LIB_SocketPolicy_Policies ) +# define SP_DeclareTypedef(x1,x2,SomePolicy) \ + typedef BOOST_PP_CAT(SomePolicy,Base) SomePolicy; \ + BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); \ + virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \ + { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); } + + BOOST_PP_SEQ_FOR_EACH( SP_DeclareTypedef, , SATLIB_SOCKET_POLICIES ) # undef SP_DeclareTypedef }; -# define SP_TemplateArgs(x1,x2,n,SomePolicy) \ - BOOST_PP_COMMA_IF( n ) \ +# define SP_TemplateArgs(x1,x2,n,SomePolicy) \ + BOOST_PP_COMMA_IF( n ) \ class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base) - template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, nix, SATCOM_LIB_SocketPolicy_Policies ) > + template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SATLIB_SOCKET_POLICIES ) > struct SocketPolicy : public SocketPolicyBase { -# define SP_DeclarePolicyMember(x1,x2,SomePolicy) \ - typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy; \ - SomePolicy BOOST_PP_CAT(the,SomePolicy); +# define SP_DeclarePolicyMember(x1,x2,SomePolicy) \ + typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy; \ + SomePolicy BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); \ + BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \ + { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); } - BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SATCOM_LIB_SocketPolicy_Policies ) + BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SATLIB_SOCKET_POLICIES ) # undef SP_DeclarePolicyMember + + static void checkBaseOf(SocketPolicyBase const & other); }; # undef SP_TemplateArgs @@ -99,20 +127,20 @@ namespace impl { struct MakeSocketPolicy_merge {}; -# define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy) \ - BOOST_PP_COMMA_IF( m ) \ +# define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy) \ + BOOST_PP_COMMA_IF( m ) \ BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy ) -# define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ) ) ) -# define BOOST_PP_LOCAL_MACRO(n) \ - SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SATCOM_LIB_SocketPolicy_Policies ),Base)*); \ - \ - template <class Base, class Policy> \ - struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)> \ - { \ - typedef SocketPolicy< \ - BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SATCOM_LIB_SocketPolicy_Policies ) \ - > type; \ +# define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SATLIB_SOCKET_POLICIES_N ) ) +# define BOOST_PP_LOCAL_MACRO(n) \ + SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SATLIB_SOCKET_POLICIES ),Base)*); \ + \ + template <class Base, class Policy> \ + struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)> \ + { \ + typedef SocketPolicy< \ + BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SATLIB_SOCKET_POLICIES ) \ + > type; \ }; # include BOOST_PP_LOCAL_ITERATE() @@ -141,19 +169,19 @@ namespace impl { typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy; }; -# define SP_DeclareArguments(x1,x2,n,SomePolicy) \ - BOOST_PP_COMMA_IF( n ) \ +# define SP_DeclareArguments(x1,x2,n,SomePolicy) \ + BOOST_PP_COMMA_IF( n ) \ typename Base::SomePolicy * template <class Base> SocketPolicy_rv<1> SocketPolicy_checkcompat_( - BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, nix, SATCOM_LIB_SocketPolicy_Policies ) ); + BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) ); # undef SP_DeclareArguments template <class Base> SocketPolicy_rv<2> SocketPolicy_checkcompat_( - BOOST_PP_ENUM_PARAMS( BOOST_PP_SEQ_SIZE(SATCOM_LIB_SocketPolicy_Policies), void * BOOST_PP_INTERCEPT ) ); + BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, void * BOOST_PP_INTERCEPT ) ); template <int Size> struct SocketPolicy_checkcompat @@ -166,25 +194,25 @@ namespace impl { {}; -# define SP_DeclareArguments(x1,x2,n,SomePolicy) \ - BOOST_PP_COMMA_IF( n ) \ +# define SP_DeclareArguments(x1,x2,n,SomePolicy) \ + BOOST_PP_COMMA_IF( n ) \ static_cast<typename Derived::SomePolicy *>(0) template <class Base, class Derived> struct SocketPolicy_compatibility : public SocketPolicy_checkcompat< sizeof( SocketPolicy_checkcompat_<Base>( - BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, nix, SATCOM_LIB_SocketPolicy_Policies ) )) > + BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) )) > {}; } // namespace impl - template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ), class T, satcom::lib::impl::nil ) > + template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SATLIB_SOCKET_POLICIES_N, class T, satcom::lib::impl::nil ) > class MakeSocketPolicy : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >, - impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ), T ) > >, + impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > >, impl::MakeSocketPolicy_impl< SocketPolicy<>, - boost::mpl::vector< BOOST_PP_ENUM_PARAMS( BOOST_PP_SEQ_SIZE( SATCOM_LIB_SocketPolicy_Policies ), T ) > > >::type + boost::mpl::vector< BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > > >::type {}; template <class BasePolicy, class DerivedPolicy> @@ -195,7 +223,7 @@ namespace impl { boost::false_type >::type {}; -# define SP_DefineConditions(x1,x2,SomePolicy) \ +# define SP_DefineConditions(x1,x2,SomePolicy) \ template <class Policy, class Trait> \ struct BOOST_PP_CAT(SomePolicy,Is) \ : public boost::is_convertible< typename Policy::SomePolicy*, Trait* > \ @@ -211,7 +239,7 @@ namespace impl { : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value > \ {}; - BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, nix, SATCOM_LIB_SocketPolicy_Policies ) + BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SATLIB_SOCKET_POLICIES ) # undef SP_DefineConditions diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh index 4d1a9d58fa8c0e2d651f4b70606a39eb264284a4..4f9c24f84f54fc0e693a1dde2673e6a27e43fd75 100644 --- a/Socket/SocketProtocol.hh +++ b/Socket/SocketProtocol.hh @@ -34,6 +34,7 @@ namespace lib { class SocketBody; class FileHandle; + class SocketPolicyBase; /** \brief */ @@ -59,7 +60,8 @@ namespace lib { /////////////////////////////////////////////////////////////////////////// SocketBody & body() const; - + virtual SocketPolicyBase const & policy() const = 0; + /////////////////////////////////////////////////////////////////////////// // Virtual interface