Skip to content
Snippets Groups Projects
Commit 96651a32 authored by g0dil's avatar g0dil
Browse files

Clean up SENFScons.py

Rename macro prefix SATLIB to SENF
Begin socket library documentation
parent d52dae4c
No related branches found
No related tags found
No related merge requests found
File added
...@@ -33,12 +33,43 @@ ...@@ -33,12 +33,43 @@
socket representation. This frees you of having to manage the socket representation. This frees you of having to manage the
socket lifetime explicitly. socket lifetime explicitly.
\section socket_hierarchy The FileHandle hierarchy
\image html FhHierarchy.png
The senf::FileHandle class is the base of a hierarchy of socket
handle classes (realized as templates). These classes provide an
interface to the complete socket API. While going down the
inheritance hierarchy, the interface will be more and more
complete.
The most complete interface is provided by
senf::ProtocolClientSocketHandle and
senf::ProtocolServerSocketHandle. The template Arguments specifies
the Protocol class of the underlying socket type. These are the
\e only classes having public constructors and are therefore the
only classes, which may be created by the library user. You will
normally use these classes by naming a specific socket typedef
(e.g. senf::TCPv4ClientSocketHandle).
However, to aid writing flexible and generic code, the socket
library provides the senf::ClientSocketHandle and
senf::ServerSocketHandle class templates. These templates
implement a family of closely related classes based on the
specification of the socket policy. This policy specification may
be \e incomplete (see below). Instances of
senf::ClientSocketHandle/senf::ServerSocketHandle can be assigned
and converted to different ClientSocketHandle/ServerSocketHandle
types as long as the policy specifications are compatible.
\attention It is very important, to (almost) always pass the socket \attention It is very important, to (almost) always pass the socket
handle <em>by value</em>. The socket handle is a very lightweight handle <em>by value</em>. The socket handle is a very lightweight
class and designed to be used like an ordinary built-in type. This class and designed to be used like an ordinary built-in type. This
is very important in combination with the policy interface. is very important in combination with the policy interface.
\section policy_framework The policy framework \section policy_framework The policy framework
\image html SocketPolicy.png
The policy framework conceptually implements a list of parallel The policy framework conceptually implements a list of parallel
inheritance hierarchies each covering a specific interface aspect inheritance hierarchies each covering a specific interface aspect
...@@ -70,6 +101,42 @@ ...@@ -70,6 +101,42 @@
<dd>configures, if and how buffering is configured for a socket</dd> <dd>configures, if and how buffering is configured for a socket</dd>
</dl> </dl>
Every Policy value is identified by a class type. The policy types
themselves built an inheritance hierarchy for each policy
axis. For each policy axis, the root of this tree is the class
named '<tt>(axis name)Base</tt>' (e.g. \p FramingPolicyBase or \p
CommunicationPolicyBase) which is aliased to '<tt>Unspecified(axis
name)</tt>' (e.g. \p UnspecifiedFramingPolicy or \p
UnspecifiedCommunicationPolicy).
The senf::SocketPolicy template combines a set of policy classes,
one for each policy axis. Together, they define the behavior of a
socket handle. The socket handle instances do net implement any
socket functionality themselves, instead defering the
implementation to the socket classes. The interface is therefore
\e not implemented using virtual members, all important socket
functions can be inlined by the compiler to create highly
efficient code.
Two SocketPolicy instances are considered compatible, if all
policy axis are compatible. A policy axis is compatible, if one
policy class is either the same as the other or derived from
it. Two SocketHandle instances can be converted into each other,
as long as the SocketPolicies are compatible.
\section policy_interface The policy interface
The socket handle classes and templates only implement the most
important socket API methods. To access the complete API, the
protocol interface is provided. Access to the protocol interface
is only possible via senf::ProtocolClientSocketHandle and
senf::ProtocolServerSocketHandle which have the necessary \c
protocol() member. This member returns a reference to the protocol
class instance which contains members covering all the API
function snot found in the SocketHandle interface. The protocol
interface is specific to the protocol. It's implementation is
quite free. Every protocol class will define the complete and
specific socket policy of it's socket handle.
*/ */
/** \page extend Extending the Library /** \page extend Extending the Library
...@@ -77,10 +144,9 @@ ...@@ -77,10 +144,9 @@
/** \page implementation Implementation notes /** \page implementation Implementation notes
\image html "../../SocketLibrary-classes.png" Class hierarchy \image html SocketLibrary-classes.png
*/ */
// Local Variables: // Local Variables:
// mode: c++ // mode: c++
......
...@@ -16,4 +16,6 @@ SENFSCons.Lib(env, ...@@ -16,4 +16,6 @@ SENFSCons.Lib(env,
SENFSCons.Doxygen(env, extra_sources = [ SENFSCons.Doxygen(env, extra_sources = [
env.Dia2Png('SocketLibrary-classes.dia'), env.Dia2Png('SocketLibrary-classes.dia'),
env.Dia2Png('FhHierarchy.dia'),
env.Dia2Png('SocketPolicy.dia'),
]) ])
No preview for this file type
...@@ -32,12 +32,12 @@ ...@@ -32,12 +32,12 @@
#define SP_TemplateArgs(x1,x2,n,SomePolicy) BOOST_PP_COMMA_IF(n) class BOOST_PP_CAT(SomePolicy,_) #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,_) #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 ) > template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SENF_SOCKET_POLICIES ) >
prefix_ void senf::SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParams, , SATLIB_SOCKET_POLICIES ) >:: prefix_ void senf::SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParams, , SENF_SOCKET_POLICIES ) >::
checkBaseOf(SocketPolicyBase const & other) checkBaseOf(SocketPolicyBase const & other)
{ {
# define SP_CheckPolicy(x1,x2,SomePolicy) (void) dynamic_cast<SomePolicy const &>(other.BOOST_PP_CAT(the,SomePolicy)()); # define SP_CheckPolicy(x1,x2,SomePolicy) (void) dynamic_cast<SomePolicy const &>(other.BOOST_PP_CAT(the,SomePolicy)());
BOOST_PP_SEQ_FOR_EACH( SP_CheckPolicy, , SATLIB_SOCKET_POLICIES ) BOOST_PP_SEQ_FOR_EACH( SP_CheckPolicy, , SENF_SOCKET_POLICIES )
# undef SP_CheckPolicy # undef SP_CheckPolicy
} }
......
File added
...@@ -36,7 +36,7 @@ namespace senf { ...@@ -36,7 +36,7 @@ namespace senf {
// be adjusted accordingly). However, AddressingPolicy MUST always // be adjusted accordingly). However, AddressingPolicy MUST always
// be the first Policy member ... // be the first Policy member ...
# define SATLIB_SOCKET_POLICIES \ # define SENF_SOCKET_POLICIES \
(AddressingPolicy) \ (AddressingPolicy) \
(FramingPolicy) \ (FramingPolicy) \
(CommunicationPolicy) \ (CommunicationPolicy) \
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
namespace senf { namespace senf {
# define SATLIB_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SATLIB_SOCKET_POLICIES ) # define SENF_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SENF_SOCKET_POLICIES )
// This REALLY is bad ... but we just need an Address member in // This REALLY is bad ... but we just need an Address member in
// AddressingPolicyBase as long as ClientSocketHandle / // AddressingPolicyBase as long as ClientSocketHandle /
...@@ -72,7 +72,7 @@ namespace senf { ...@@ -72,7 +72,7 @@ namespace senf {
{ virtual ~ BOOST_PP_CAT(SomePolicy,Base) () {} }; \ { virtual ~ BOOST_PP_CAT(SomePolicy,Base) () {} }; \
typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy); typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
BOOST_PP_SEQ_FOR_EACH( SP_DeclareBase, , BOOST_PP_SEQ_POP_FRONT( SATLIB_SOCKET_POLICIES ) ) BOOST_PP_SEQ_FOR_EACH( SP_DeclareBase, , BOOST_PP_SEQ_POP_FRONT( SENF_SOCKET_POLICIES ) )
# undef SP_DeclareBase # undef SP_DeclareBase
...@@ -86,7 +86,7 @@ namespace senf { ...@@ -86,7 +86,7 @@ namespace senf {
virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \ virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \
{ return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); } { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
BOOST_PP_SEQ_FOR_EACH( SP_DeclareTypedef, , SATLIB_SOCKET_POLICIES ) BOOST_PP_SEQ_FOR_EACH( SP_DeclareTypedef, , SENF_SOCKET_POLICIES )
# undef SP_DeclareTypedef # undef SP_DeclareTypedef
}; };
...@@ -95,7 +95,7 @@ namespace senf { ...@@ -95,7 +95,7 @@ namespace senf {
BOOST_PP_COMMA_IF( n ) \ BOOST_PP_COMMA_IF( n ) \
class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base) class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base)
template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SATLIB_SOCKET_POLICIES ) > template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SENF_SOCKET_POLICIES ) >
struct SocketPolicy struct SocketPolicy
: public SocketPolicyBase : public SocketPolicyBase
{ {
...@@ -105,7 +105,7 @@ namespace senf { ...@@ -105,7 +105,7 @@ namespace senf {
BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \ BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \
{ return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); } { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SATLIB_SOCKET_POLICIES ) BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SENF_SOCKET_POLICIES )
# undef SP_DeclarePolicyMember # undef SP_DeclarePolicyMember
static void checkBaseOf(SocketPolicyBase const & other); static void checkBaseOf(SocketPolicyBase const & other);
...@@ -129,15 +129,15 @@ namespace impl { ...@@ -129,15 +129,15 @@ namespace impl {
BOOST_PP_COMMA_IF( m ) \ BOOST_PP_COMMA_IF( m ) \
BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy ) BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
# define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SATLIB_SOCKET_POLICIES_N ) ) # define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SENF_SOCKET_POLICIES_N ) )
# define BOOST_PP_LOCAL_MACRO(n) \ # define BOOST_PP_LOCAL_MACRO(n) \
SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SATLIB_SOCKET_POLICIES ),Base)*); \ SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SENF_SOCKET_POLICIES ),Base)*); \
\ \
template <class Base, class Policy> \ template <class Base, class Policy> \
struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)> \ struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)> \
{ \ { \
typedef SocketPolicy< \ typedef SocketPolicy< \
BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SATLIB_SOCKET_POLICIES ) \ BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SENF_SOCKET_POLICIES ) \
> type; \ > type; \
}; };
...@@ -173,13 +173,13 @@ namespace impl { ...@@ -173,13 +173,13 @@ namespace impl {
template <class Base> template <class Base>
SocketPolicy_rv<1> SocketPolicy_checkcompat_( SocketPolicy_rv<1> SocketPolicy_checkcompat_(
BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) ); BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) );
# undef SP_DeclareArguments # undef SP_DeclareArguments
template <class Base> template <class Base>
SocketPolicy_rv<2> SocketPolicy_checkcompat_( SocketPolicy_rv<2> SocketPolicy_checkcompat_(
BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, void * BOOST_PP_INTERCEPT ) ); BOOST_PP_ENUM_PARAMS( SENF_SOCKET_POLICIES_N, void * BOOST_PP_INTERCEPT ) );
template <int Size> template <int Size>
struct SocketPolicy_checkcompat struct SocketPolicy_checkcompat
...@@ -200,17 +200,17 @@ namespace impl { ...@@ -200,17 +200,17 @@ namespace impl {
struct SocketPolicy_compatibility struct SocketPolicy_compatibility
: public SocketPolicy_checkcompat< sizeof( : public SocketPolicy_checkcompat< sizeof(
SocketPolicy_checkcompat_<Base>( SocketPolicy_checkcompat_<Base>(
BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) )) > BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) )) >
{}; {};
} // namespace impl } // namespace impl
template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SATLIB_SOCKET_POLICIES_N, class T, senf::impl::nil ) > template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_SOCKET_POLICIES_N, class T, senf::impl::nil ) >
class MakeSocketPolicy class MakeSocketPolicy
: public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >, : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >,
impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > >, impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( SENF_SOCKET_POLICIES_N, T ) > >,
impl::MakeSocketPolicy_impl< SocketPolicy<>, impl::MakeSocketPolicy_impl< SocketPolicy<>,
boost::mpl::vector< BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > > >::type boost::mpl::vector< BOOST_PP_ENUM_PARAMS( SENF_SOCKET_POLICIES_N, T ) > > >::type
{}; {};
template <class BasePolicy, class DerivedPolicy> template <class BasePolicy, class DerivedPolicy>
...@@ -237,7 +237,7 @@ namespace impl { ...@@ -237,7 +237,7 @@ namespace impl {
: public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value > \ : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value > \
{}; {};
BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SATLIB_SOCKET_POLICIES ) BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SENF_SOCKET_POLICIES )
# undef SP_DefineConditions # undef SP_DefineConditions
......
...@@ -87,7 +87,7 @@ EXCLUDE_PATTERNS = *.test.cc .* ...@@ -87,7 +87,7 @@ EXCLUDE_PATTERNS = *.test.cc .*
EXAMPLE_PATH = EXAMPLE_PATH =
EXAMPLE_PATTERNS = * EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO EXAMPLE_RECURSIVE = NO
IMAGE_PATH = IMAGE_PATH = .
INPUT_FILTER = INPUT_FILTER =
FILTER_PATTERNS = FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO FILTER_SOURCE_FILES = NO
......
...@@ -113,8 +113,7 @@ def GlobSources(exclude=[]): ...@@ -113,8 +113,7 @@ def GlobSources(exclude=[]):
def StandardTargets(env): def StandardTargets(env):
all = env.Alias('all') all = env.Alias('all')
env.Clean(all, [ '.sconsign', '.sconf_temp', 'config.log', 'ChangeLog.bak', '.clean' env.Clean(all, [ '.sconsign', '.sconf_temp', 'config.log' ])
] + glob.glob("*~"))
env.Depends(all, '.') env.Depends(all, '.')
def GlobalTargets(env): def GlobalTargets(env):
...@@ -151,14 +150,7 @@ def Objects(env, sources, testSources = None, LIBS = []): ...@@ -151,14 +150,7 @@ def Objects(env, sources, testSources = None, LIBS = []):
return objects return objects
def DoxyGlob(exclude=[]): def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []):
sources = [ f
for ext in ("cci", "ct", "cti", "h", "hh", "ih", "mmc", "dox")
for f in glob.glob("*."+ext)
if f not in exclude ]
return sources
def Doxygen(env, doxyfile="Doxyfile", extra_sources = []):
docs = env.Doxygen(doxyfile) docs = env.Doxygen(doxyfile)
# The last target is the (optional) tagfile # The last target is the (optional) tagfile
if os.path.basename(str(docs[-1])) != '.stamp': if os.path.basename(str(docs[-1])) != '.stamp':
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment