507eafdf6e1c8828730503cd9ee42e3ec6221bbb
[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 interface, it does not make much sense
27         (how did I come to include it ??)
28
29     \todo Do we want to support separate read and write policies. This allows to treat pipes within
30         this framework however, is this worth the effort?
31
32     \idea Creating a new Socket will create 4 (!) new instances (The handle, the body, the policy
33         and the protocol) of which 3 (argh) (body, policy and protocol) live on the heap. This is
34         expensive. We should convert all the policy classes to singletons and assign the same
35         instance to all socket bodies with the same policy. This would reduce the number of heap
36         allocations per socket handle to two.
37  */
38
39 /** \defgroup policy_group The Policy Framework
40
41     \image html SocketPolicy.png
42
43     \section policy_group_introduction Introduction to the Policy Framework
44
45     The policy framework conceptually implements a list of parallel inheritance hierarchies each
46     covering a specific interface aspect of the socket handle. The socket handle itself only
47     provides minimal functionality. All further functionality is relayed to a policy class, or more
48     precisely, to a group of policy classes, one for each policy axis. The policy axis are
49
50     <dl><dt><em>addressingPolicy</em></dt><dd>configures, whether a socket is addressable and if
51     so, configures the address type</dd>
52
53     <dt><em>framingPolicy</em></dt> <dd>configures the type of framing the socket provides: either
54     no framing providing a simple i/o stream or packet framing</dd>
55
56     <dt><em>communicationPolicy</em></dt><dd>configures,if and how the communication partner is
57     selected</dd>
58
59     <dt><em>readPolicy</em></dt><dd>configures the readability of the socket</dd>
60
61     <dt><em>writePolicy</em></dt><dd>configures the writability of the socket</dd>
62
63     <dt><em>bufferingPolicy</em></dt><dd>configures, if and how buffering is configured for a
64     socket</dd> </dl>
65
66     The template senf::SocketPolicy combines these policy axis to form a concrete socket policy. In
67     a concrete policy, each of these policy axis is assigned a value, the policy value. This value
68     is identified by a class type, a policy class. E.g. possible values for <em>framingPolicy</em>
69     are <tt>DatagramFramingPolicy</tt> or <tt>StreamFramingPolicy</tt> which are classes derived
70     from the axis base class <tt>FramingPolicyBase</tt>. This base class also doubles as
71     <tt>UnspecifiedFramingPolicy</tt> (which is just a typedef alias).  If a policy axis is assigned
72     this Unspecified type, the axis is left unspecified, the concrete policy will be incomplete.
73     
74     The senf::SocketPolicy template defines the behavior of a socket handle. The socket handle
75     instances do not implement any socket functionality themselves instead defering the
76     implementation to the policy classes. The SocketHandle interface is therefore \e not implemented
77     using virtual members, all important socket functions can be inlined by the compiler to create
78     highly efficient code.
79
80     A senf::SocketPolicy instance can be incomplete. In this case it does \e not completely specify
81     the socket interface, it leaves some aspects open by assigning the Unspecified value to one or
82     more of the policy axis. A senf::SocketHandle based on such a policy will have a reduced
83     interface: It will only support those members for wich the corresponding policies are defined.
84
85     To build a senf::SocketPolicy instance the senf::MakeSocketPolicy helper is provided. This
86     helper template takes any number (it is really limited to 6 Arguments but more arguments don't
87     make sense) of policy classes as it's argument. The MakeSocketPolicy helper will take the
88     arguments in the order they are specified and for each argument will check to which axis the
89     policy class belongs (by checking the base classes of that class) and assign it to the correct
90     policy axis in the senf::SocketPolicy template. If any policy axis are not specified, they are
91     defaulted to their corresponding Unspecified value. This helper frees you to specify the policy
92     classes in any order. An additional feature is, that you may specify a complete policy as a
93     first argument. This policy will then be used to provide default values for unspecified axis.
94
95     Two senf::SocketHandle's with different policies can be \e compatible. If they are, the more
96     specific SocketHandle can be converted (assigned to) the more basic SocketHandle. A SocketHandle
97     is more specific then another SocketHandle if the policy of the former is more specific then
98     that of the latter which means, that for each policy axis separately, the value of that axis of
99     the more specific policy is derived from or the same as the value of that axis in the more basic
100     policy. This is like converting a derived class pointer to a base class pointer, only it happens
101     separately but at the same time for each policy axis:
102
103     \code
104     // This defines an incomplete policy where addressingPolicy, writePolicy and bufferingPolicy
105     // are unspecified
106     typedef senf::MakeSocketPolicy<
107         senf::StreamFramingPolicy,
108         senf::ConnectedCommunicationPolicy,
109         senf::ReadablePolicy
110         >::policy MyReadableSocketPolicy
111
112     typedef senf::ClientSocketHandle<MyReadableSocketPolicy> MyReadableHandle;
113
114     // TCPv4ClientSocketHandle is a socket handle with the policy equivalent to
115     // senf::MakeSocketPolicy<
116     //     INet4AddressingPolicy,
117     //     StreamFramingPolicy,
118     //     ConnectedCommunicationPolicy,
119     //     ReadablePolicy,
120     //     WritablePolicy,
121     //     SocketBufferingPolicy>::policy
122     senf::TCPv4ClientSocketHandle tcpHandle (...);
123
124     MyReadableHandle myHandle (tcpHandle); // Conversion to more basic socket handle
125     \endcode
126
127     \section policy_group_details The Policy Framework Classes
128
129     In the following discussion, deeper insight into C++ and especially the concepts of template
130     meta-programming are needed. Hoewever, this information is only needed if you want to write new
131     policy classes or want to use the policy framework explicitly for your own involved
132     optimizations ... or if you are just plain curious :-)
133     
134     In the following discussion we will use the following conventions:
135     \li \e Axis is one or \c AddressingPolicy, \c FramingPolicy, \c CommunicationPolicy, \c
136         ReadPolicy, \c WritePolicy or \c BufferingPolicy
137     \li \e socketPolicy is any socket policy (that is, an instantiation of the SocketPolicy
138         template)
139     \li \e trait is an any policy class (that is, any class derived from one of the axis base
140         classes)
141
142     Each axis is comprised of a number of classes and templates (all in namespace senf of course):
143
144     <dl><dt>\e Axis \c Base (ex: AddressingPolicyBase)</dt><dd>Baseclass of all policies in this
145     axis</dd>
146
147     <dt>\c Unspecified \e Axis (ex: \ref UnspecifiedAddressingPolicy)</dt> <dd>An alias (typedef)
148     for \e Axis \c Base</dd>
149
150     <dt>\e Axis \c Is < \e socketPolicy, \e trait > (ex: AddressingPolicyIs)</dt> <dd>A template
151     metafunction returning \c boost::true_type, if \e trait (any class derived from \e Axis \c
152     Base) is a compatible policy value of the given \e socketPolicy</dd>
153
154     <dt>\c If \e Axis \c Is < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIs)</dt> <dd>This
155     is a combination of \e Axis \c Is and \c boost::enable_if</dd>
156
157     <dt>\c If \e Axis \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
158     <dd>The inverse of above</dd> </dl>
159
160     These classes form the basis of the policy framework. To bind the policy axis together, there
161     are some more classes and templates.
162
163     <dl><dt>\c class \c SocketPolicyBase</dt> <dd>This class is the base class of the SocketPolicy
164     template. It is used to validate, that a class is really a SocketPolicy (by checking, that it
165     derives from SocketPolicyBase. This is simpler than chacking the template directly).</dd>
166
167     <dt>\c template \c SocketPolicy < \e addressingPolicy, \e framingPolicy, \e communicationPolicy,
168     \e readPolicy, \e writePolicy, \e bufferingPolicy ></dt> <dd>This is the central SocketPolicy
169     template. It combines a complete set of policy classes, one for each axis.</dd>
170
171     <dt>\c template \c MakeSocketPolicy < \e args ></dt> <dd>\c MakeSocketPolicy is a template
172     metafunction which simplifies building SocketPolicy instantiations. It takes any number (ok, up
173     to a maximum of 6) of policy classes as an argument (in any order). It will sort these arguments
174     into the SocketPolicy template arguments. If for some axis no class is specified, it's slot will
175     be filled with \c Unspecified \e Axis. Additionally, the first Argument may optionally be ab
176     arbitrary SocketPolicy. It will provide default values for unspecified axis</dd>
177
178     <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt> <dd>This template
179     metafunction will check, wether the socket policy \e derived is convertible to \e base. This
180     means, that for each axis, the corresponding policy class in \e derived must be derived or be
181     the same as the one on \e base.</dd> </dl>
182
183     \implementation All these classes are created automatically. The \c SENF_SOCKET_POLICIES makro
184     is a Boost.Preprocessor style sequence listing all policy axis. The Boost.Preprocessor library
185     is then used to generate the respective classes.
186
187     \section policy_implement Implementing Policy Classes
188
189     To define a new policy class, derive from the corresponding base class for your policy
190     axies. The only policy axis which might possibly need to be extended are the addressing policy
191     (AddressingPolicyBase) and the buffering policy (BufferingPolicyBase). See the Documentation of
192     these classes for more information on which members can be implemented.
193
194     All members you define must be static. For any of the policy classes, you must only define those
195     members which are supported by your implementation. If you leave out a member you automatically
196     disable the corresponding functionality in the ClientSocketHandle/ServerSocketHandle interface.
197
198     The member prototypes given in the base class documentation only specify the call signature not
199     the way, the member must be defined (FileHandle really is not a FileHandle but an arbitrary
200     SocketHandle).
201
202     If the existence of a member depends on other policies, you should use the
203     <code>If</code><i>SomePolicy</i><code>Is</code> and
204     <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to dynamically enable/disable the
205     member depending on some other policy:
206
207     \code
208       struct ExampleAddressingPolicy
209       {
210           template <class Policy>
211           void connect(senf::SocketHandle<Policy> handle, Address & addr,
212                        typename senf::IfCommmunicationPolicyIs<
213                            Policy, senf::ConnectedCommunicationPolicy>::type * = 0);
214       };
215     \endcode
216
217     The \c connect member in this example will only be enabled, it the communication policy of the
218     socket handle is ConnectedCommunicationPolicy (or a derived type). See <a
219     href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a> for a discussion of
220     the third argument (\c senf::ConnectedCommunicationPolicyIs is based on the \c boost::enable_if
221     template).
222
223     \see \ref extend_policy \n
224          <a class="ext" href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
225          <a class="ext" href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
226          <a class="ext" href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
227
228     \idea We could combine all the \e Axis \c Is templates into a single template. Since the \e
229     trait argument will automatically specify the axis to be used, it is not necessary to specify
230     that axis in the tempalte functor's name. We could even combine this with \c
231     SocketPolicyIsBaseOf.
232  */
233
234 /** \defgroup policy_impl_group Policy Implementation classes
235     \ingroup policy_group
236
237     Here you will find all policy classes. Also included are some
238     supporting classes which are used as base classes to build other
239     policy classes.
240  */
241
242 #ifndef HH_SocketPolicy_
243 #define HH_SocketPolicy_ 1
244
245 // Custom includes
246
247 #include "GenericSockAddr.hh"
248
249 //#include "SocketPolicy.mpp"
250 ///////////////////////////////hh.p////////////////////////////////////////
251
252 namespace senf {
253
254     /// \addtogroup policy_group
255     /// @{
256
257     // This may be adapted to change the supported policies (however, ClientSocketHandle and
258     // ServerSocketHandle will probably have to be adjusted accordingly)
259
260     /** \brief List all policy axis
261
262         \internal
263
264         This define symbol is used to configure the policy axis. The
265         base class for each of these axis must be defined explicitly
266         (e.g. AddressingPolicyBase). The implementation files will
267         then automatically generate all the other classes from this
268         list.
269
270         \see policy_group
271      */
272 #   define SENF_SOCKET_POLICIES                 \
273         (AddressingPolicy)                      \
274         (FramingPolicy)                         \
275         (CommunicationPolicy)                   \
276         (ReadPolicy)                            \
277         (WritePolicy)                           \
278         (BufferingPolicy)
279
280     // Wer define these classes explicitly (and not with some macro
281     // magic) because
282     // a) AddressingPolicyBase is different from all the others
283     // b) We want to document each one explicitly
284
285     /** \brief Policy defining socket addressing
286
287         AddressingPolicyBase is the baseclass of all addressing policy
288         classes. When defining a new addressing policy, the following
289         members can be defined. All methods must be static.
290
291         <table class="senf">
292         <tr><td>typedef</td> <td><tt>Address</tt></td>                                   <td>Address type</td></tr>
293         <tr><td>method</td>  <td><tt>void local(FileHandle, Address &)</tt></td>         <td>Get local socket address</td></tr>
294         <tr><td>method</td>  <td><tt>void peer(FileHandle, Address &)</tt></td>          <td>Get remote socket address</td></tr>
295         <tr><td>method</td>  <td><tt>void bind(FileHandle, Address const &)</tt></td>    <td>Bind socket to local address</td></tr>
296         <tr><td>method</tr>  <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
297         </table>
298
299         \see policy_group
300      */
301     struct AddressingPolicyBase
302     {
303         virtual ~AddressingPolicyBase() {}
304
305         typedef GenericSockAddr Address;
306     };
307
308     /** \brief Policy defining the framing format
309
310         This policy does not define any operations since it does have
311         no influence on any method signature. It does however affect
312         the semantics of the \c read() and \c write() operations.
313
314         \note This policy axis probably only has two sensible statess:
315         StreamFramingPolicy and DatagramFramingPolicy.
316
317         \see policy_group
318      */
319     struct FramingPolicyBase
320     {
321         virtual ~FramingPolicyBase() {}
322     };
323
324     /** \brief Policy defining, how peers are selected
325
326         The CommunicationPolicy may define two members:
327
328         <table class="senf">
329         <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
330         <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td>         <td>Accept a new connection</td></tr>
331         </table>
332
333         The \c listen member is straight forward. The \c accept() member
334         must return a new file descriptor (which will be used to
335         create a new SocketHandle of the correct type). Additionally,
336         accept() should only be defined, if the Addressing policy is
337         not \c NoAddressingPolicy (which together with
338         ConnectedCommunicationPolicy would identify a point-to-point
339         link with fixed communication partners).
340
341         \note This Policy only has two meaningful states:
342         ConnectedCommunicationPolicy and
343         UnconnectedCommunicationPolicy. It is probably not sensible to
344         define a new CommunicationPolicy type.
345
346         \see policy_group
347      */
348     struct CommunicationPolicyBase
349     {
350         virtual ~CommunicationPolicyBase() {}
351     };
352
353     /** \brief Policy defining the readability
354
355         The ReadPolicy defines, wether the socket is readable. It
356         may define two members:
357
358         <table class="senf">
359         <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td>                <td>read data from socket</td></tr>
360         <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
361         </table>
362
363         The second member should only be enabled if the communication
364         policy is UnconnectedCommunication (otherwise it does not make
365         sense since the communication partner is fixed) (see
366         AddressingPolicyBase on how to do this).
367
368         \note This Policy only has two meaningful states:
369         ReadablePolicy and NotReadablePolicy. It probably does not
370         make sense to define new read policy types.
371
372         \see policy_group
373      */
374     struct ReadPolicyBase
375     {
376         virtual ~ReadPolicyBase() {}
377     };
378
379     /** \brief Policy defining the writability
380
381         The WritePolicy defines, wether the socket is writable. It may
382         define two members:
383
384         <table class="senf">
385         <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td>              <td>read data from socket</td></tr>
386         <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
387         </table>
388
389         The second member should only be enabled if the communication
390         policy is UnconnectedCommunication (otherwise it does not make
391         sense since the communication partner is fixed) (see
392         AddressingPolicyBase on how to do this).
393
394         \note This Policy only has two meaningful states:
395         WritablePolicy and NotWritablePolicy. It probably does not
396         make sense to define new write policy types.
397
398         \see policy_group
399      */
400     struct WritePolicyBase
401     {
402         virtual ~WritePolicyBase() {}
403     };
404
405     /** \brief Policy defining the buffering interface
406
407         The BufferingPolicy defines the buffer handling of the
408         socket. It may provide the follogin members:
409
410         \see policy_group
411      */
412     struct BufferingPolicyBase
413     {
414         virtual ~BufferingPolicyBase() {}
415     };
416
417     // The implementation file will for each Policy declared above
418     // define the following (SomePolicy is one of the above):
419     //
420     // struct SomePolicyBase;
421     // typedef UndefinedSomePolicy;
422     // template SomePolicyIs< SocketPolicy, Axis >
423     // template IfSomePolicyIs< SocketPolicy, Axis >
424     // template IfSomePolicyIsNot< SocketPolicy, Axis >
425     //
426     // Additionally the following are defined:
427     //
428     // class SocketPolicyBase
429     // template SocketPolicy< ..policies.. >
430     // template MakeSocketPolicy< ..args.. >
431     // template SocketPolicyIsBaseOf< Base, Derived >
432
433 #   ifdef DOXYGEN
434
435     // The following stub definitions are only visible to doxygen
436
437     /** \brief Alias of AddressingPolicyBase for better readability
438         \see \ref policy_group
439      */
440     typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
441
442     /** \brief Check single policy axis
443
444         This template is an example of the \e Axis \c Is family of
445         tempalte metafunctions. It will check, wether \c Trait is a
446         valid compatible Policy class of \c SocketPolicy. \c Trait
447         must be derived from AddressingPolicyBase (respectively \i
448         Policy \c Base).
449
450         \see \ref policy_group
451      */
452     template <class SocketPolicy, class Trait>
453     struct AddressingPolicyIs
454     {};
455
456     /** \brief Enable template overload depending on policy value
457
458         This template is an exmaple of the \c If \e Axis \c Is
459         family of templates. It is used like <a class="ext"
460         href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
461         to enable a templated overload only, if the AddressingPolicy
462         of \e Axis is compatible with \c Trait (that is the
463         AddressingPolicy of \c Policy is derived from \c Trait).
464
465         \see policy_group
466      */
467     template <class SocketPolicy, class Trait>
468     struct IfAddressingPolicyIs
469     {};
470
471     /** \brief Inversion of \c IfAddressingPolicyIs
472         \see policy_group
473      */
474     template <class SocketPolicy, class Trait>
475     struct IfAddressingPolicyIsNot
476     {};
477
478     /** \brief Baseclass of all SocketPolicies
479
480         \internal
481
482         This class provides the baseclass of all socket policies
483         (bundles). It serves two purposes:
484         \li It allows us to easily identify a socket policy bundle by
485             checking a classes baseclass.
486         \li It provides an abstract (virtual) interface to access the
487             policy axes
488
489         \see policy_group
490      */
491     struct SocketPolicyBase
492     {
493         /** \brief Polymorphic access to policy axes
494
495             This is an example of a policy axes accessor. It returns a
496             reference to the policy axes used by the conrecte protocol
497             bundle. This reference can then be checked using RTTI
498             information.
499          */
500         AddressingPolicyBase const & theAddressingPolicy() const = 0;
501     };
502
503     /** \brief Collection of policy classes
504
505         The SocketPolicy template defines the complete Policy used by
506         the socket library. It contains one policy class for each
507         policy axis. This template takes one policy from each axis as
508         it's template arguments (this example implementation only has
509         AddressingPolicy as an argument).
510
511         A SocketPolicy can be complete or incomplete. An incomplete
512         SocketPolicy will have at least one axis set to \c Undefined
513         \e Axis (or a generic derived class which is used to group
514         some other policies but does not (completely) define the
515         policy behavior). A complete SocketPolicy will have a
516         concrete definition of the desired behavior for each policy
517         axis.
518
519         \see policy_group
520      */
521     template < class AddressingPolicy >
522     struct SocketPolicy
523     {
524         /** \brief Check dynamic policy compatibility
525
526             This method will check the socket policy \a other against
527             this policy. It will check, wether \a other is a base
528             policy (or the same) of this policy. This check is done
529             against the \e dynamic type of \a other using RTTI. It
530             will throw \c std::bad_cast, if the policy is not
531             compatible.
532
533             \param[in] other SocketPolicy to check
534             \throws std::bad_cast if \a other is not a compatible
535                 policy
536          */
537         static void checkBaseOf(SocketPolicyBase const & other);
538     };
539
540     /** \brief Metafunction to create SocketPolicy
541
542         This template metafunction simplifies the creation of a
543         SocketPolicy instantiation. It takes any number (that is up to
544         6) of Policy classes as arguments in any Order. It will create
545         a SocketPolicy from these policy classes. Any axis not
546         specified will be left as \c Unspecified \e Axis.
547
548         \see policy_group
549      */
550     template <class Arg1, class Arg2, class ArgN>
551     struct MakeSocketPolicy
552     {};
553
554     /** \brief Check policy compatibility
555
556         This tempalte metafunction checks, wether the SocketPolicy \c
557         Derived is more specialized than \c Base (and therefore a
558         SocketHandle with policy \c Derived is convertible to a
559         SocketHandle with policy \c Base).
560
561         The metafunction will return true (that is inherits from \c
562         boost::true_type, see the <a class="ext"
563         href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a>
564         library documentation for more information) if each policy
565         class in \c Base is a baseclass of (or the same as) the
566         corresponding policy class in \c Derived.
567
568         \see policy_group
569      */
570     template <class Base, class Derived>
571     struct SocketPolicyIsBaseOf
572     {};
573
574 #   endif
575
576     /// @}
577 }
578
579 //////////////////////////////hh.e////////////////////////////////////////
580 #include "SocketPolicy.ih"
581 //#include "SocketPolicy.cci"
582 #include "SocketPolicy.ct"
583 //#include "SocketPolicy.cti"
584 #endif
585
586 \f
587 // Local Variables:
588 // mode: c++
589 // fill-column: 100
590 // c-file-style: "senf"
591 // indent-tabs-mode: nil
592 // ispell-local-dictionary: "american"
593 // End: