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 include
30 \todo Do we want to support separate read and write policies. This
31 allows to treat pipes within this framework however, is this worth
35 /** \defgroup policy_group The Policy Framework
37 \image html SocketPolicy.png
39 \section policy_group_introduction Introduction to the Policy Framework
41 The policy framework conceptually implements a list of parallel
42 inheritance hierarchies each covering a specific interface aspect
43 of the socket handle. The socket handle itself only provides
44 minimal functionality. All further functionality is relayed to a
45 policy class, or more precisely, to a group of policy classes, one
46 for each policy axis. The policy axis are
49 <dt><em>addressingPolicy</em></dt>
50 <dd>configures, whether a socket is
51 addressable and if so, configures the address type</dd>
53 <dt><em>framingPolicy</em></dt>
54 <dd>configures the type of framing the socket provides: either no
55 framing providing a simple i/o stream or packet framing</dd>
57 <dt><em>communicationPolicy</em></dt>
58 <dd>configures,if and how the communication partner is
61 <dt><em>readPolicy</em></dt>
62 <dd>configures the readability of the socket</dd>
64 <dt><em>writePolicy</em></dt>
65 <dd>configures the writability of the socket</dd>
67 <dt><em>bufferingPolicy</em></dt>
68 <dd>configures, if and how buffering is configured for a socket</dd>
71 Every Policy value is identified by a class type. The policy
72 classes themselves built an inheritance hierarchy for each policy
73 axis. For each policy axis, the root of this tree is the class
74 named \i Policy \c Base (e.g. \p AddressingPolicyBase).
76 The senf::SocketPolicy defines the complete policy of a socket. It
77 combines a set of policy classes, one for each policy
78 axis. Together, they define the behavior of a socket handle. The
79 socket handle instances do not implement any socket functionality
80 themselves instead defering the implementation to the policy
81 classes. The SocketHandle interface is therefore \e not
82 implemented using virtual members, all important socket functions
83 can be inlined by the compiler to create highly efficient code.
85 A SocketPolicy can be incomplete. In this case it does \e not
86 completely specify the socket interface, it leaves some aspects
87 open. A SocketHandle based on such a policy will have a reduced
88 interface: It will only support those members for wich the
89 corresponding policies are defined.
91 Two SocketHandle's with different policies can be \e
92 compatible. If they are, the more derived SocketHandle can be
93 converted (assigned to) the more basic SocketHandle.
95 \section policy_group_details The Policy Framework Classes
97 In the following discussion we will use the following conventions:
98 \li \e Policy is one or \c AddressingPolicy, \c FramingPolicy, \c
99 CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c
101 \li \e socketPolicy is any socket policy (that is, an
102 instantiation of the SocketPolicy template)
103 \li \e trait is an any policy class (that is, any class derived
104 from one of the axis base classes)
106 Each axis is comprised of a number of classes and templates (all
107 in namespace senf of course):
110 <dt>\e Policy \c Base (ex: AddressingPolicyBase)</dt>
111 <dd>Baseclass of all policies in this axis</dd>
113 <dt>\c Unspecified \e Policy (ex: \ref UnspecifiedAddressingPolicy)</dt>
114 <dd>An alias (typedef) for \e Policy \c Base</dd>
116 <dt>\e Policy \c Is < \e socketPolicy, \e trait > (ex: AddressingPolicyIs)</dt>
117 <dd>A template metafunction returning \c boost::true_type, if \e
118 trait (any class derived from \e Policy \c Base) is a compatible
119 policy value of the given \e socketPolicy</dd>
121 <dt>\c If \e Policy \c Is < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIs)</dt>
122 <dd>This is a combination of \e Policy \c Is and \c boost::enable_if</dd>
124 <dt>\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
125 <dd>The inverse of above</dd>
128 These classes form the basis of the policy framework. To bind the
129 policy axis together, there are some more classes and templates.
132 <dt>\c class \c SocketPolicyBase</dt>
133 <dd>This class is the base class of the SocketPolicy template. It
134 is used to validate, that a class is really a SocketPolicy (by
135 checking, that it derives from SocketPolicyBase. This is simpler
136 than chacking the template directly).</dd>
138 <dt>\c template \c SocketPolicy < \e addressingPolicy, \e framingPolicy, \e communicationPolicy, \e readPolicy, \e writePolicy, \e bufferingPolicy ></dt>
139 <dd>This is the central SocketPolicy template. It combines a
140 complete set of policy classes, one for each axis.</dd>
142 <dt>\c template \c MakeSocketPolicy < \e args ></dt>
143 <dd>\c MakeSocketPolicy is a template metafunction which
144 simplifies building SocketPolicy instantiations. It takes any
145 number (ok, up to a maximum of 6) of policy classes as an
146 argument (in any order). It will sort these arguments into the
147 SocketPolicy template arguments. If for some axis no class is
148 specified, it's slot will be filled with \c Unspecified \e
149 Policy. Additionally, the first Argument may optionally be ab
150 arbitrary SocketPolicy. It will provide default values for
151 unspecified axis</dd>
153 <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt>
154 <dd>This template metafunction will check, wether the socket
155 policy \e derived is convertible to \e base. This means, that for
156 each axis, the corresponding policy class in \e derived must be
157 derived or be the same as the one on \e base.</dd>
160 \implementation All these classes are created automatically. The
161 \c SENF_SOCKET_POLICIES makro is a Boost.Preprocessor style
162 sequence listing all policy axis. The Boost.Preprocessor library
163 is then used to generate the respective classes.
165 \section policy_implement Implementing Policy Classes
167 To define a new policy class, derive from the corresponding base
168 class for your policy axies. The only policy axis which might
169 possibly need to be extended are the addressing policy
170 (AddressingPolicyBase) and the buffering policy
171 (BufferingPolicyBase). See the Documentation of these classes for
172 more information on which members can be implemented.
174 All members you define must be static. For any of the policy
175 classes, you must only define those members which are supported by
176 your implementation. If you leave out a member you automatically
177 disable the corresponding functionality in the
178 ClientSocketHandle/ServerSocketHandle interface.
180 The member prototypes given in the base class documentation only
181 specify the call signature not the way, the member must be defined
182 (FileHandle really is not a FileHandle but an arbitrary
185 If the existence of a member depends on other policies, you should
186 use the <code>If</code><i>SomePolicy</i><code>Is</code> and
187 <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to
188 dynamically enable/disable the member depending on some other
192 struct ExampleAddressingPolicy
194 template <class Policy>
195 void connect(senf::SocketHandle<Policy> handle, Address & addr,
196 typename senf::IfCommmunicationPolicyIs<
197 Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
201 The \c connect member in this example will only be enabled, it
202 the communication policy of the socket handle is
203 ConnectedCommunicationPolicy (or a derived type). See <a
204 href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a>
205 for a discussion of the third argument (\c
206 senf::ConnectedCommunicationPolicyIs is based on the \c
207 boost::enable_if template).
209 \see \ref extend_policy \n
210 <a class="ext" href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
211 <a class="ext" href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
212 <a class="ext" href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
214 \idea We could combine all the \e Policy \c Is templates into a
215 single template. Since the \e trait argument will automatically
216 specify the axis to be used, it is not necessary to specify that
217 axis in the tempalte functor's name. We could even combine this
218 with \c SocketPolicyIsBaseOf.
221 #ifndef HH_SocketPolicy_
222 #define HH_SocketPolicy_ 1
226 #include "GenericSockAddr.hh"
228 //#include "SocketPolicy.mpp"
229 ///////////////////////////////hh.p////////////////////////////////////////
233 /// \addtogroup policy_group
236 // This may be adapted to change the supported policies (however,
237 // ClientSocketHandle and ServerSocketHandle will probably have to
238 // be adjusted accordingly)
240 /** \brief List all policy axis
244 This define symbol is used to configure the policy axis. The
245 base class for each of these axis must be defined explicitly
246 (e.g. AddressingPolicyBase). The implementation files will
247 then automatically generate all the other classes from this
252 # define SENF_SOCKET_POLICIES \
255 (CommunicationPolicy) \
260 // Wer define these classes explicitly (and not with some macro
262 // a) AddressingPolicyBase is different from all the others
263 // b) We want to document each one explicitly
265 /** \brief Policy defining socket addressing
267 AddressingPolicyBase is the baseclass of all addressing policy
268 classes. When defining a new addressing policy, the following
269 members can be defined. All methods must be static.
272 <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
273 <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
274 <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
275 <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
276 <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
281 struct AddressingPolicyBase
283 virtual ~AddressingPolicyBase() {}
285 typedef GenericSockAddr Address;
288 /** \brief Policy defining the framing format
290 This policy does not define any operations since it does have
291 no influence on any method signature. It does however affect
292 the semantics of the \c read() and \c write() operations.
294 \note This policy axis probably only has two sensible statess:
295 StreamFramingPolicy and DatagramFramingPolicy.
299 struct FramingPolicyBase
301 virtual ~FramingPolicyBase() {}
304 /** \brief Policy defining, how peers are selected
306 The CommunicationPolicy may define two members:
309 <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
310 <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
313 The \c listen member is straight forward. The \c accept() member
314 must return a new file descriptor (which will be used to
315 create a new SocketHandle of the correct type). Additionally,
316 accept() should only be defined, if the Addressing policy is
317 not \c NoAddressingPolicy (which together with
318 ConnectedCommunicationPolicy would identify a point-to-point
319 link with fixed communication partners).
321 \note This Policy only has two meaningful states:
322 ConnectedCommunicationPolicy and
323 UnconnectedCommunicationPolicy. It is probably not sensible to
324 define a new CommunicationPolicy type.
328 struct CommunicationPolicyBase
330 virtual ~CommunicationPolicyBase() {}
333 /** \brief Policy defining the readability
335 The ReadPolicy defines, wether the socket is readable. It
336 may define two members:
339 <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
340 <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
343 The second member should only be enabled if the communication
344 policy is UnconnectedCommunication (otherwise it does not make
345 sense since the communication partner is fixed) (see
346 AddressingPolicyBase on how to do this).
348 \note This Policy only has two meaningful states:
349 ReadablePolicy and NotReadablePolicy. It probably does not
350 make sense to define new read policy types.
354 struct ReadPolicyBase
356 virtual ~ReadPolicyBase() {}
359 /** \brief Policy defining the writability
361 The WritePolicy defines, wether the socket is writable. It may
365 <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
366 <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
369 The second member should only be enabled if the communication
370 policy is UnconnectedCommunication (otherwise it does not make
371 sense since the communication partner is fixed) (see
372 AddressingPolicyBase on how to do this).
374 \note This Policy only has two meaningful states:
375 WritablePolicy and NotWritablePolicy. It probably does not
376 make sense to define new write policy types.
380 struct WritePolicyBase
382 virtual ~WritePolicyBase() {}
385 /** \brief Policy defining the buffering interface
387 The BufferingPolicy defines the buffer handling of the
388 socket. It may provide the follogin members:
392 struct BufferingPolicyBase
394 virtual ~BufferingPolicyBase() {}
397 // The implementation file will for each Policy declared above
398 // define the following (SomePolicy is one of the above):
400 // struct SomePolicyBase;
401 // typedef UndefinedSomePolicy;
402 // template SomePolicyIs< SocketPolicy, Axis >
403 // template IfSomePolicyIs< SocketPolicy, Axis >
404 // template IfSomePolicyIsNot< SocketPolicy, Axis >
406 // Additionally the following are defined:
408 // class SocketPolicyBase
409 // template SocketPolicy< ..policies.. >
410 // template MakeSocketPolicy< ..args.. >
411 // template SocketPolicyIsBaseOf< Base, Derived >
415 // The following stub definitions are only visible to doxygen
417 /** \brief Alias of AddressingPolicyBase for better readability
418 \see \ref policy_group
420 typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
422 /** \brief Check single policy axis
424 This template is an example of the \i Policy \c Is family of
425 tempalte metafunctions. It will check, wether \c Trait is a
426 valid compatible Policy class of \c SocketPolicy. \c Trait
427 must be derived from AddressingPolicyBase (respectively \i
430 \see \ref policy_group
432 template <class SocketPolicy, class Trait>
433 struct AddressingPolicyIs
436 /** \brief Enable template overload depending on policy value
438 This template is an exmaple of the \c If \i Policy \c Is
439 family of templates. It is used like <a class="ext"
440 href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
441 to enable a templated overload only, if the AddressingPolicy
442 of \i Policy is compatible with \c Trait (that is the
443 AddressingPolicy of \c Policy is derived from \c Trait).
447 template <class SocketPolicy, class Trait>
448 struct IfAddressingPolicyIs
451 /** \brief Inversion of \c IfAddressingPolicyIs
454 template <class SocketPolicy, class Trait>
455 struct IfAddressingPolicyIsNot
458 /** \brief Baseclass of all SocketPolicies
462 This class is used to
466 struct SocketPolicyBase
469 /** \brief Collection of policy classes
471 The SocketPolicy template defines the complete Policy used by
472 the socket library. It contains one policy class for each
475 A SocketPolicy can be complete or incomplete. An incomplete
476 SocketPolicy will have at least one axis set to \c Undefined
477 \i Policy (or a generic derived class which is used to group
478 some other policies but does not (completely) define the
479 policy behavior). A complete SocketPolicy will have a
480 concrete definition of the desired behavior for each policy
486 class AddressingPolicy,
488 class CommunicationPolicy,
491 class BufferingPolicy >
495 /** \brief Metafunction to create SocketPolicy
497 This template metafunction simplifies the creation of a
498 SocketPolicy instantiation. It takes any number (that is up to
499 6) of Policy classes as arguments in any Order. It will create
500 a SocketPolicy from these policy classes. Any axis not
501 specified will be left as \c Unspecified \i Policy.
505 template <class Arg1, class Arg2, class ArgN>
506 struct MakeSocketPolicy
509 /** \brief Check policy compatibility
511 This tempalte metafunction checks, wether the SocketPolicy \c
512 Derived is more specialized than \c Base (and therefore a
513 SocketHandle with policy \c Derived is convertible to a
514 SocketHandle with policy \c Base).
516 The metafunction will return true (that is inherits from \c
517 boost::true_type, see the <a class="ext"
518 href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
519 library documentation for more information) if each policy
520 class in \c Base is a baseclass of (or the same as) the
521 corresponding policy class in \c Derived.
525 template <class Base, class Derived>
526 struct SocketPolicyIsBaseOf
534 //////////////////////////////hh.e////////////////////////////////////////
535 #include "SocketPolicy.ih"
536 //#include "SocketPolicy.cci"
537 #include "SocketPolicy.ct"
538 //#include "SocketPolicy.cti"
544 // c-file-style: "senf"