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 SocketPolicy 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 policy_framework \n
210 \ref extend_policy \n
211 <a class="ext" href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
212 <a class="ext" href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
213 <a class="ext" href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
215 \idea We could combine all the \e Policy \c Is templates into a
216 single template. Since the \e trait argument will automatically
217 specify the axis to be used, it is not necessary to specify that
218 axis in the tempalte functor's name. We could even combine this
219 with \c SocketPolicyIsBaseOf.
222 #ifndef HH_SocketPolicy_
223 #define HH_SocketPolicy_ 1
227 #include "GenericSockAddr.hh"
229 //#include "SocketPolicy.mpp"
230 ///////////////////////////////hh.p////////////////////////////////////////
234 /// \addtogroup policy_group
237 // This may be adapted to change the supported policies (however,
238 // ClientSocketHandle and ServerSocketHandle will probably have to
239 // be adjusted accordingly)
241 /** \brief List all policy axis
245 This define symbol is used to configure the policy axis. The
246 base class for each of these axis must be defined explicitly
247 (e.g. AddressingPolicyBase). The implementation files will
248 then automatically generate all the other classes from this
253 # define SENF_SOCKET_POLICIES \
256 (CommunicationPolicy) \
261 // Wer define these classes explicitly (and not with some macro
263 // a) AddressingPolicyBase is different from all the others
264 // b) We want to document each one explicitly
266 /** \brief Policy defining socket addressing
268 AddressingPolicyBase is the baseclass of all addressing policy
269 classes. When defining a new addressing policy, the following
270 members can be defined. All methods must be static.
273 <tr><td>typedef</td> <td><tt>Address</tt></td> <td>Address type</td></tr>
274 <tr><td>method</td> <td><tt>void local(FileHandle, Address &)</tt></td> <td>Get local socket address</td></tr>
275 <tr><td>method</td> <td><tt>void peer(FileHandle, Address &)</tt></td> <td>Get remote socket address</td></tr>
276 <tr><td>method</td> <td><tt>void bind(FileHandle, Address const &)</tt></td> <td>Bind socket to local address</td></tr>
277 <tr><td>method</tr> <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
282 struct AddressingPolicyBase
284 virtual ~AddressingPolicyBase() {}
286 typedef GenericSockAddr Address;
289 /** \brief Policy defining the framing format
291 This policy does not define any operations since it does have
292 no influence on any method signature. It does however affect
293 the semantics of the \c read() and \c write() operations.
295 \note This policy axis probably only has two sensible statess:
296 StreamFramingPolicy and DatagramFramingPolicy.
300 struct FramingPolicyBase
302 virtual ~FramingPolicyBase() {}
305 /** \brief Policy defining, how peers are selected
307 The CommunicationPolicy may define two members:
310 <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
311 <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td> <td>Accept a new connection</td></tr>
314 The \c listen member is straight forward. The \c accept() member
315 must return a new file descriptor (which will be used to
316 create a new SocketHandle of the correct type). Additionally,
317 accept() should only be defined, if the Addressing policy is
318 not \c NoAddressingPolicy (which together with
319 ConnectedCommunicationPolicy would identify a point-to-point
320 link with fixed communication partners).
322 \note This Policy only has two meaningful states:
323 ConnectedCommunicationPolicy and
324 UnconnectedCommunicationPolicy. It is probably not sensible to
325 define a new CommunicationPolicy type.
329 struct CommunicationPolicyBase
331 virtual ~CommunicationPolicyBase() {}
334 /** \brief Policy defining the readability
336 The ReadPolicy defines, wether the socket is readable. It
337 may define two members:
340 <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
341 <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
344 The second member should only be enabled if the communication
345 policy is UnconnectedCommunication (otherwise it does not make
346 sense since the communication partner is fixed) (see
347 AddressingPolicyBase on how to do this).
349 \note This Policy only has two meaningful states:
350 ReadablePolicy and NotReadablePolicy. It probably does not
351 make sense to define new read policy types.
355 struct ReadPolicyBase
357 virtual ~ReadPolicyBase() {}
360 /** \brief Policy defining the writability
362 The WritePolicy defines, wether the socket is writable. It may
366 <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td> <td>read data from socket</td></tr>
367 <tr><td>method</td> <td><tt>unsigned writeto(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 WritablePolicy and NotWritablePolicy. It probably does not
377 make sense to define new write policy types.
381 struct WritePolicyBase
383 virtual ~WritePolicyBase() {}
386 /** \brief Policy defining the buffering interface
388 The BufferingPolicy defines the buffer handling of the
389 socket. It may provide the follogin members:
393 struct BufferingPolicyBase
395 virtual ~BufferingPolicyBase() {}
398 // The implementation file will for each Policy declared above
399 // define the following (SomePolicy is one of the above):
401 // struct SomePolicyBase;
402 // typedef UndefinedSomePolicy;
403 // template SomePolicyIs< SocketPolicy, Axis >
404 // template IfSomePolicyIs< SocketPolicy, Axis >
405 // template IfSomePolicyIsNot< SocketPolicy, Axis >
407 // Additionally the following are defined:
409 // class SocketPolicyBase
410 // template SocketPolicy< ..policies.. >
411 // template MakeSocketPolicy< ..args.. >
412 // template SocketPolicyIsBaseOf< Base, Derived >
416 // The following stub definitions are only visible to doxygen
418 /** \brief Alias of AddressingPolicyBase for better readability
419 \see \ref policy_group
421 typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
423 /** \brief Check single policy axis
425 This template is an example of the \i Policy \c Is family of
426 tempalte metafunctions. It will check, wether \c Trait is a
427 valid compatible Policy class of \c SocketPolicy. \c Trait
428 must be derived from AddressingPolicyBase (respectively \i
431 \see \ref policy_group
433 template <class SocketPolicy, class Trait>
434 struct AddressingPolicyIs
437 /** \brief Enable template overload depending on policy value
439 This template is an exmaple of the \c If \i Policy \c Is
440 family of templates. It is used like <a class="ext"
441 href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
442 to enable a templated overload only, if the AddressingPolicy
443 of \i Policy is compatible with \c Trait (that is the
444 AddressingPolicy of \c Policy is derived from \c Trait).
448 template <class SocketPolicy, class Trait>
449 struct IfAddressingPolicyIs
452 /** \brief Inversion of \c IfAddressingPolicyIs
455 template <class SocketPolicy, class Trait>
456 struct IfAddressingPolicyIsNot
459 /** \brief Baseclass of all SocketPolicies
463 This class is used to
467 struct SocketPolicyBase
470 /** \brief Collection of policy classes
472 The SocketPolicy template defines the complete Policy used by
473 the socket library. It contains one policy class for each
476 A SocketPolicy can be complete or incomplete. An incomplete
477 SocketPolicy will have at least one axis set to \c Undefined
478 \i Policy (or a generic derived class which is used to group
479 some other policies but does not (completely) define the
480 policy behavior). A complete SocketPolicy will have a
481 concrete definition of the desired behavior for each policy
487 class AddressingPolicy,
489 class CommunicationPolicy,
492 class BufferingPolicy >
496 /** \brief Metafunction to create SocketPolicy
498 This template metafunction simplifies the creation of a
499 SocketPolicy instantiation. It takes any number (that is up to
500 6) of Policy classes as arguments in any Order. It will create
501 a SocketPolicy from these policy classes. Any axis not
502 specified will be left as \c Unspecified \i Policy.
506 template <class Arg1, class Arg2, class ArgN>
507 struct MakeSocketPolicy
510 /** \brief Check policy compatibility
512 This tempalte metafunction checks, wether the SocketPolicy \c
513 Derived is more specialized than \c Base (and therefore a
514 SocketHandle with policy \c Derived is convertible to a
515 SocketHandle with policy \c Base).
517 The metafunction will return true (that is inherits from \c
518 boost::true_type, see the <a class="ext"
519 href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
520 library documentation for more information) if each policy
521 class in \c Base is a baseclass of (or the same as) the
522 corresponding policy class in \c Derived.
526 template <class Base, class Derived>
527 struct SocketPolicyIsBaseOf
535 //////////////////////////////hh.e////////////////////////////////////////
536 #include "SocketPolicy.ih"
537 //#include "SocketPolicy.cci"
538 #include "SocketPolicy.ct"
539 //#include "SocketPolicy.cti"
545 // c-file-style: "senf"