Fixed whitespace in all files (no tabs)
[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 /** \defgroup policy_impl_group Policy Implementation classes
232     \ingroup policy_group
233
234     Here you will find all policy classes. Also included are some
235     supporting classes which are used as base classes to build other
236     policy classes.
237  */
238
239 #ifndef HH_SocketPolicy_
240 #define HH_SocketPolicy_ 1
241
242 // Custom includes
243
244 #include "GenericSockAddr.hh"
245
246 //#include "SocketPolicy.mpp"
247 ///////////////////////////////hh.p////////////////////////////////////////
248
249 namespace senf {
250
251     /// \addtogroup policy_group
252     /// @{
253
254     // This may be adapted to change the supported policies (however,
255     // ClientSocketHandle and ServerSocketHandle will probably have to
256     // be adjusted accordingly)
257
258     /** \brief List all policy axis
259
260         \internal
261
262         This define symbol is used to configure the policy axis. The
263         base class for each of these axis must be defined explicitly
264         (e.g. AddressingPolicyBase). The implementation files will
265         then automatically generate all the other classes from this
266         list.
267
268         \see policy_group
269      */
270 #   define SENF_SOCKET_POLICIES                 \
271         (AddressingPolicy)                      \
272         (FramingPolicy)                         \
273         (CommunicationPolicy)                   \
274         (ReadPolicy)                            \
275         (WritePolicy)                           \
276         (BufferingPolicy)
277
278     // Wer define these classes explicitly (and not with some macro
279     // magic) because
280     // a) AddressingPolicyBase is different from all the others
281     // b) We want to document each one explicitly
282
283     /** \brief Policy defining socket addressing
284
285         AddressingPolicyBase is the baseclass of all addressing policy
286         classes. When defining a new addressing policy, the following
287         members can be defined. All methods must be static.
288
289         <table class="senf">
290         <tr><td>typedef</td> <td><tt>Address</tt></td>                                   <td>Address type</td></tr>
291         <tr><td>method</td>  <td><tt>void local(FileHandle, Address &)</tt></td>         <td>Get local socket address</td></tr>
292         <tr><td>method</td>  <td><tt>void peer(FileHandle, Address &)</tt></td>          <td>Get remote socket address</td></tr>
293         <tr><td>method</td>  <td><tt>void bind(FileHandle, Address const &)</tt></td>    <td>Bind socket to local address</td></tr>
294         <tr><td>method</tr>  <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
295         </table>
296
297         \see policy_group
298      */
299     struct AddressingPolicyBase
300     {
301         virtual ~AddressingPolicyBase() {}
302
303         typedef GenericSockAddr Address;
304     };
305
306     /** \brief Policy defining the framing format
307
308         This policy does not define any operations since it does have
309         no influence on any method signature. It does however affect
310         the semantics of the \c read() and \c write() operations.
311
312         \note This policy axis probably only has two sensible statess:
313         StreamFramingPolicy and DatagramFramingPolicy.
314
315         \see policy_group
316      */
317     struct FramingPolicyBase
318     {
319         virtual ~FramingPolicyBase() {}
320     };
321
322     /** \brief Policy defining, how peers are selected
323
324         The CommunicationPolicy may define two members:
325
326         <table class="senf">
327         <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
328         <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td>         <td>Accept a new connection</td></tr>
329         </table>
330
331         The \c listen member is straight forward. The \c accept() member
332         must return a new file descriptor (which will be used to
333         create a new SocketHandle of the correct type). Additionally,
334         accept() should only be defined, if the Addressing policy is
335         not \c NoAddressingPolicy (which together with
336         ConnectedCommunicationPolicy would identify a point-to-point
337         link with fixed communication partners).
338
339         \note This Policy only has two meaningful states:
340         ConnectedCommunicationPolicy and
341         UnconnectedCommunicationPolicy. It is probably not sensible to
342         define a new CommunicationPolicy type.
343
344         \see policy_group
345      */
346     struct CommunicationPolicyBase
347     {
348         virtual ~CommunicationPolicyBase() {}
349     };
350
351     /** \brief Policy defining the readability
352
353         The ReadPolicy defines, wether the socket is readable. It
354         may define two members:
355
356         <table class="senf">
357         <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td>                <td>read data from socket</td></tr>
358         <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
359         </table>
360
361         The second member should only be enabled if the communication
362         policy is UnconnectedCommunication (otherwise it does not make
363         sense since the communication partner is fixed) (see
364         AddressingPolicyBase on how to do this).
365
366         \note This Policy only has two meaningful states:
367         ReadablePolicy and NotReadablePolicy. It probably does not
368         make sense to define new read policy types.
369
370         \see policy_group
371      */
372     struct ReadPolicyBase
373     {
374         virtual ~ReadPolicyBase() {}
375     };
376
377     /** \brief Policy defining the writability
378
379         The WritePolicy defines, wether the socket is writable. It may
380         define two members:
381
382         <table class="senf">
383         <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td>              <td>read data from socket</td></tr>
384         <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
385         </table>
386
387         The second member should only be enabled if the communication
388         policy is UnconnectedCommunication (otherwise it does not make
389         sense since the communication partner is fixed) (see
390         AddressingPolicyBase on how to do this).
391
392         \note This Policy only has two meaningful states:
393         WritablePolicy and NotWritablePolicy. It probably does not
394         make sense to define new write policy types.
395
396         \see policy_group
397      */
398     struct WritePolicyBase
399     {
400         virtual ~WritePolicyBase() {}
401     };
402
403     /** \brief Policy defining the buffering interface
404
405         The BufferingPolicy defines the buffer handling of the
406         socket. It may provide the follogin members:
407
408         \see policy_group
409      */
410     struct BufferingPolicyBase
411     {
412         virtual ~BufferingPolicyBase() {}
413     };
414
415     // The implementation file will for each Policy declared above
416     // define the following (SomePolicy is one of the above):
417     //
418     // struct SomePolicyBase;
419     // typedef UndefinedSomePolicy;
420     // template SomePolicyIs< SocketPolicy, Axis >
421     // template IfSomePolicyIs< SocketPolicy, Axis >
422     // template IfSomePolicyIsNot< SocketPolicy, Axis >
423     //
424     // Additionally the following are defined:
425     //
426     // class SocketPolicyBase
427     // template SocketPolicy< ..policies.. >
428     // template MakeSocketPolicy< ..args.. >
429     // template SocketPolicyIsBaseOf< Base, Derived >
430
431 #   ifdef DOXYGEN
432
433     // The following stub definitions are only visible to doxygen
434
435     /** \brief Alias of AddressingPolicyBase for better readability
436         \see \ref policy_group
437      */
438     typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
439
440     /** \brief Check single policy axis
441
442         This template is an example of the \e Policy \c Is family of
443         tempalte metafunctions. It will check, wether \c Trait is a
444         valid compatible Policy class of \c SocketPolicy. \c Trait
445         must be derived from AddressingPolicyBase (respectively \i
446         Policy \c Base).
447
448         \see \ref policy_group
449      */
450     template <class SocketPolicy, class Trait>
451     struct AddressingPolicyIs
452     {};
453
454     /** \brief Enable template overload depending on policy value
455
456         This template is an exmaple of the \c If \e Policy \c Is
457         family of templates. It is used like <a class="ext"
458         href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
459         to enable a templated overload only, if the AddressingPolicy
460         of \e Policy is compatible with \c Trait (that is the
461         AddressingPolicy of \c Policy is derived from \c Trait).
462
463         \see policy_group
464      */
465     template <class SocketPolicy, class Trait>
466     struct IfAddressingPolicyIs
467     {};
468
469     /** \brief Inversion of \c IfAddressingPolicyIs
470         \see policy_group
471      */
472     template <class SocketPolicy, class Trait>
473     struct IfAddressingPolicyIsNot
474     {};
475
476     /** \brief Baseclass of all SocketPolicies
477
478         \internal
479
480         This class provides the baseclass of all socket policies
481         (bundles). It serves two purposes:
482         \li It allows us to easily identify a socket policy bundle by
483             checking a classes baseclass.
484         \li It provides an abstract (virtual) interface to access the
485             policy axes
486
487         \see policy_group
488      */
489     struct SocketPolicyBase
490     {
491         /** \brief Polymorphic access to policy axes
492
493             This is an example of a policy axes accessor. It returns a
494             reference to the policy axes used by the conrecte protocol
495             bundle. This reference can then be checked using RTTI
496             information.
497          */
498         AddressingPolicyBase const & theAddressingPolicy() const = 0;
499     };
500
501     /** \brief Collection of policy classes
502
503         The SocketPolicy template defines the complete Policy used by
504         the socket library. It contains one policy class for each
505         policy axis. This template takes one policy from each axis as
506         it's template arguments (this example implementation only has
507         AddressingPolicy as an argument).
508
509         A SocketPolicy can be complete or incomplete. An incomplete
510         SocketPolicy will have at least one axis set to \c Undefined
511         \e Policy (or a generic derived class which is used to group
512         some other policies but does not (completely) define the
513         policy behavior). A complete SocketPolicy will have a
514         concrete definition of the desired behavior for each policy
515         axis.
516
517         \see policy_group
518      */
519     template < class AddressingPolicy >
520     struct SocketPolicy
521     {
522         /** \brief Check dynamic policy compatibility
523
524             This method will check the socket policy \a other against
525             this policy. It will check, wether \a other is a base
526             policy (or the same) of this policy. This check is done
527             against the \e dynamic type of \a other using RTTI. It
528             will throw \c std::bad_cast, if the policy is not
529             compatible.
530
531             \param[in] other SocketPolicy to check
532             \throws std::bad_cast if \a other is not a compatible
533                 policy
534          */
535         static void checkBaseOf(SocketPolicyBase const & other);
536     };
537
538     /** \brief Metafunction to create SocketPolicy
539
540         This template metafunction simplifies the creation of a
541         SocketPolicy instantiation. It takes any number (that is up to
542         6) of Policy classes as arguments in any Order. It will create
543         a SocketPolicy from these policy classes. Any axis not
544         specified will be left as \c Unspecified \e Policy.
545
546         \see policy_group
547      */
548     template <class Arg1, class Arg2, class ArgN>
549     struct MakeSocketPolicy
550     {};
551
552     /** \brief Check policy compatibility
553
554         This tempalte metafunction checks, wether the SocketPolicy \c
555         Derived is more specialized than \c Base (and therefore a
556         SocketHandle with policy \c Derived is convertible to a
557         SocketHandle with policy \c Base).
558
559         The metafunction will return true (that is inherits from \c
560         boost::true_type, see the <a class="ext"
561         href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
562         library documentation for more information) if each policy
563         class in \c Base is a baseclass of (or the same as) the
564         corresponding policy class in \c Derived.
565
566         \see policy_group
567      */
568     template <class Base, class Derived>
569     struct SocketPolicyIsBaseOf
570     {};
571
572 #   endif
573
574     /// @}
575 }
576
577 //////////////////////////////hh.e////////////////////////////////////////
578 #include "SocketPolicy.ih"
579 //#include "SocketPolicy.cci"
580 #include "SocketPolicy.ct"
581 //#include "SocketPolicy.cti"
582 #endif
583
584 \f
585 // Local Variables:
586 // mode: c++
587 // fill-column: 100
588 // c-file-style: "senf"
589 // indent-tabs-mode: nil
590 // ispell-local-dictionary: "american"
591 // End: