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 /** \defgroup policy_impl_group Policy Implementation classes
232 \ingroup policy_group
234 Here you will find all policy classes. Also included are some
235 supporting classes which are used as base classes to build other
239 #ifndef HH_SocketPolicy_
240 #define HH_SocketPolicy_ 1
244 #include "GenericSockAddr.hh"
246 //#include "SocketPolicy.mpp"
247 ///////////////////////////////hh.p////////////////////////////////////////
251 /// \addtogroup policy_group
254 // This may be adapted to change the supported policies (however,
255 // ClientSocketHandle and ServerSocketHandle will probably have to
256 // be adjusted accordingly)
258 /** \brief List all policy axis
262 This define symbol is used to configure the policy axis. The
263 base class for each of these axis must be defined explicitly
264 (e.g. AddressingPolicyBase). The implementation files will
265 then automatically generate all the other classes from this
270 # define SENF_SOCKET_POLICIES \
273 (CommunicationPolicy) \
278 // Wer define these classes explicitly (and not with some macro
280 // a) AddressingPolicyBase is different from all the others
281 // b) We want to document each one explicitly
283 /** \brief Policy defining socket addressing
285 AddressingPolicyBase is the baseclass of all addressing policy
286 classes. When defining a new addressing policy, the following
287 members can be defined. All methods must be static.
290 <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
291 <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
292 <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
293 <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
294 <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
299 struct AddressingPolicyBase
301 virtual ~AddressingPolicyBase() {}
303 typedef GenericSockAddr Address;
306 /** \brief Policy defining the framing format
308 This policy does not define any operations since it does have
309 no influence on any method signature. It does however affect
310 the semantics of the \c read() and \c write() operations.
312 \note This policy axis probably only has two sensible statess:
313 StreamFramingPolicy and DatagramFramingPolicy.
317 struct FramingPolicyBase
319 virtual ~FramingPolicyBase() {}
322 /** \brief Policy defining, how peers are selected
324 The CommunicationPolicy may define two members:
327 <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
328 <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
331 The \c listen member is straight forward. The \c accept() member
332 must return a new file descriptor (which will be used to
333 create a new SocketHandle of the correct type). Additionally,
334 accept() should only be defined, if the Addressing policy is
335 not \c NoAddressingPolicy (which together with
336 ConnectedCommunicationPolicy would identify a point-to-point
337 link with fixed communication partners).
339 \note This Policy only has two meaningful states:
340 ConnectedCommunicationPolicy and
341 UnconnectedCommunicationPolicy. It is probably not sensible to
342 define a new CommunicationPolicy type.
346 struct CommunicationPolicyBase
348 virtual ~CommunicationPolicyBase() {}
351 /** \brief Policy defining the readability
353 The ReadPolicy defines, wether the socket is readable. It
354 may define two members:
357 <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
358 <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
361 The second member should only be enabled if the communication
362 policy is UnconnectedCommunication (otherwise it does not make
363 sense since the communication partner is fixed) (see
364 AddressingPolicyBase on how to do this).
366 \note This Policy only has two meaningful states:
367 ReadablePolicy and NotReadablePolicy. It probably does not
368 make sense to define new read policy types.
372 struct ReadPolicyBase
374 virtual ~ReadPolicyBase() {}
377 /** \brief Policy defining the writability
379 The WritePolicy defines, wether the socket is writable. It may
383 <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
384 <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
387 The second member should only be enabled if the communication
388 policy is UnconnectedCommunication (otherwise it does not make
389 sense since the communication partner is fixed) (see
390 AddressingPolicyBase on how to do this).
392 \note This Policy only has two meaningful states:
393 WritablePolicy and NotWritablePolicy. It probably does not
394 make sense to define new write policy types.
398 struct WritePolicyBase
400 virtual ~WritePolicyBase() {}
403 /** \brief Policy defining the buffering interface
405 The BufferingPolicy defines the buffer handling of the
406 socket. It may provide the follogin members:
410 struct BufferingPolicyBase
412 virtual ~BufferingPolicyBase() {}
415 // The implementation file will for each Policy declared above
416 // define the following (SomePolicy is one of the above):
418 // struct SomePolicyBase;
419 // typedef UndefinedSomePolicy;
420 // template SomePolicyIs< SocketPolicy, Axis >
421 // template IfSomePolicyIs< SocketPolicy, Axis >
422 // template IfSomePolicyIsNot< SocketPolicy, Axis >
424 // Additionally the following are defined:
426 // class SocketPolicyBase
427 // template SocketPolicy< ..policies.. >
428 // template MakeSocketPolicy< ..args.. >
429 // template SocketPolicyIsBaseOf< Base, Derived >
433 // The following stub definitions are only visible to doxygen
435 /** \brief Alias of AddressingPolicyBase for better readability
436 \see \ref policy_group
438 typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
440 /** \brief Check single policy axis
442 This template is an example of the \e Policy \c Is family of
443 tempalte metafunctions. It will check, wether \c Trait is a
444 valid compatible Policy class of \c SocketPolicy. \c Trait
445 must be derived from AddressingPolicyBase (respectively \i
448 \see \ref policy_group
450 template <class SocketPolicy, class Trait>
451 struct AddressingPolicyIs
454 /** \brief Enable template overload depending on policy value
456 This template is an exmaple of the \c If \e Policy \c Is
457 family of templates. It is used like <a class="ext"
458 href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
459 to enable a templated overload only, if the AddressingPolicy
460 of \e Policy is compatible with \c Trait (that is the
461 AddressingPolicy of \c Policy is derived from \c Trait).
465 template <class SocketPolicy, class Trait>
466 struct IfAddressingPolicyIs
469 /** \brief Inversion of \c IfAddressingPolicyIs
472 template <class SocketPolicy, class Trait>
473 struct IfAddressingPolicyIsNot
476 /** \brief Baseclass of all SocketPolicies
480 This class provides the baseclass of all socket policies
481 (bundles). It serves two purposes:
482 \li It allows us to easily identify a socket policy bundle by
483 checking a classes baseclass.
484 \li It provides an abstract (virtual) interface to access the
489 struct SocketPolicyBase
491 /** \brief Polymorphic access to policy axes
493 This is an example of a policy axes accessor. It returns a
494 reference to the policy axes used by the conrecte protocol
495 bundle. This reference can then be checked using RTTI
498 AddressingPolicyBase const & theAddressingPolicy() const = 0;
501 /** \brief Collection of policy classes
503 The SocketPolicy template defines the complete Policy used by
504 the socket library. It contains one policy class for each
505 policy axis. This template takes one policy from each axis as
506 it's template arguments (this example implementation only has
507 AddressingPolicy as an argument).
509 A SocketPolicy can be complete or incomplete. An incomplete
510 SocketPolicy will have at least one axis set to \c Undefined
511 \e Policy (or a generic derived class which is used to group
512 some other policies but does not (completely) define the
513 policy behavior). A complete SocketPolicy will have a
514 concrete definition of the desired behavior for each policy
519 template < class AddressingPolicy >
522 /** \brief Check dynamic policy compatibility
524 This method will check the socket policy \a other against
525 this policy. It will check, wether \a other is a base
526 policy (or the same) of this policy. This check is done
527 against the \e dynamic type of \a other using RTTI. It
528 will throw \c std::bad_cast, if the policy is not
531 \param[in] other SocketPolicy to check
532 \throws std::bad_cast if \a other is not a compatible
535 static void checkBaseOf(SocketPolicyBase const & other);
538 /** \brief Metafunction to create SocketPolicy
540 This template metafunction simplifies the creation of a
541 SocketPolicy instantiation. It takes any number (that is up to
542 6) of Policy classes as arguments in any Order. It will create
543 a SocketPolicy from these policy classes. Any axis not
544 specified will be left as \c Unspecified \e Policy.
548 template <class Arg1, class Arg2, class ArgN>
549 struct MakeSocketPolicy
552 /** \brief Check policy compatibility
554 This tempalte metafunction checks, wether the SocketPolicy \c
555 Derived is more specialized than \c Base (and therefore a
556 SocketHandle with policy \c Derived is convertible to a
557 SocketHandle with policy \c Base).
559 The metafunction will return true (that is inherits from \c
560 boost::true_type, see the <a class="ext"
561 href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
562 library documentation for more information) if each policy
563 class in \c Base is a baseclass of (or the same as) the
564 corresponding policy class in \c Derived.
568 template <class Base, class Derived>
569 struct SocketPolicyIsBaseOf
577 //////////////////////////////hh.e////////////////////////////////////////
578 #include "SocketPolicy.ih"
579 //#include "SocketPolicy.cci"
580 #include "SocketPolicy.ct"
581 //#include "SocketPolicy.cti"
587 // c-file-style: "senf"