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 In a concrete policy, each of these policy axis is assigned a value,
80 the policy value. This value is identified by a class type. For example,
81 possible values for <em>framingPolicy</em> are <tt>DatagramFramingPolicy</tt>
82 or <tt>StreamFramingPolicy</tt> which are classes derived from the axis
83 base class <tt>FramingPolicyBase</tt>. This base class doubles as
84 <tt>UnspecifiedFramingPolicy</tt> (which is just a typedef alias).
85 If a policy axis is assigned this Unspecified type, the axis is left
86 unspecified, the policy will be incomplete.
88 The senf::SocketPolicy tempalte defines the complete policy of a socket. It
89 combines a set of policy classes, one for each policy
90 axis as described above. Together, they define the behavior of a socket handle. The
91 socket handle instances do not implement any socket functionality
92 themselves instead defering the implementation to the policy
93 classes. The SocketHandle interface is therefore \e not
94 implemented using virtual members, all important socket functions
95 can be inlined by the compiler to create highly efficient code.
97 A SocketPolicy can be incomplete. In this case it does \e not
98 completely specify the socket interface, it leaves some aspects
99 open. A SocketHandle based on such a policy will have a reduced
100 interface: It will only support those members for wich the
101 corresponding policies are defined.
103 Two SocketHandle's with different policies can be \e
104 compatible. If they are, the more derived SocketHandle can be
105 converted (assigned to) the more basic SocketHandle.
107 \doc Example (concrete policy, incomplete policy, compatibility/assignment)
109 \section policy_group_details The Policy Framework Classes
111 \doc Policy should be Axis here. Make clear, that this information is only
112 needed when extending the library.
114 In the following discussion we will use the following conventions:
115 \li \e Policy is one or \c AddressingPolicy, \c FramingPolicy, \c
116 CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c
118 \li \e socketPolicy is any socket policy (that is, an
119 instantiation of the SocketPolicy template)
120 \li \e trait is an any policy class (that is, any class derived
121 from one of the axis base classes)
123 Each axis is comprised of a number of classes and templates (all
124 in namespace senf of course):
127 <dt>\e Policy \c Base (ex: AddressingPolicyBase)</dt>
128 <dd>Baseclass of all policies in this axis</dd>
130 <dt>\c Unspecified \e Policy (ex: \ref UnspecifiedAddressingPolicy)</dt>
131 <dd>An alias (typedef) for \e Policy \c Base</dd>
133 <dt>\e Policy \c Is < \e socketPolicy, \e trait > (ex: AddressingPolicyIs)</dt>
134 <dd>A template metafunction returning \c boost::true_type, if \e
135 trait (any class derived from \e Policy \c Base) is a compatible
136 policy value of the given \e socketPolicy</dd>
138 <dt>\c If \e Policy \c Is < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIs)</dt>
139 <dd>This is a combination of \e Policy \c Is and \c boost::enable_if</dd>
141 <dt>\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
142 <dd>The inverse of above</dd>
145 These classes form the basis of the policy framework. To bind the
146 policy axis together, there are some more classes and templates.
149 <dt>\c class \c SocketPolicyBase</dt>
150 <dd>This class is the base class of the SocketPolicy template. It
151 is used to validate, that a class is really a SocketPolicy (by
152 checking, that it derives from SocketPolicyBase. This is simpler
153 than chacking the template directly).</dd>
155 <dt>\c template \c SocketPolicy < \e addressingPolicy, \e
156 framingPolicy, \e communicationPolicy, \e readPolicy, \e
157 writePolicy, \e bufferingPolicy ></dt>
158 <dd>This is the central SocketPolicy template. It combines a
159 complete set of policy classes, one for each axis.</dd>
161 <dt>\c template \c MakeSocketPolicy < \e args ></dt>
162 <dd>\c MakeSocketPolicy is a template metafunction which
163 simplifies building SocketPolicy instantiations. It takes any
164 number (ok, up to a maximum of 6) of policy classes as an
165 argument (in any order). It will sort these arguments into the
166 SocketPolicy template arguments. If for some axis no class is
167 specified, it's slot will be filled with \c Unspecified \e
168 Policy. Additionally, the first Argument may optionally be ab
169 arbitrary SocketPolicy. It will provide default values for
170 unspecified axis</dd>
172 <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt>
173 <dd>This template metafunction will check, wether the socket
174 policy \e derived is convertible to \e base. This means, that for
175 each axis, the corresponding policy class in \e derived must be
176 derived or be the same as the one on \e base.</dd>
179 \implementation All these classes are created automatically. The
180 \c SENF_SOCKET_POLICIES makro is a Boost.Preprocessor style
181 sequence listing all policy axis. The Boost.Preprocessor library
182 is then used to generate the respective classes.
184 \section policy_implement Implementing Policy Classes
186 To define a new policy class, derive from the corresponding base
187 class for your policy axies. The only policy axis which might
188 possibly need to be extended are the addressing policy
189 (AddressingPolicyBase) and the buffering policy
190 (BufferingPolicyBase). See the Documentation of these classes for
191 more information on which members can be implemented.
193 All members you define must be static. For any of the policy
194 classes, you must only define those members which are supported by
195 your implementation. If you leave out a member you automatically
196 disable the corresponding functionality in the
197 ClientSocketHandle/ServerSocketHandle interface.
199 The member prototypes given in the base class documentation only
200 specify the call signature not the way, the member must be defined
201 (FileHandle really is not a FileHandle but an arbitrary
204 If the existence of a member depends on other policies, you should
205 use the <code>If</code><i>SomePolicy</i><code>Is</code> and
206 <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to
207 dynamically enable/disable the member depending on some other
211 struct ExampleAddressingPolicy
213 template <class Policy>
214 void connect(senf::SocketHandle<Policy> handle, Address & addr,
215 typename senf::IfCommmunicationPolicyIs<
216 Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
220 The \c connect member in this example will only be enabled, it
221 the communication policy of the socket handle is
222 ConnectedCommunicationPolicy (or a derived type). See <a
223 href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a>
224 for a discussion of the third argument (\c
225 senf::ConnectedCommunicationPolicyIs is based on the \c
226 boost::enable_if template).
228 \see \ref extend_policy \n
229 <a class="ext" href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
230 <a class="ext" href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
231 <a class="ext" href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
233 \idea We could combine all the \e Policy \c Is templates into a
234 single template. Since the \e trait argument will automatically
235 specify the axis to be used, it is not necessary to specify that
236 axis in the tempalte functor's name. We could even combine this
237 with \c SocketPolicyIsBaseOf.
240 /** \defgroup policy_impl_group Policy Implementation classes
241 \ingroup policy_group
243 Here you will find all policy classes. Also included are some
244 supporting classes which are used as base classes to build other
248 #ifndef HH_SocketPolicy_
249 #define HH_SocketPolicy_ 1
253 #include "GenericSockAddr.hh"
255 //#include "SocketPolicy.mpp"
256 ///////////////////////////////hh.p////////////////////////////////////////
260 /// \addtogroup policy_group
263 // This may be adapted to change the supported policies (however,
264 // ClientSocketHandle and ServerSocketHandle will probably have to
265 // be adjusted accordingly)
267 /** \brief List all policy axis
271 This define symbol is used to configure the policy axis. The
272 base class for each of these axis must be defined explicitly
273 (e.g. AddressingPolicyBase). The implementation files will
274 then automatically generate all the other classes from this
279 # define SENF_SOCKET_POLICIES \
282 (CommunicationPolicy) \
287 // Wer define these classes explicitly (and not with some macro
289 // a) AddressingPolicyBase is different from all the others
290 // b) We want to document each one explicitly
292 /** \brief Policy defining socket addressing
294 AddressingPolicyBase is the baseclass of all addressing policy
295 classes. When defining a new addressing policy, the following
296 members can be defined. All methods must be static.
299 <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
300 <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
301 <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
302 <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
303 <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
308 struct AddressingPolicyBase
310 virtual ~AddressingPolicyBase() {}
312 typedef GenericSockAddr Address;
315 /** \brief Policy defining the framing format
317 This policy does not define any operations since it does have
318 no influence on any method signature. It does however affect
319 the semantics of the \c read() and \c write() operations.
321 \note This policy axis probably only has two sensible statess:
322 StreamFramingPolicy and DatagramFramingPolicy.
326 struct FramingPolicyBase
328 virtual ~FramingPolicyBase() {}
331 /** \brief Policy defining, how peers are selected
333 The CommunicationPolicy may define two members:
336 <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
337 <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
340 The \c listen member is straight forward. The \c accept() member
341 must return a new file descriptor (which will be used to
342 create a new SocketHandle of the correct type). Additionally,
343 accept() should only be defined, if the Addressing policy is
344 not \c NoAddressingPolicy (which together with
345 ConnectedCommunicationPolicy would identify a point-to-point
346 link with fixed communication partners).
348 \note This Policy only has two meaningful states:
349 ConnectedCommunicationPolicy and
350 UnconnectedCommunicationPolicy. It is probably not sensible to
351 define a new CommunicationPolicy type.
355 struct CommunicationPolicyBase
357 virtual ~CommunicationPolicyBase() {}
360 /** \brief Policy defining the readability
362 The ReadPolicy defines, wether the socket is readable. It
363 may define two members:
366 <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
367 <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
370 The second member should only be enabled if the communication
371 policy is UnconnectedCommunication (otherwise it does not make
372 sense since the communication partner is fixed) (see
373 AddressingPolicyBase on how to do this).
375 \note This Policy only has two meaningful states:
376 ReadablePolicy and NotReadablePolicy. It probably does not
377 make sense to define new read policy types.
381 struct ReadPolicyBase
383 virtual ~ReadPolicyBase() {}
386 /** \brief Policy defining the writability
388 The WritePolicy defines, wether the socket is writable. It may
392 <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
393 <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
396 The second member should only be enabled if the communication
397 policy is UnconnectedCommunication (otherwise it does not make
398 sense since the communication partner is fixed) (see
399 AddressingPolicyBase on how to do this).
401 \note This Policy only has two meaningful states:
402 WritablePolicy and NotWritablePolicy. It probably does not
403 make sense to define new write policy types.
407 struct WritePolicyBase
409 virtual ~WritePolicyBase() {}
412 /** \brief Policy defining the buffering interface
414 The BufferingPolicy defines the buffer handling of the
415 socket. It may provide the follogin members:
419 struct BufferingPolicyBase
421 virtual ~BufferingPolicyBase() {}
424 // The implementation file will for each Policy declared above
425 // define the following (SomePolicy is one of the above):
427 // struct SomePolicyBase;
428 // typedef UndefinedSomePolicy;
429 // template SomePolicyIs< SocketPolicy, Axis >
430 // template IfSomePolicyIs< SocketPolicy, Axis >
431 // template IfSomePolicyIsNot< SocketPolicy, Axis >
433 // Additionally the following are defined:
435 // class SocketPolicyBase
436 // template SocketPolicy< ..policies.. >
437 // template MakeSocketPolicy< ..args.. >
438 // template SocketPolicyIsBaseOf< Base, Derived >
442 // The following stub definitions are only visible to doxygen
444 /** \brief Alias of AddressingPolicyBase for better readability
445 \see \ref policy_group
447 typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
449 /** \brief Check single policy axis
451 This template is an example of the \e Policy \c Is family of
452 tempalte metafunctions. It will check, wether \c Trait is a
453 valid compatible Policy class of \c SocketPolicy. \c Trait
454 must be derived from AddressingPolicyBase (respectively \i
457 \see \ref policy_group
459 template <class SocketPolicy, class Trait>
460 struct AddressingPolicyIs
463 /** \brief Enable template overload depending on policy value
465 This template is an exmaple of the \c If \e Policy \c Is
466 family of templates. It is used like <a class="ext"
467 href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
468 to enable a templated overload only, if the AddressingPolicy
469 of \e Policy is compatible with \c Trait (that is the
470 AddressingPolicy of \c Policy is derived from \c Trait).
474 template <class SocketPolicy, class Trait>
475 struct IfAddressingPolicyIs
478 /** \brief Inversion of \c IfAddressingPolicyIs
481 template <class SocketPolicy, class Trait>
482 struct IfAddressingPolicyIsNot
485 /** \brief Baseclass of all SocketPolicies
489 This class provides the baseclass of all socket policies
490 (bundles). It serves two purposes:
491 \li It allows us to easily identify a socket policy bundle by
492 checking a classes baseclass.
493 \li It provides an abstract (virtual) interface to access the
498 struct SocketPolicyBase
500 /** \brief Polymorphic access to policy axes
502 This is an example of a policy axes accessor. It returns a
503 reference to the policy axes used by the conrecte protocol
504 bundle. This reference can then be checked using RTTI
507 AddressingPolicyBase const & theAddressingPolicy() const = 0;
510 /** \brief Collection of policy classes
512 The SocketPolicy template defines the complete Policy used by
513 the socket library. It contains one policy class for each
514 policy axis. This template takes one policy from each axis as
515 it's template arguments (this example implementation only has
516 AddressingPolicy as an argument).
518 A SocketPolicy can be complete or incomplete. An incomplete
519 SocketPolicy will have at least one axis set to \c Undefined
520 \e Policy (or a generic derived class which is used to group
521 some other policies but does not (completely) define the
522 policy behavior). A complete SocketPolicy will have a
523 concrete definition of the desired behavior for each policy
528 template < class AddressingPolicy >
531 /** \brief Check dynamic policy compatibility
533 This method will check the socket policy \a other against
534 this policy. It will check, wether \a other is a base
535 policy (or the same) of this policy. This check is done
536 against the \e dynamic type of \a other using RTTI. It
537 will throw \c std::bad_cast, if the policy is not
540 \param[in] other SocketPolicy to check
541 \throws std::bad_cast if \a other is not a compatible
544 static void checkBaseOf(SocketPolicyBase const & other);
547 /** \brief Metafunction to create SocketPolicy
549 This template metafunction simplifies the creation of a
550 SocketPolicy instantiation. It takes any number (that is up to
551 6) of Policy classes as arguments in any Order. It will create
552 a SocketPolicy from these policy classes. Any axis not
553 specified will be left as \c Unspecified \e Policy.
557 template <class Arg1, class Arg2, class ArgN>
558 struct MakeSocketPolicy
561 /** \brief Check policy compatibility
563 This tempalte metafunction checks, wether the SocketPolicy \c
564 Derived is more specialized than \c Base (and therefore a
565 SocketHandle with policy \c Derived is convertible to a
566 SocketHandle with policy \c Base).
568 The metafunction will return true (that is inherits from \c
569 boost::true_type, see the <a class="ext"
570 href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
571 library documentation for more information) if each policy
572 class in \c Base is a baseclass of (or the same as) the
573 corresponding policy class in \c Derived.
577 template <class Base, class Derived>
578 struct SocketPolicyIsBaseOf
586 //////////////////////////////hh.e////////////////////////////////////////
587 #include "SocketPolicy.ih"
588 //#include "SocketPolicy.cci"
589 #include "SocketPolicy.ct"
590 //#include "SocketPolicy.cti"
597 // c-file-style: "senf"
598 // indent-tabs-mode: nil
599 // ispell-local-dictionary: "american"