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