switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / PPI / AnnotationRouter.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief AnnotationRouter public header */
30
31 #ifndef HH_SENF_PPI_AnnotationRouter_
32 #define HH_SENF_PPI_AnnotationRouter_ 1
33
34 // Custom includes
35 #include <boost/ptr_container/ptr_map.hpp>
36 #include <senf/Utils/String.hh>
37 #include "Module.hh"
38 #include "Connectors.hh"
39 #include "MultiConnectorMixin.hh"
40
41 //#include "AnnotationRouter.mpp"
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43
44 namespace senf {
45 namespace ppi {
46 namespace module {
47
48     /** \brief %Route packets to destination according to some annotation value
49
50         This router takes packet on a single input and directs them to one of it outputs depending
51         on a \ref packet_usage_annotation "packet annotation". Each output connected
52         will be associated with a single annotation value. Incoming packets for which no matching
53         output is found are directed to a default output. If this output is left unconnected, those
54         packets will be dropped.
55
56         The \a AnnotationType template parameter defines the routing key. This annotation must
57         support the following operations:
58         \li Comparison with '<' (\c LessThanComparable concept)
59         \li Copy construction and copy assignment (\c Copyable and \c Assignable concepts)
60             (e.g. via compiler synthesized copy constructor and assignment operator)
61         \li Output streaming to an ostream via '\c <<' (for error description purposes) (\c
62             OutputStreamable concept)
63
64         The following annotation can be used to route the packets according to a mac address.
65         \code
66         struct TargetInterface
67         {
68             senf::MACAddress mac;
69
70             bool operator< (TargetInterface const & other)
71                 { return mac < other.mac; }
72
73             TargetInterface(senf::MACAddress const & m)
74                 : mac (m) {}
75         };
76
77         std::ostream & operator<<(std::ostream & os, TargetInterface const & v)
78             { os << v.mac; return os; }
79         \endcode
80
81         The additional senf::MACAddress constructor allows to construct an instance directly from a
82         mac address and allows to pass a senf::MACAddress value as routing key directly:
83
84         \code
85         senf::ppi::module::AnnotationRouter<TargetInterface> router;
86
87         senf::ppi::connect(router, target1, senf::MACAddress::from_string("00:1a:2b:04:06:08"));
88         \endcode
89
90         The special senf::ppi::connect() overload takes a third argument, the routing key. This must
91         be an AnnotationType value or must be (explicitly) convertible to AnnotationType.
92
93         The input will be throttled whenever any of the outputs except \a defaultOutput are
94         throttled.
95
96         \ingroup routing_modules
97
98         \todo Call Module::v_init() on every connection change and remove disconnected connections
99         from the container
100      */
101     template <class AnnotationType>
102     class AnnotationRouter
103         : public Module,
104           public MultiConnectorMixin< AnnotationRouter<AnnotationType>,
105                                         connector::ActiveOutput<>,
106                                         AnnotationType >
107     {
108         SENF_PPI_MODULE(AnnotationRouter);
109     public:
110         connector::PassiveInput<> input;
111         connector::ActiveOutput<> defaultOutput;
112
113         AnnotationRouter();
114
115         struct DuplicateKeyException : public senf::Exception
116         { DuplicateKeyException(AnnotationType const & key)
117               : senf::Exception("Duplicate senf::ppi::module::AnnotationRouter routing key ")
118                 { append( senf::str(key)); } };
119
120     private:
121         AnnotationType connectorSetup(connector::ActiveOutput<> & conn, AnnotationType const & key);
122         void request();
123
124         friend class MultiConnectorMixin< AnnotationRouter<AnnotationType>,
125                                             connector::ActiveOutput<>,
126                                             AnnotationType >;
127     };
128
129 }}}
130
131 //-/////////////////////////////////////////////////////////////////////////////////////////////////
132 //#include "AnnotationRouter.cci"
133 #include "AnnotationRouter.ct"
134 //#include "AnnotationRouter.cti"
135 #endif
136
137 \f
138 // Local Variables:
139 // mode: c++
140 // fill-column: 100
141 // comment-column: 40
142 // c-file-style: "senf"
143 // indent-tabs-mode: nil
144 // ispell-local-dictionary: "american"
145 // compile-command: "scons -u test"
146 // End: