4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief Policy Framework public header
26 \todo We should probably remove BufferingPolicy from the
27 interface, it does not make much sense (how did I come to
30 \todo Do we want to support separate read and write policies. This
31 allows to treat pipes within this framework however, is this
34 \idea Creating a new Socket will create 4 (!) new instances (The
35 handle, the body, the policy and the protocol) of which 3
36 (argh) (body, policy and protocol) live on the heap. This is
37 expensive. We should convert all the policy classes to
38 singletons and assign the same instance to all socket bodies
39 with the same policy. This would reduce the number of heap
40 allocations per socket handle to two.
43 /** \defgroup policy_group The Policy Framework
45 \image html SocketPolicy.png
47 \section policy_group_introduction Introduction to the Policy Framework
49 The policy framework conceptually implements a list of parallel
50 inheritance hierarchies each covering a specific interface aspect
51 of the socket handle. The socket handle itself only provides
52 minimal functionality. All further functionality is relayed to a
53 policy class, or more precisely, to a group of policy classes, one
54 for each policy axis. The policy axis are
57 <dt><em>addressingPolicy</em></dt>
58 <dd>configures, whether a socket is
59 addressable and if so, configures the address type</dd>
61 <dt><em>framingPolicy</em></dt>
62 <dd>configures the type of framing the socket provides: either no
63 framing providing a simple i/o stream or packet framing</dd>
65 <dt><em>communicationPolicy</em></dt>
66 <dd>configures,if and how the communication partner is
69 <dt><em>readPolicy</em></dt>
70 <dd>configures the readability of the socket</dd>
72 <dt><em>writePolicy</em></dt>
73 <dd>configures the writability of the socket</dd>
75 <dt><em>bufferingPolicy</em></dt>
76 <dd>configures, if and how buffering is configured for a socket</dd>
79 Every Policy value is identified by a class type. The policy
80 classes themselves built an inheritance hierarchy for each policy
81 axis. For each policy axis, the root of this tree is the class
82 named \e Policy \c Base (e.g. \p AddressingPolicyBase).
84 The senf::SocketPolicy defines the complete policy of a socket. It
85 combines a set of policy classes, one for each policy
86 axis. Together, they define the behavior of a socket handle. The
87 socket handle instances do not implement any socket functionality
88 themselves instead defering the implementation to the policy
89 classes. The SocketHandle interface is therefore \e not
90 implemented using virtual members, all important socket functions
91 can be inlined by the compiler to create highly efficient code.
93 A SocketPolicy can be incomplete. In this case it does \e not
94 completely specify the socket interface, it leaves some aspects
95 open. A SocketHandle based on such a policy will have a reduced
96 interface: It will only support those members for wich the
97 corresponding policies are defined.
99 Two SocketHandle's with different policies can be \e
100 compatible. If they are, the more derived SocketHandle can be
101 converted (assigned to) the more basic SocketHandle.
103 \section policy_group_details The Policy Framework Classes
105 In the following discussion we will use the following conventions:
106 \li \e Policy is one or \c AddressingPolicy, \c FramingPolicy, \c
107 CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c
109 \li \e socketPolicy is any socket policy (that is, an
110 instantiation of the SocketPolicy template)
111 \li \e trait is an any policy class (that is, any class derived
112 from one of the axis base classes)
114 Each axis is comprised of a number of classes and templates (all
115 in namespace senf of course):
118 <dt>\e Policy \c Base (ex: AddressingPolicyBase)</dt>
119 <dd>Baseclass of all policies in this axis</dd>
121 <dt>\c Unspecified \e Policy (ex: \ref UnspecifiedAddressingPolicy)</dt>
122 <dd>An alias (typedef) for \e Policy \c Base</dd>
124 <dt>\e Policy \c Is < \e socketPolicy, \e trait > (ex: AddressingPolicyIs)</dt>
125 <dd>A template metafunction returning \c boost::true_type, if \e
126 trait (any class derived from \e Policy \c Base) is a compatible
127 policy value of the given \e socketPolicy</dd>
129 <dt>\c If \e Policy \c Is < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIs)</dt>
130 <dd>This is a combination of \e Policy \c Is and \c boost::enable_if</dd>
132 <dt>\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
133 <dd>The inverse of above</dd>
136 These classes form the basis of the policy framework. To bind the
137 policy axis together, there are some more classes and templates.
140 <dt>\c class \c SocketPolicyBase</dt>
141 <dd>This class is the base class of the SocketPolicy template. It
142 is used to validate, that a class is really a SocketPolicy (by
143 checking, that it derives from SocketPolicyBase. This is simpler
144 than chacking the template directly).</dd>
146 <dt>\c template \c SocketPolicy < \e addressingPolicy, \e
147 framingPolicy, \e communicationPolicy, \e readPolicy, \e
148 writePolicy, \e bufferingPolicy ></dt>
149 <dd>This is the central SocketPolicy template. It combines a
150 complete set of policy classes, one for each axis.</dd>
152 <dt>\c template \c MakeSocketPolicy < \e args ></dt>
153 <dd>\c MakeSocketPolicy is a template metafunction which
154 simplifies building SocketPolicy instantiations. It takes any
155 number (ok, up to a maximum of 6) of policy classes as an
156 argument (in any order). It will sort these arguments into the
157 SocketPolicy template arguments. If for some axis no class is
158 specified, it's slot will be filled with \c Unspecified \e
159 Policy. Additionally, the first Argument may optionally be ab
160 arbitrary SocketPolicy. It will provide default values for
161 unspecified axis</dd>
163 <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt>
164 <dd>This template metafunction will check, wether the socket
165 policy \e derived is convertible to \e base. This means, that for
166 each axis, the corresponding policy class in \e derived must be
167 derived or be the same as the one on \e base.</dd>
170 \implementation All these classes are created automatically. The
171 \c SENF_SOCKET_POLICIES makro is a Boost.Preprocessor style
172 sequence listing all policy axis. The Boost.Preprocessor library
173 is then used to generate the respective classes.
175 \section policy_implement Implementing Policy Classes
177 To define a new policy class, derive from the corresponding base
178 class for your policy axies. The only policy axis which might
179 possibly need to be extended are the addressing policy
180 (AddressingPolicyBase) and the buffering policy
181 (BufferingPolicyBase). See the Documentation of these classes for
182 more information on which members can be implemented.
184 All members you define must be static. For any of the policy
185 classes, you must only define those members which are supported by
186 your implementation. If you leave out a member you automatically
187 disable the corresponding functionality in the
188 ClientSocketHandle/ServerSocketHandle interface.
190 The member prototypes given in the base class documentation only
191 specify the call signature not the way, the member must be defined
192 (FileHandle really is not a FileHandle but an arbitrary
195 If the existence of a member depends on other policies, you should
196 use the <code>If</code><i>SomePolicy</i><code>Is</code> and
197 <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to
198 dynamically enable/disable the member depending on some other
202 struct ExampleAddressingPolicy
204 template <class Policy>
205 void connect(senf::SocketHandle<Policy> handle, Address & addr,
206 typename senf::IfCommmunicationPolicyIs<
207 Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
211 The \c connect member in this example will only be enabled, it
212 the communication policy of the socket handle is
213 ConnectedCommunicationPolicy (or a derived type). See <a
214 href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a>
215 for a discussion of the third argument (\c
216 senf::ConnectedCommunicationPolicyIs is based on the \c
217 boost::enable_if template).
219 \see \ref extend_policy \n
220 <a class="ext" href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
221 <a class="ext" href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
222 <a class="ext" href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
224 \idea We could combine all the \e Policy \c Is templates into a
225 single template. Since the \e trait argument will automatically
226 specify the axis to be used, it is not necessary to specify that
227 axis in the tempalte functor's name. We could even combine this
228 with \c SocketPolicyIsBaseOf.
231 #ifndef HH_SocketPolicy_
232 #define HH_SocketPolicy_ 1
236 #include "GenericSockAddr.hh"
238 //#include "SocketPolicy.mpp"
239 ///////////////////////////////hh.p////////////////////////////////////////
243 /// \addtogroup policy_group
246 // This may be adapted to change the supported policies (however,
247 // ClientSocketHandle and ServerSocketHandle will probably have to
248 // be adjusted accordingly)
250 /** \brief List all policy axis
254 This define symbol is used to configure the policy axis. The
255 base class for each of these axis must be defined explicitly
256 (e.g. AddressingPolicyBase). The implementation files will
257 then automatically generate all the other classes from this
262 # define SENF_SOCKET_POLICIES \
265 (CommunicationPolicy) \
270 // Wer define these classes explicitly (and not with some macro
272 // a) AddressingPolicyBase is different from all the others
273 // b) We want to document each one explicitly
275 /** \brief Policy defining socket addressing
277 AddressingPolicyBase is the baseclass of all addressing policy
278 classes. When defining a new addressing policy, the following
279 members can be defined. All methods must be static.
282 <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
283 <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
284 <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
285 <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
286 <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
291 struct AddressingPolicyBase
293 virtual ~AddressingPolicyBase() {}
295 typedef GenericSockAddr Address;
298 /** \brief Policy defining the framing format
300 This policy does not define any operations since it does have
301 no influence on any method signature. It does however affect
302 the semantics of the \c read() and \c write() operations.
304 \note This policy axis probably only has two sensible statess:
305 StreamFramingPolicy and DatagramFramingPolicy.
309 struct FramingPolicyBase
311 virtual ~FramingPolicyBase() {}
314 /** \brief Policy defining, how peers are selected
316 The CommunicationPolicy may define two members:
319 <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
320 <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
323 The \c listen member is straight forward. The \c accept() member
324 must return a new file descriptor (which will be used to
325 create a new SocketHandle of the correct type). Additionally,
326 accept() should only be defined, if the Addressing policy is
327 not \c NoAddressingPolicy (which together with
328 ConnectedCommunicationPolicy would identify a point-to-point
329 link with fixed communication partners).
331 \note This Policy only has two meaningful states:
332 ConnectedCommunicationPolicy and
333 UnconnectedCommunicationPolicy. It is probably not sensible to
334 define a new CommunicationPolicy type.
338 struct CommunicationPolicyBase
340 virtual ~CommunicationPolicyBase() {}
343 /** \brief Policy defining the readability
345 The ReadPolicy defines, wether the socket is readable. It
346 may define two members:
349 <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
350 <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
353 The second member should only be enabled if the communication
354 policy is UnconnectedCommunication (otherwise it does not make
355 sense since the communication partner is fixed) (see
356 AddressingPolicyBase on how to do this).
358 \note This Policy only has two meaningful states:
359 ReadablePolicy and NotReadablePolicy. It probably does not
360 make sense to define new read policy types.
364 struct ReadPolicyBase
366 virtual ~ReadPolicyBase() {}
369 /** \brief Policy defining the writability
371 The WritePolicy defines, wether the socket is writable. It may
375 <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
376 <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
379 The second member should only be enabled if the communication
380 policy is UnconnectedCommunication (otherwise it does not make
381 sense since the communication partner is fixed) (see
382 AddressingPolicyBase on how to do this).
384 \note This Policy only has two meaningful states:
385 WritablePolicy and NotWritablePolicy. It probably does not
386 make sense to define new write policy types.
390 struct WritePolicyBase
392 virtual ~WritePolicyBase() {}
395 /** \brief Policy defining the buffering interface
397 The BufferingPolicy defines the buffer handling of the
398 socket. It may provide the follogin members:
402 struct BufferingPolicyBase
404 virtual ~BufferingPolicyBase() {}
407 // The implementation file will for each Policy declared above
408 // define the following (SomePolicy is one of the above):
410 // struct SomePolicyBase;
411 // typedef UndefinedSomePolicy;
412 // template SomePolicyIs< SocketPolicy, Axis >
413 // template IfSomePolicyIs< SocketPolicy, Axis >
414 // template IfSomePolicyIsNot< SocketPolicy, Axis >
416 // Additionally the following are defined:
418 // class SocketPolicyBase
419 // template SocketPolicy< ..policies.. >
420 // template MakeSocketPolicy< ..args.. >
421 // template SocketPolicyIsBaseOf< Base, Derived >
425 // The following stub definitions are only visible to doxygen
427 /** \brief Alias of AddressingPolicyBase for better readability
428 \see \ref policy_group
430 typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
432 /** \brief Check single policy axis
434 This template is an example of the \i Policy \c Is family of
435 tempalte metafunctions. It will check, wether \c Trait is a
436 valid compatible Policy class of \c SocketPolicy. \c Trait
437 must be derived from AddressingPolicyBase (respectively \i
440 \see \ref policy_group
442 template <class SocketPolicy, class Trait>
443 struct AddressingPolicyIs
446 /** \brief Enable template overload depending on policy value
448 This template is an exmaple of the \c If \i Policy \c Is
449 family of templates. It is used like <a class="ext"
450 href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
451 to enable a templated overload only, if the AddressingPolicy
452 of \i Policy is compatible with \c Trait (that is the
453 AddressingPolicy of \c Policy is derived from \c Trait).
457 template <class SocketPolicy, class Trait>
458 struct IfAddressingPolicyIs
461 /** \brief Inversion of \c IfAddressingPolicyIs
464 template <class SocketPolicy, class Trait>
465 struct IfAddressingPolicyIsNot
468 /** \brief Baseclass of all SocketPolicies
472 This class provides the baseclass of all socket policies
473 (bundles). It serves two purposes:
474 \li It allows us to easily identify a socket policy bundle by
475 checking a classes baseclass.
476 \li It provides an abstract (virtual) interface to access the
481 struct SocketPolicyBase
483 /** \brief Polymorphic access to policy axes
485 This is an example of a policy axes accessor. It returns a
486 reference to the policy axes used by the conrecte protocol
487 bundle. This reference can then be checked using RTTI
490 AddressingPolicyBase const & theAddressingPolicy() const = 0;
493 /** \brief Collection of policy classes
495 The SocketPolicy template defines the complete Policy used by
496 the socket library. It contains one policy class for each
497 policy axis. This template takes one policy from each axis as
498 it's template arguments (this example implementation only has
499 AddressingPolicy as an argument).
501 A SocketPolicy can be complete or incomplete. An incomplete
502 SocketPolicy will have at least one axis set to \c Undefined
503 \i Policy (or a generic derived class which is used to group
504 some other policies but does not (completely) define the
505 policy behavior). A complete SocketPolicy will have a
506 concrete definition of the desired behavior for each policy
511 template < class AddressingPolicy >
514 /** \brief Check dynamic policy compatibility
516 This method will check the socket policy \a other against
517 this policy. It will check, wether \a other is a base
518 policy (or the same) of this policy. This check is done
519 against the \e dynamic type of \a other using RTTI. It
520 will throw \c std::bad_cast, if the policy is not
523 \param[in] other SocketPolicy to check
524 \throws std::bad_cast if \a other is not a compatible
527 static void checkBaseOf(SocketPolicyBase const & other);
530 /** \brief Metafunction to create SocketPolicy
532 This template metafunction simplifies the creation of a
533 SocketPolicy instantiation. It takes any number (that is up to
534 6) of Policy classes as arguments in any Order. It will create
535 a SocketPolicy from these policy classes. Any axis not
536 specified will be left as \c Unspecified \i Policy.
540 template <class Arg1, class Arg2, class ArgN>
541 struct MakeSocketPolicy
544 /** \brief Check policy compatibility
546 This tempalte metafunction checks, wether the SocketPolicy \c
547 Derived is more specialized than \c Base (and therefore a
548 SocketHandle with policy \c Derived is convertible to a
549 SocketHandle with policy \c Base).
551 The metafunction will return true (that is inherits from \c
552 boost::true_type, see the <a class="ext"
553 href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
554 library documentation for more information) if each policy
555 class in \c Base is a baseclass of (or the same as) the
556 corresponding policy class in \c Derived.
560 template <class Base, class Derived>
561 struct SocketPolicyIsBaseOf
569 //////////////////////////////hh.e////////////////////////////////////////
570 #include "SocketPolicy.ih"
571 //#include "SocketPolicy.cci"
572 #include "SocketPolicy.ct"
573 //#include "SocketPolicy.cti"
579 // c-file-style: "senf"