]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/vbus_factory.h
update
[l4.git] / l4 / pkg / io / server / src / vbus_factory.h
1 /*
2  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 #pragma once
11
12 #include "main.h"
13 #include "debug.h"
14
15 #include <l4/cxx/avl_map>
16 #include <l4/cxx/hlist>
17 #include <string>
18 #include <typeinfo>
19
20 #include "hw_device.h"
21 #include "vdevice.h"
22
23 namespace Vi {
24
25 template< typename VI, typename HW >
26 class Generic_type_factory
27 : public cxx::H_list_item
28 {
29 private:
30   typedef Generic_type_factory<VI, HW> Self;
31   typedef cxx::H_list<Self> List;
32   typedef typename List::Iterator Iterator;
33
34   static List _for_type;
35
36 public:
37   virtual VI *vcreate(HW *f) = 0;
38   virtual ~Generic_type_factory() {}
39
40   static VI *create(HW *f, bool warn = true);
41
42 protected:
43   explicit Generic_type_factory(std::type_info const *type);
44
45 private:
46   std::type_info const *_type;
47 };
48
49 template< typename VI, typename HW >
50 cxx::H_list<Generic_type_factory<VI,HW> > Generic_type_factory<VI,HW>::_for_type(true);
51
52 typedef Generic_type_factory<Dev_feature, Hw::Dev_feature> Feature_factory;
53 typedef Generic_type_factory<Resource, Resource> Resource_factory;
54
55 class Dev_factory : public cxx::H_list_item
56 {
57 public:
58   virtual Device *vcreate() = 0;
59   virtual Device *vcreate(Hw::Device *f) = 0;
60
61   typedef cxx::Avl_map<std::string, Dev_factory *> Name_map;
62   typedef cxx::H_list<Dev_factory> List;
63   typedef List::Iterator Iterator;
64
65   static List _for_type;
66   std::type_info const *_type;
67
68 protected:
69   explicit Dev_factory(std::type_info const *type);
70
71   static Name_map &name_map()
72   {
73     static Name_map _name_map;
74     return _name_map;
75   }
76
77 public:
78   static Device *create(std::string const &_class);
79   static Device *create(Hw::Device *f, bool warn = true);
80
81 private:
82   Dev_factory(Dev_factory const &);
83   void operator = (Dev_factory const &);
84 };
85
86
87 template< typename VI,  typename HW_BASE, typename HW, typename BASE >
88 class Generic_factory_t : public BASE
89
90 {
91 public:
92
93   Generic_factory_t() : BASE(&typeid(HW)) {}
94
95   VI *vcreate(HW_BASE *dev)
96   {
97 #if 0
98     if (dev->ref_count())
99       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
100              dev->name());
101 #endif
102
103     VI *d = 0;
104     if (HW* h = dynamic_cast<HW*>(dev))
105       d = new VI(h);
106 //    dev->inc_ref_count();
107     return d;
108   }
109
110   VI *vcreate()
111   { return 0; }
112
113 };
114
115 template< typename VI, typename HW >
116 class Feature_factory_t
117 : public Generic_factory_t<VI, Hw::Dev_feature, HW, Feature_factory >
118 {};
119
120 template< typename VI, typename HW >
121 class Resource_factory_t
122 : public Generic_factory_t<VI, Resource, HW, Resource_factory >
123 {};
124
125 template< typename V_DEV, typename HW_DEV = void >
126 class Dev_factory_t :  public Dev_factory
127 {
128 public:
129   typedef HW_DEV Hw_dev;
130   typedef V_DEV  V_dev;
131
132   Dev_factory_t() : Dev_factory(&typeid(Hw_dev))
133   { }
134
135
136   virtual Device *vcreate(Hw::Device *dev)
137   {
138     if (dev->ref_count())
139       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
140              dev->name());
141
142     if (!dynamic_cast<HW_DEV const*>(dev))
143       return 0;
144
145     Device *d = new V_dev(static_cast<Hw_dev*>(dev));
146     dev->inc_ref_count();
147     return d;
148   }
149
150   virtual Device *vcreate()
151   { return 0; }
152
153 };
154
155 template< typename V_DEV >
156 class Dev_factory_t<V_DEV, void> :  public Dev_factory
157 {
158 public:
159   typedef void  Hw_dev;
160   typedef V_DEV V_dev;
161
162   explicit Dev_factory_t(std::string const &_class) : Dev_factory(0)
163   { name_map()[_class] = this; }
164
165
166   virtual Device *vcreate(Hw::Device *)
167   { return 0; }
168
169   virtual Device *vcreate()
170   { return new V_dev; }
171
172 };
173
174 template< typename VI, typename HW >
175 Generic_type_factory<VI, HW>::Generic_type_factory(std::type_info const *type)
176 : _type(type)
177 {
178   if (!type)
179     return;
180
181   printf("GTF: register factory for %s\n", type->name());
182
183   Iterator i = _for_type.end();
184   for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
185     {
186       void *x = 0;
187       // use the compiler catch logic to figure out if TYPE
188       // is a base class of c->_type, if it is we must put
189       // this behind c in the list.
190       if (type->__do_catch(c->_type, &x, 0))
191         i = c;
192     }
193
194   _for_type.insert(this, i);
195 }
196
197 template< typename VI, typename HW >
198 VI *
199 Generic_type_factory<VI, HW>::create(HW *f, bool warn)
200 {
201   if (!f)
202     return 0;
203
204   for (Iterator c = _for_type.begin(); c != _for_type.end(); ++c)
205
206     {
207       VI *v = c->vcreate(f);
208       if (v)
209         return v;
210     }
211
212   if (warn)
213     d_printf(DBG_WARN, "WARNING: cannot fabricate buddy object for '%s'\n",
214              typeid(*f).name());
215   return 0;
216 }
217
218 }
219