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 three new instances (The
35 handle, the body and the policy) of which two (body and
36 policy) live on the heap. This is expensive. We should check,
37 wether we can make all the policy classes to singletons and
38 assign the same instance to all socket bodies with the same
39 policy. This would reduce the number of allocations per socket
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 \i 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 framingPolicy, \e communicationPolicy, \e readPolicy, \e writePolicy, \e bufferingPolicy ></dt>
147 <dd>This is the central SocketPolicy template. It combines a
148 complete set of policy classes, one for each axis.</dd>
150 <dt>\c template \c MakeSocketPolicy < \e args ></dt>
151 <dd>\c MakeSocketPolicy is a template metafunction which
152 simplifies building SocketPolicy instantiations. It takes any
153 number (ok, up to a maximum of 6) of policy classes as an
154 argument (in any order). It will sort these arguments into the
155 SocketPolicy template arguments. If for some axis no class is
156 specified, it's slot will be filled with \c Unspecified \e
157 Policy. Additionally, the first Argument may optionally be ab
158 arbitrary SocketPolicy. It will provide default values for
159 unspecified axis</dd>
161 <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt>
162 <dd>This template metafunction will check, wether the socket
163 policy \e derived is convertible to \e base. This means, that for
164 each axis, the corresponding policy class in \e derived must be
165 derived or be the same as the one on \e base.</dd>
168 \implementation All these classes are created automatically. The
169 \c SENF_SOCKET_POLICIES makro is a Boost.Preprocessor style
170 sequence listing all policy axis. The Boost.Preprocessor library
171 is then used to generate the respective classes.
173 \section policy_implement Implementing Policy Classes
175 To define a new policy class, derive from the corresponding base
176 class for your policy axies. The only policy axis which might
177 possibly need to be extended are the addressing policy
178 (AddressingPolicyBase) and the buffering policy
179 (BufferingPolicyBase). See the Documentation of these classes for
180 more information on which members can be implemented.
182 All members you define must be static. For any of the policy
183 classes, you must only define those members which are supported by
184 your implementation. If you leave out a member you automatically
185 disable the corresponding functionality in the
186 ClientSocketHandle/ServerSocketHandle interface.
188 The member prototypes given in the base class documentation only
189 specify the call signature not the way, the member must be defined
190 (FileHandle really is not a FileHandle but an arbitrary
193 If the existence of a member depends on other policies, you should
194 use the <code>If</code><i>SomePolicy</i><code>Is</code> and
195 <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to
196 dynamically enable/disable the member depending on some other
200 struct ExampleAddressingPolicy
202 template <class Policy>
203 void connect(senf::SocketHandle<Policy> handle, Address & addr,
204 typename senf::IfCommmunicationPolicyIs<
205 Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
209 The \c connect member in this example will only be enabled, it
210 the communication policy of the socket handle is
211 ConnectedCommunicationPolicy (or a derived type). See <a
212 href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a>
213 for a discussion of the third argument (\c
214 senf::ConnectedCommunicationPolicyIs is based on the \c
215 boost::enable_if template).
217 \see \ref extend_policy \n
218 <a class="ext" href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
219 <a class="ext" href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
220 <a class="ext" href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
222 \idea We could combine all the \e Policy \c Is templates into a
223 single template. Since the \e trait argument will automatically
224 specify the axis to be used, it is not necessary to specify that
225 axis in the tempalte functor's name. We could even combine this
226 with \c SocketPolicyIsBaseOf.
229 #ifndef HH_SocketPolicy_
230 #define HH_SocketPolicy_ 1
234 #include "GenericSockAddr.hh"
236 //#include "SocketPolicy.mpp"
237 ///////////////////////////////hh.p////////////////////////////////////////
241 /// \addtogroup policy_group
244 // This may be adapted to change the supported policies (however,
245 // ClientSocketHandle and ServerSocketHandle will probably have to
246 // be adjusted accordingly)
248 /** \brief List all policy axis
252 This define symbol is used to configure the policy axis. The
253 base class for each of these axis must be defined explicitly
254 (e.g. AddressingPolicyBase). The implementation files will
255 then automatically generate all the other classes from this
260 # define SENF_SOCKET_POLICIES \
263 (CommunicationPolicy) \
268 // Wer define these classes explicitly (and not with some macro
270 // a) AddressingPolicyBase is different from all the others
271 // b) We want to document each one explicitly
273 /** \brief Policy defining socket addressing
275 AddressingPolicyBase is the baseclass of all addressing policy
276 classes. When defining a new addressing policy, the following
277 members can be defined. All methods must be static.
280 <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
281 <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
282 <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
283 <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
284 <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
289 struct AddressingPolicyBase
291 virtual ~AddressingPolicyBase() {}
293 typedef GenericSockAddr Address;
296 /** \brief Policy defining the framing format
298 This policy does not define any operations since it does have
299 no influence on any method signature. It does however affect
300 the semantics of the \c read() and \c write() operations.
302 \note This policy axis probably only has two sensible statess:
303 StreamFramingPolicy and DatagramFramingPolicy.
307 struct FramingPolicyBase
309 virtual ~FramingPolicyBase() {}
312 /** \brief Policy defining, how peers are selected
314 The CommunicationPolicy may define two members:
317 <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
318 <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
321 The \c listen member is straight forward. The \c accept() member
322 must return a new file descriptor (which will be used to
323 create a new SocketHandle of the correct type). Additionally,
324 accept() should only be defined, if the Addressing policy is
325 not \c NoAddressingPolicy (which together with
326 ConnectedCommunicationPolicy would identify a point-to-point
327 link with fixed communication partners).
329 \note This Policy only has two meaningful states:
330 ConnectedCommunicationPolicy and
331 UnconnectedCommunicationPolicy. It is probably not sensible to
332 define a new CommunicationPolicy type.
336 struct CommunicationPolicyBase
338 virtual ~CommunicationPolicyBase() {}
341 /** \brief Policy defining the readability
343 The ReadPolicy defines, wether the socket is readable. It
344 may define two members:
347 <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
348 <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
351 The second member should only be enabled if the communication
352 policy is UnconnectedCommunication (otherwise it does not make
353 sense since the communication partner is fixed) (see
354 AddressingPolicyBase on how to do this).
356 \note This Policy only has two meaningful states:
357 ReadablePolicy and NotReadablePolicy. It probably does not
358 make sense to define new read policy types.
362 struct ReadPolicyBase
364 virtual ~ReadPolicyBase() {}
367 /** \brief Policy defining the writability
369 The WritePolicy defines, wether the socket is writable. It may
373 <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
374 <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
377 The second member should only be enabled if the communication
378 policy is UnconnectedCommunication (otherwise it does not make
379 sense since the communication partner is fixed) (see
380 AddressingPolicyBase on how to do this).
382 \note This Policy only has two meaningful states:
383 WritablePolicy and NotWritablePolicy. It probably does not
384 make sense to define new write policy types.
388 struct WritePolicyBase
390 virtual ~WritePolicyBase() {}
393 /** \brief Policy defining the buffering interface
395 The BufferingPolicy defines the buffer handling of the
396 socket. It may provide the follogin members:
400 struct BufferingPolicyBase
402 virtual ~BufferingPolicyBase() {}
405 // The implementation file will for each Policy declared above
406 // define the following (SomePolicy is one of the above):
408 // struct SomePolicyBase;
409 // typedef UndefinedSomePolicy;
410 // template SomePolicyIs< SocketPolicy, Axis >
411 // template IfSomePolicyIs< SocketPolicy, Axis >
412 // template IfSomePolicyIsNot< SocketPolicy, Axis >
414 // Additionally the following are defined:
416 // class SocketPolicyBase
417 // template SocketPolicy< ..policies.. >
418 // template MakeSocketPolicy< ..args.. >
419 // template SocketPolicyIsBaseOf< Base, Derived >
423 // The following stub definitions are only visible to doxygen
425 /** \brief Alias of AddressingPolicyBase for better readability
426 \see \ref policy_group
428 typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
430 /** \brief Check single policy axis
432 This template is an example of the \i Policy \c Is family of
433 tempalte metafunctions. It will check, wether \c Trait is a
434 valid compatible Policy class of \c SocketPolicy. \c Trait
435 must be derived from AddressingPolicyBase (respectively \i
438 \see \ref policy_group
440 template <class SocketPolicy, class Trait>
441 struct AddressingPolicyIs
444 /** \brief Enable template overload depending on policy value
446 This template is an exmaple of the \c If \i Policy \c Is
447 family of templates. It is used like <a class="ext"
448 href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
449 to enable a templated overload only, if the AddressingPolicy
450 of \i Policy is compatible with \c Trait (that is the
451 AddressingPolicy of \c Policy is derived from \c Trait).
455 template <class SocketPolicy, class Trait>
456 struct IfAddressingPolicyIs
459 /** \brief Inversion of \c IfAddressingPolicyIs
462 template <class SocketPolicy, class Trait>
463 struct IfAddressingPolicyIsNot
466 /** \brief Baseclass of all SocketPolicies
470 This class is used to
474 struct SocketPolicyBase
477 /** \brief Collection of policy classes
479 The SocketPolicy template defines the complete Policy used by
480 the socket library. It contains one policy class for each
483 A SocketPolicy can be complete or incomplete. An incomplete
484 SocketPolicy will have at least one axis set to \c Undefined
485 \i Policy (or a generic derived class which is used to group
486 some other policies but does not (completely) define the
487 policy behavior). A complete SocketPolicy will have a
488 concrete definition of the desired behavior for each policy
494 class AddressingPolicy,
496 class CommunicationPolicy,
499 class BufferingPolicy >
503 /** \brief Metafunction to create SocketPolicy
505 This template metafunction simplifies the creation of a
506 SocketPolicy instantiation. It takes any number (that is up to
507 6) of Policy classes as arguments in any Order. It will create
508 a SocketPolicy from these policy classes. Any axis not
509 specified will be left as \c Unspecified \i Policy.
513 template <class Arg1, class Arg2, class ArgN>
514 struct MakeSocketPolicy
517 /** \brief Check policy compatibility
519 This tempalte metafunction checks, wether the SocketPolicy \c
520 Derived is more specialized than \c Base (and therefore a
521 SocketHandle with policy \c Derived is convertible to a
522 SocketHandle with policy \c Base).
524 The metafunction will return true (that is inherits from \c
525 boost::true_type, see the <a class="ext"
526 href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
527 library documentation for more information) if each policy
528 class in \c Base is a baseclass of (or the same as) the
529 corresponding policy class in \c Derived.
533 template <class Base, class Derived>
534 struct SocketPolicyIsBaseOf
542 //////////////////////////////hh.e////////////////////////////////////////
543 #include "SocketPolicy.ih"
544 //#include "SocketPolicy.cci"
545 #include "SocketPolicy.ct"
546 //#include "SocketPolicy.cti"
552 // c-file-style: "senf"