added some doc comments
[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     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.
87     
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.
96
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.
102
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.
106
107     \doc Example (concrete policy, incomplete policy, compatibility/assignment)
108
109     \section policy_group_details The Policy Framework Classes
110
111    \doc Policy should be Axis here. Make clear, that this information is only 
112    needed when extending the library.
113     
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
117         BufferingPolicy
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)
122
123     Each axis is comprised of a number of classes and templates (all
124     in namespace senf of course):
125
126     <dl>
127     <dt>\e Policy \c Base (ex: AddressingPolicyBase)</dt>
128     <dd>Baseclass of all policies in this axis</dd>
129
130     <dt>\c Unspecified \e Policy  (ex: \ref UnspecifiedAddressingPolicy)</dt>
131     <dd>An alias (typedef) for \e Policy \c Base</dd>
132
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>
137
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>
140
141     <dt>\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
142     <dd>The inverse of above</dd>
143     </dl>
144
145     These classes form the basis of the policy framework. To bind the
146     policy axis together, there are some more classes and templates.
147
148     <dl>
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>
154
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>
160
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>
171
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>
177     </dl>
178
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.
183
184     \section policy_implement Implementing Policy Classes
185
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.
192
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.
198
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
202     SocketHandle).
203
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
208     policy:
209
210     \code
211       struct ExampleAddressingPolicy
212       {
213           template <class Policy>
214           void connect(senf::SocketHandle<Policy> handle, Address & addr,
215                        typename senf::IfCommmunicationPolicyIs<
216                            Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
217       };
218     \endcode
219
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).
227
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>
232
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.
238  */
239
240 /** \defgroup policy_impl_group Policy Implementation classes
241     \ingroup policy_group
242
243     Here you will find all policy classes. Also included are some
244     supporting classes which are used as base classes to build other
245     policy classes.
246  */
247
248 #ifndef HH_SocketPolicy_
249 #define HH_SocketPolicy_ 1
250
251 // Custom includes
252
253 #include "GenericSockAddr.hh"
254
255 //#include "SocketPolicy.mpp"
256 ///////////////////////////////hh.p////////////////////////////////////////
257
258 namespace senf {
259
260     /// \addtogroup policy_group
261     /// @{
262
263     // This may be adapted to change the supported policies (however,
264     // ClientSocketHandle and ServerSocketHandle will probably have to
265     // be adjusted accordingly)
266
267     /** \brief List all policy axis
268
269         \internal
270
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
275         list.
276
277         \see policy_group
278      */
279 #   define SENF_SOCKET_POLICIES                 \
280         (AddressingPolicy)                      \
281         (FramingPolicy)                         \
282         (CommunicationPolicy)                   \
283         (ReadPolicy)                            \
284         (WritePolicy)                           \
285         (BufferingPolicy)
286
287     // Wer define these classes explicitly (and not with some macro
288     // magic) because
289     // a) AddressingPolicyBase is different from all the others
290     // b) We want to document each one explicitly
291
292     /** \brief Policy defining socket addressing
293
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.
297
298         <table class="senf">
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>
304         </table>
305
306         \see policy_group
307      */
308     struct AddressingPolicyBase
309     {
310         virtual ~AddressingPolicyBase() {}
311
312         typedef GenericSockAddr Address;
313     };
314
315     /** \brief Policy defining the framing format
316
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.
320
321         \note This policy axis probably only has two sensible statess:
322         StreamFramingPolicy and DatagramFramingPolicy.
323
324         \see policy_group
325      */
326     struct FramingPolicyBase
327     {
328         virtual ~FramingPolicyBase() {}
329     };
330
331     /** \brief Policy defining, how peers are selected
332
333         The CommunicationPolicy may define two members:
334
335         <table class="senf">
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>
338         </table>
339
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).
347
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.
352
353         \see policy_group
354      */
355     struct CommunicationPolicyBase
356     {
357         virtual ~CommunicationPolicyBase() {}
358     };
359
360     /** \brief Policy defining the readability
361
362         The ReadPolicy defines, wether the socket is readable. It
363         may define two members:
364
365         <table class="senf">
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>
368         </table>
369
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).
374
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.
378
379         \see policy_group
380      */
381     struct ReadPolicyBase
382     {
383         virtual ~ReadPolicyBase() {}
384     };
385
386     /** \brief Policy defining the writability
387
388         The WritePolicy defines, wether the socket is writable. It may
389         define two members:
390
391         <table class="senf">
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>
394         </table>
395
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).
400
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.
404
405         \see policy_group
406      */
407     struct WritePolicyBase
408     {
409         virtual ~WritePolicyBase() {}
410     };
411
412     /** \brief Policy defining the buffering interface
413
414         The BufferingPolicy defines the buffer handling of the
415         socket. It may provide the follogin members:
416
417         \see policy_group
418      */
419     struct BufferingPolicyBase
420     {
421         virtual ~BufferingPolicyBase() {}
422     };
423
424     // The implementation file will for each Policy declared above
425     // define the following (SomePolicy is one of the above):
426     //
427     // struct SomePolicyBase;
428     // typedef UndefinedSomePolicy;
429     // template SomePolicyIs< SocketPolicy, Axis >
430     // template IfSomePolicyIs< SocketPolicy, Axis >
431     // template IfSomePolicyIsNot< SocketPolicy, Axis >
432     //
433     // Additionally the following are defined:
434     //
435     // class SocketPolicyBase
436     // template SocketPolicy< ..policies.. >
437     // template MakeSocketPolicy< ..args.. >
438     // template SocketPolicyIsBaseOf< Base, Derived >
439
440 #   ifdef DOXYGEN
441
442     // The following stub definitions are only visible to doxygen
443
444     /** \brief Alias of AddressingPolicyBase for better readability
445         \see \ref policy_group
446      */
447     typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
448
449     /** \brief Check single policy axis
450
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
455         Policy \c Base).
456
457         \see \ref policy_group
458      */
459     template <class SocketPolicy, class Trait>
460     struct AddressingPolicyIs
461     {};
462
463     /** \brief Enable template overload depending on policy value
464
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).
471
472         \see policy_group
473      */
474     template <class SocketPolicy, class Trait>
475     struct IfAddressingPolicyIs
476     {};
477
478     /** \brief Inversion of \c IfAddressingPolicyIs
479         \see policy_group
480      */
481     template <class SocketPolicy, class Trait>
482     struct IfAddressingPolicyIsNot
483     {};
484
485     /** \brief Baseclass of all SocketPolicies
486
487         \internal
488
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
494             policy axes
495
496         \see policy_group
497      */
498     struct SocketPolicyBase
499     {
500         /** \brief Polymorphic access to policy axes
501
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
505             information.
506          */
507         AddressingPolicyBase const & theAddressingPolicy() const = 0;
508     };
509
510     /** \brief Collection of policy classes
511
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).
517
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
524         axis.
525
526         \see policy_group
527      */
528     template < class AddressingPolicy >
529     struct SocketPolicy
530     {
531         /** \brief Check dynamic policy compatibility
532
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
538             compatible.
539
540             \param[in] other SocketPolicy to check
541             \throws std::bad_cast if \a other is not a compatible
542                 policy
543          */
544         static void checkBaseOf(SocketPolicyBase const & other);
545     };
546
547     /** \brief Metafunction to create SocketPolicy
548
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.
554
555         \see policy_group
556      */
557     template <class Arg1, class Arg2, class ArgN>
558     struct MakeSocketPolicy
559     {};
560
561     /** \brief Check policy compatibility
562
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).
567
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.
574
575         \see policy_group
576      */
577     template <class Base, class Derived>
578     struct SocketPolicyIsBaseOf
579     {};
580
581 #   endif
582
583     /// @}
584 }
585
586 //////////////////////////////hh.e////////////////////////////////////////
587 #include "SocketPolicy.ih"
588 //#include "SocketPolicy.cci"
589 #include "SocketPolicy.ct"
590 //#include "SocketPolicy.cti"
591 #endif
592
593 \f
594 // Local Variables:
595 // mode: c++
596 // fill-column: 100
597 // c-file-style: "senf"
598 // indent-tabs-mode: nil
599 // ispell-local-dictionary: "american"
600 // End: