Add INPUT_FILTER support do Doxygen builder
[senf.git] / Socket / SocketPolicy.hh
1 // $Id$
2 //
3 // Copyright (C) 2006 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief Policy Framework public header
25
26     \todo We should probably remove BufferingPolicy from the
27         interface, it does not make much sense (how did I come to
28         include it ??)
29     
30     \todo Do we want to support separate read and write policies. This
31         allows to treat pipes within this framework however, is this
32         worth the effort?
33
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.
41  */
42
43 /** \defgroup policy_group The Policy Framework
44
45     \image html SocketPolicy.png
46
47     \section policy_group_introduction Introduction to the Policy Framework
48
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
55     
56     <dl>
57     <dt><em>addressingPolicy</em></dt>
58     <dd>configures, whether a socket is
59     addressable and if so, configures the address type</dd>
60     
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>
64     
65     <dt><em>communicationPolicy</em></dt>
66     <dd>configures,if and how the communication partner is
67     selected</dd> 
68     
69     <dt><em>readPolicy</em></dt>
70     <dd>configures the readability of the socket</dd>
71     
72     <dt><em>writePolicy</em></dt>
73     <dd>configures the writability of the socket</dd>
74     
75     <dt><em>bufferingPolicy</em></dt>
76     <dd>configures, if and how buffering is configured for a socket</dd>
77     </dl>
78
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).
83
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.
92
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.
98
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.
102     
103     \section policy_group_details The Policy Framework Classes
104
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
108         BufferingPolicy
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)
113
114     Each axis is comprised of a number of classes and templates (all
115     in namespace senf of course):
116     
117     <dl>
118     <dt>\e Policy \c Base (ex: AddressingPolicyBase)</dt>
119     <dd>Baseclass of all policies in this axis</dd>
120
121     <dt>\c Unspecified \e Policy  (ex: \ref UnspecifiedAddressingPolicy)</dt>
122     <dd>An alias (typedef) for \e Policy \c Base</dd>
123
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>
128
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>
131
132     <dt>\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
133     <dd>The inverse of above</dd>
134     </dl>
135     
136     These classes form the basis of the policy framework. To bind the
137     policy axis together, there are some more classes and templates.
138
139     <dl>
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>
145
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>
151
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>
162
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>
168     </dl>
169
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.
174
175     \section policy_implement Implementing Policy Classes
176
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.
183
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.
189
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
193     SocketHandle).
194     
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
199     policy:
200
201     \code
202       struct ExampleAddressingPolicy 
203       {
204           template <class Policy>
205           void connect(senf::SocketHandle<Policy> handle, Address & addr,
206                        typename senf::IfCommmunicationPolicyIs<
207                            Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
208       };
209     \endcode
210
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).
218
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>
223
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.
229  */
230
231 #ifndef HH_SocketPolicy_
232 #define HH_SocketPolicy_ 1
233
234 // Custom includes
235
236 #include "GenericSockAddr.hh"
237
238 //#include "SocketPolicy.mpp"
239 ///////////////////////////////hh.p////////////////////////////////////////
240
241 namespace senf {
242
243     /// \addtogroup policy_group
244     /// @{
245
246     // This may be adapted to change the supported policies (however,
247     // ClientSocketHandle and ServerSocketHandle will probably have to
248     // be adjusted accordingly)
249
250     /** \brief List all policy axis
251         
252         \internal
253
254         This define symbol is used to configure the policy axis. The
255         base class for each of these axis must be defined explicitly
256         (e.g. AddressingPolicyBase). The implementation files will
257         then automatically generate all the other classes from this
258         list.
259
260         \see policy_group
261      */
262 #   define SENF_SOCKET_POLICIES                 \
263         (AddressingPolicy)                      \
264         (FramingPolicy)                         \
265         (CommunicationPolicy)                   \
266         (ReadPolicy)                            \
267         (WritePolicy)                           \
268         (BufferingPolicy)
269
270     // Wer define these classes explicitly (and not with some macro
271     // magic) because
272     // a) AddressingPolicyBase is different from all the others
273     // b) We want to document each one explicitly
274     
275     /** \brief Policy defining socket addressing
276
277         AddressingPolicyBase is the baseclass of all addressing policy
278         classes. When defining a new addressing policy, the following
279         members can be defined. All methods must be static.
280
281         <table class="senf">
282         <tr><td>typedef</td> <td><tt>Address</tt></td>                                   <td>Address type</td></tr>
283         <tr><td>method</td>  <td><tt>void local(FileHandle, Address &)</tt></td>         <td>Get local socket address</td></tr>
284         <tr><td>method</td>  <td><tt>void peer(FileHandle, Address &)</tt></td>          <td>Get remote socket address</td></tr>
285         <tr><td>method</td>  <td><tt>void bind(FileHandle, Address const &)</tt></td>    <td>Bind socket to local address</td></tr>
286         <tr><td>method</tr>  <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
287         </table>
288
289         \see policy_group
290      */
291     struct AddressingPolicyBase
292     {
293         virtual ~AddressingPolicyBase() {}
294         
295         typedef GenericSockAddr Address;
296     };
297
298     /** \brief Policy defining the framing format
299
300         This policy does not define any operations since it does have
301         no influence on any method signature. It does however affect
302         the semantics of the \c read() and \c write() operations.
303
304         \note This policy axis probably only has two sensible statess:
305         StreamFramingPolicy and DatagramFramingPolicy.
306
307         \see policy_group
308      */
309     struct FramingPolicyBase 
310     {
311         virtual ~FramingPolicyBase() {}
312     };
313
314     /** \brief Policy defining, how peers are selected
315
316         The CommunicationPolicy may define two members:
317
318         <table class="senf">
319         <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
320         <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td>         <td>Accept a new connection</td></tr>
321         </table>
322         
323         The \c listen member is straight forward. The \c accept() member
324         must return a new file descriptor (which will be used to
325         create a new SocketHandle of the correct type). Additionally,
326         accept() should only be defined, if the Addressing policy is
327         not \c NoAddressingPolicy (which together with
328         ConnectedCommunicationPolicy would identify a point-to-point
329         link with fixed communication partners).
330
331         \note This Policy only has two meaningful states:
332         ConnectedCommunicationPolicy and
333         UnconnectedCommunicationPolicy. It is probably not sensible to
334         define a new CommunicationPolicy type.
335
336         \see policy_group
337      */
338     struct CommunicationPolicyBase
339     {
340         virtual ~CommunicationPolicyBase() {}
341     };
342
343     /** \brief Policy defining the readability
344
345         The ReadPolicy defines, wether the socket is readable. It
346         may define two members:
347
348         <table class="senf">
349         <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td>                <td>read data from socket</td></tr>
350         <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         </table>
352
353         The second member should only be enabled if the communication
354         policy is UnconnectedCommunication (otherwise it does not make
355         sense since the communication partner is fixed) (see
356         AddressingPolicyBase on how to do this).
357
358         \note This Policy only has two meaningful states:
359         ReadablePolicy and NotReadablePolicy. It probably does not
360         make sense to define new read policy types.
361
362         \see policy_group
363      */
364     struct ReadPolicyBase
365     {
366         virtual ~ReadPolicyBase() {}
367     };
368
369     /** \brief Policy defining the writability
370
371         The WritePolicy defines, wether the socket is writable. It may
372         define two members:
373
374         <table class="senf">
375         <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td>              <td>read data from socket</td></tr>
376         <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         </table>
378
379         The second member should only be enabled if the communication
380         policy is UnconnectedCommunication (otherwise it does not make
381         sense since the communication partner is fixed) (see
382         AddressingPolicyBase on how to do this).
383
384         \note This Policy only has two meaningful states:
385         WritablePolicy and NotWritablePolicy. It probably does not
386         make sense to define new write policy types.
387
388         \see policy_group
389      */
390     struct WritePolicyBase
391     {
392         virtual ~WritePolicyBase() {}
393     };
394     
395     /** \brief Policy defining the buffering interface
396
397         The BufferingPolicy defines the buffer handling of the
398         socket. It may provide the follogin members:
399         
400         \see policy_group
401      */
402     struct BufferingPolicyBase
403     {
404         virtual ~BufferingPolicyBase() {}
405     };
406     
407     // The implementation file will for each Policy declared above
408     // define the following (SomePolicy is one of the above):
409     //
410     // struct SomePolicyBase;
411     // typedef UndefinedSomePolicy;
412     // template SomePolicyIs< SocketPolicy, Axis >
413     // template IfSomePolicyIs< SocketPolicy, Axis >
414     // template IfSomePolicyIsNot< SocketPolicy, Axis >
415     //
416     // Additionally the following are defined:
417     //
418     // class SocketPolicyBase
419     // template SocketPolicy< ..policies.. >
420     // template MakeSocketPolicy< ..args.. >
421     // template SocketPolicyIsBaseOf< Base, Derived >
422
423 #   ifdef DOXYGEN
424
425     // The following stub definitions are only visible to doxygen
426
427     /** \brief Alias of AddressingPolicyBase for better readability
428         \see \ref policy_group
429      */
430     typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
431     
432     /** \brief Check single policy axis
433         
434         This template is an example of the \i Policy \c Is family of
435         tempalte metafunctions. It will check, wether \c Trait is a
436         valid compatible Policy class of \c SocketPolicy. \c Trait
437         must be derived from AddressingPolicyBase (respectively \i
438         Policy \c Base). 
439
440         \see \ref policy_group
441      */
442     template <class SocketPolicy, class Trait>
443     struct AddressingPolicyIs
444     {};
445
446     /** \brief Enable template overload depending on policy value
447
448         This template is an exmaple of the \c If \i Policy \c Is
449         family of templates. It is used like <a class="ext"
450         href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
451         to enable a templated overload only, if the AddressingPolicy
452         of \i Policy is compatible with \c Trait (that is the
453         AddressingPolicy of \c Policy is derived from \c Trait).
454
455         \see policy_group
456      */
457     template <class SocketPolicy, class Trait>
458     struct IfAddressingPolicyIs
459     {};
460
461     /** \brief Inversion of \c IfAddressingPolicyIs
462         \see policy_group
463      */
464     template <class SocketPolicy, class Trait>
465     struct IfAddressingPolicyIsNot
466     {};
467
468     /** \brief Baseclass of all SocketPolicies
469
470         \internal
471
472         This class provides the baseclass of all socket policies
473         (bundles). It serves two purposes: 
474         \li It allows us to easily identify a socket policy bundle by
475             checking a classes baseclass.
476         \li It provides an abstract (virtual) interface to access the
477             policy axes
478
479         \see policy_group
480      */
481     struct SocketPolicyBase
482     {
483         /** \brief Polymorphic access to policy axes
484             
485             This is an example of a policy axes accessor. It returns a
486             reference to the policy axes used by the conrecte protocol
487             bundle. This reference can then be checked using RTTI
488             information.
489          */
490         AddressingPolicyBase const & theAddressingPolicy() const = 0;
491     };
492
493     /** \brief Collection of policy classes
494         
495         The SocketPolicy template defines the complete Policy used by
496         the socket library. It contains one policy class for each
497         policy axis. This template takes one policy from each axis as
498         it's template arguments (this example implementation only has
499         AddressingPolicy as an argument).
500
501         A SocketPolicy can be complete or incomplete. An incomplete
502         SocketPolicy will have at least one axis set to \c Undefined
503         \i Policy (or a generic derived class which is used to group
504         some other policies but does not (completely) define the
505         policy behavior). A complete SocketPolicy will have a
506         concrete definition of the desired behavior for each policy
507         axis.
508
509         \see policy_group
510      */
511     template < class AddressingPolicy >
512     struct SocketPolicy
513     {
514         /** \brief Check dynamic policy compatibility
515
516             This method will check the socket policy \a other against
517             this policy. It will check, wether \a other is a base
518             policy (or the same) of this policy. This check is done
519             against the \e dynamic type of \a other using RTTI. It
520             will throw \c std::bad_cast, if the policy is not
521             compatible.
522
523             \param[in] other SocketPolicy to check
524             \throws std::bad_cast if \a other is not a compatible
525                 policy
526          */
527         static void checkBaseOf(SocketPolicyBase const & other);
528     };
529     
530     /** \brief Metafunction to create SocketPolicy
531         
532         This template metafunction simplifies the creation of a
533         SocketPolicy instantiation. It takes any number (that is up to
534         6) of Policy classes as arguments in any Order. It will create
535         a SocketPolicy from these policy classes. Any axis not
536         specified will be left as \c Unspecified \i Policy. 
537
538         \see policy_group
539      */
540     template <class Arg1, class Arg2, class ArgN>
541     struct MakeSocketPolicy
542     {};
543
544     /** \brief Check policy compatibility
545
546         This tempalte metafunction checks, wether the SocketPolicy \c
547         Derived is more specialized than \c Base (and therefore a
548         SocketHandle with policy \c Derived is convertible to a
549         SocketHandle with policy \c Base).
550
551         The metafunction will return true (that is inherits from \c
552         boost::true_type, see the <a class="ext"
553         href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
554         library documentation for more information) if each policy
555         class in \c Base is a baseclass of (or the same as) the
556         corresponding policy class in \c Derived.
557
558         \see policy_group
559      */
560     template <class Base, class Derived>
561     struct SocketPolicyIsBaseOf
562     {};
563
564 #   endif
565
566     /// @}
567 }
568
569 //////////////////////////////hh.e////////////////////////////////////////
570 #include "SocketPolicy.ih"
571 //#include "SocketPolicy.cci"
572 #include "SocketPolicy.ct"
573 //#include "SocketPolicy.cti"
574 #endif
575
576 \f
577 // Local Variables:
578 // mode: c++
579 // c-file-style: "senf"
580 // End: