6b98b155e5e5d24850b7728b04b52389ffe464ba
[senf.git] / PPI / AnnotationRouter.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.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 AnnotationRouter public header */
25
26 #ifndef HH_AnnotationRouter_
27 #define HH_AnnotationRouter_ 1
28
29 // Custom includes
30 #include <boost/ptr_container/ptr_map.hpp>
31 #include "Module.hh"
32 #include "Connectors.hh"
33
34 //#include "AnnotationRouter.mpp"
35 ///////////////////////////////hh.p////////////////////////////////////////
36
37 namespace senf {
38 namespace ppi {
39 namespace module {
40
41     /** \brief Route packets to destination according to some annotation value
42
43         This router takes packet on a single input and directs them to one of it outputs depending
44         on a packet annotation. Each output connected will be associated with a single annotation
45         value. Incoming packets for which no matching output is found are directed to a default
46         output. If this output is left unconnected, those packets will be dropped.
47
48         The \a AnnotationType template parameter defines the routing key. This annotation must
49         support the following operations:
50         \li Comparison with '<'
51         \li Copy-construction
52         \li Output streaming to an ostream via '<<'
53
54         The following annotation can be used to route the packets according to a mac address.
55         \code
56         struct TargetInterface
57         {
58             senf::MACAddress mac;
59
60             bool operator< (TargetInterface const & other) 
61                 { return mac < other.mac; }
62
63             TargetInterface(senf::MACAddress const & m) 
64                 : mac (m) {}
65         };
66
67         std::ostream & operator<<(std::ostream & os, TargetInterface const & v)
68             { os << v.mac; return os; }
69         \endcode
70
71         The additional senf::MACAddress constructor allows to construct an instance directly from a
72         mac address and allows to pass a senf::MACAddress value as routing key directly:
73
74         \code
75         senf::ppi::module::AnnotationRouter router;
76
77         senf::ppi::connect(router, target1, senf::MACAddress::from_string("00:1a:2b:04:06:08"));
78         \endcode
79
80         The special senf::ppi::connect() overload takes a third argument, the routing key. This must
81         be an AnnotationType value or must be (explicitly) convertible to AnnotationType.
82
83         The input will be throttled whenever any of the outputs except \a defaultOutput are
84         throttled.
85
86         \ingroup routing_modules
87
88         \todo Call Module::v_init() on every connection change and remove disconnected connections
89         from the container 
90      */
91     template <class AnnotationType>
92     class AnnotationRouter : public Module
93     {
94         SENF_PPI_MODULE(AnnotationRouter);
95     public:
96         connector::PassiveInput<> input;
97         connector::ActiveOutput<> defaultOutput;
98         
99         AnnotationRouter();
100
101         struct DuplicateKeyException : public senf::Exception
102         { DuplicateKeyException(AnnotationType const & key) 
103               : senf::Exception("Duplicate senf::ppi::module::AnnotationRouter routing key")
104                 { append(boost::lexical_cast<std::string>(key)); } };
105
106     private:
107         connector::ActiveOutput<> & newOutput(AnnotationType const & key);
108
109 #ifndef DOXYGEN
110         // I didn't get template friend functions to work ...
111     public:
112 #endif
113         template <class Target>
114         connector::GenericActiveOutput & connect(Target & target, AnnotationType const & key);
115
116     private:
117         void request();
118         
119         typedef boost::ptr_map<AnnotationType, connector::ActiveOutput<> > Outputs;
120         Outputs outputs_;
121     };
122
123 }
124
125 #ifndef DOXYGEN
126
127     template <class Target, class AnnotationType, class ArgType>
128     connector::GenericActiveOutput & connect(
129         module::AnnotationRouter<AnnotationType> & source, Target & target, 
130         ArgType const & key);
131
132 #endif
133
134 }}
135
136 ///////////////////////////////hh.e////////////////////////////////////////
137 //#include "AnnotationRouter.cci"
138 #include "AnnotationRouter.ct"
139 #include "AnnotationRouter.cti"
140 #endif
141
142 \f
143 // Local Variables:
144 // mode: c++
145 // fill-column: 100
146 // comment-column: 40
147 // c-file-style: "senf"
148 // indent-tabs-mode: nil
149 // ispell-local-dictionary: "american"
150 // compile-command: "scons -u test"
151 // End: