StateFS
 All Classes Files Functions Variables Typedefs Enumerations Groups Pages
provider.hpp
1 #ifndef _STATEFS_PROVIDER_HPP_
2 #define _STATEFS_PROVIDER_HPP_
3 
4 #include <statefs/provider.h>
5 
6 #include <cor/util.hpp>
7 
8 #include <string>
9 #include <map>
10 #include <memory>
11 
12 #include <string.h>
13 // TODO TMP
14 #include <iostream>
15 
16 namespace statefs {
17 
18 class ANode
19 {
20 public:
21  virtual ::statefs_node *get_node() =0;
22  virtual ::statefs_node const* get_node() const =0;
23  virtual ::statefs_node_type get_type() const =0;
24  virtual std::string get_name() const =0;
25  virtual void release() =0;
26  virtual ~ANode();
27 };
28 
29 class ABranch
30 {
31 public:
32  virtual ::statefs_branch *get_branch() =0;
33  virtual ::statefs_branch const* get_branch() const =0;
34  virtual ~ABranch();
35 };
36 
37 
38 static inline statefs_node* node_from(statefs_provider *v)
39 {
40  return &v->root.node;
41 }
42 
43 static inline statefs_node const* node_from(statefs_provider const* v)
44 {
45  return &v->root.node;
46 }
47 
48 template <typename T>
49 statefs_node* node_from(T *v)
50 {
51  return &v->node;
52 }
53 
54 template <typename T>
55 statefs_node const* node_from(T const* v)
56 {
57  return &v->node;
58 }
59 
60 template <typename T>
61 T* node_to(::statefs_node *n)
62 {
63  return cor::member_container(n, &T::node);
64 }
65 
66 template <>
67 statefs_provider* node_to<statefs_provider>(::statefs_node *);
68 
69 template <typename NodeT>
70 class NodeWrapper : public NodeT, public ANode
71 {
72 public:
73  ::statefs_node *node_cast()
74  { return node_from(static_cast<NodeT*>(this)); }
75  ::statefs_node const* node_cast() const
76  { return node_from(static_cast<NodeT const*>(this)); }
77 
78  virtual ::statefs_node *get_node() { return node_cast(); }
79  virtual ::statefs_node const* get_node() const { return node_cast(); }
80  virtual ::statefs_node_type get_type() const { return node_cast()->type; }
81  virtual std::string get_name() const { return node_cast()->name; }
82 
83 
84  NodeWrapper(char const *name, statefs_node const& node_template)
85  {
86  memcpy(node_cast(), &node_template, sizeof(statefs_node));
87  node_cast()->name = strdup(name);
88  node_cast()->release = &release_bridge;
89  }
90  virtual ~NodeWrapper()
91  {
92  free(const_cast<char*>(node_cast()->name));
93  }
94 
95 private:
96  static void release_bridge(::statefs_node *n)
97  {
98  NodeWrapper *self = static_cast<NodeWrapper*>(node_to<NodeT>(n));
99  static_cast<ANode*>(self)->release();
100  }
101 };
102 
103 template <typename T>
104 statefs_branch* branch_from(T *v)
105 {
106  return &v->branch;
107 }
108 
109 template <typename T>
110 statefs_branch const* branch_from(T const* v)
111 {
112  return &v->branch;
113 }
114 
115 static inline statefs_branch* branch_from(statefs_provider *v)
116 {
117  return &v->root.branch;
118 }
119 
120 static inline statefs_branch const* branch_from(statefs_provider const* v)
121 {
122  return &v->root.branch;
123 }
124 
125 template <typename BranchT>
127 
128 template <typename T>
129 BranchWrapper<T> *branch_to(statefs_branch *src)
130 {
131  T *t = cor::member_container(src, &T::branch);
132  return static_cast<BranchWrapper<T> *>(t);
133 }
134 
135 template <typename T>
136 BranchWrapper<T> const* branch_to(statefs_branch const* src)
137 {
138  T const* t = cor::member_container(src, &T::branch);
139  return static_cast<BranchWrapper<T> const*>(t);
140 }
141 
142 template <>
143 BranchWrapper<statefs_provider> *branch_to<statefs_provider>(statefs_branch *);
144 
145 template <>
146 BranchWrapper<statefs_provider> const* branch_to<statefs_provider>(statefs_branch const*);
147 
148 template <typename BranchT>
149 class BranchWrapper : public NodeWrapper<BranchT>
150 {
151 public:
152 
153  ::statefs_branch *branch_cast()
154  { return branch_from(static_cast<BranchT*>(this)); }
155  ::statefs_branch const* branch_cast() const
156  { return branch_from(static_cast<BranchT const*>(this)); }
157 
158  BranchWrapper
159  (char const *name
160  , statefs_node const& node_template
161  , statefs_branch const &branch_template)
162  : NodeWrapper<BranchT>(name, node_template)
163  {
164  memcpy(branch_cast(), &branch_template, sizeof(statefs_branch));
165  }
166 
167  static BranchWrapper<BranchT> *self_cast(statefs_branch *src)
168  {
169  return branch_to<BranchT>(src);
170  }
171 
172  static BranchWrapper<BranchT> const* self_cast(statefs_branch const* src)
173  {
174  return branch_to<BranchT>(src);
175  }
176 
177 };
178 
179 
181 {
182 public:
183  typedef std::shared_ptr<ANode> child_ptr;
184 
185 protected:
186  typedef std::map<std::string, child_ptr> storage_type;
187  typedef storage_type::const_iterator iter_type;
188 
189 public:
190 
191  BranchStorage();
192 
193  child_ptr insert(child_ptr child);
194  child_ptr insert(ANode *child);
195 
196 protected:
197 
198  statefs_node* find(char const*) const;
199  statefs_node* get(statefs_handle_t) const;
200  statefs_handle_t first() const;
201  void next(statefs_handle_t*) const;
202  bool release(statefs_handle_t) const;
203 
204 private:
205 
206  storage_type props_;
207 };
208 
209 template <class BranchT>
210 class Branch : public BranchWrapper<BranchT>, public BranchStorage
211 {
212 private:
213 
214  static const statefs_branch branch_template;
215 
217 
218  static statefs_node * child_find(statefs_branch const* branch
219  , char const *name)
220  {
221  auto self = self_cast(branch);
222  return self->BranchStorage::find(name);
223  }
224 
225  static statefs_node * child_get(statefs_branch const* branch, statefs_handle_t h)
226  {
227  auto self = self_cast(branch);
228  return self->BranchStorage::get(h);
229  }
230 
231  static statefs_handle_t child_first(statefs_branch const* branch)
232  {
233  auto self = self_cast(branch);
234  return self->BranchStorage::first();
235  }
236 
237  static void child_next(statefs_branch const* branch, statefs_handle_t *h)
238  {
239  auto self = self_cast(branch);
240  return self->BranchStorage::next(h);
241  }
242 
243  static bool child_release(statefs_branch const* branch, statefs_handle_t h)
244  {
245  auto self = self_cast(branch);
246  return self->BranchStorage::release(h);
247  }
248 
249 protected:
250  // implement
251  // static WrapperT const *self_cast(statefs_branch const*);
252  // in WrapperT
253  static Branch const *self_cast(statefs_branch const* branch)
254  {
255  return static_cast<Branch const*>
256  (base_type::self_cast(branch));
257  }
258 
259 public:
260  Branch(char const *name, statefs_node const& node_template)
261  : base_type(name, node_template, branch_template)
262  {}
263 
264  virtual ~Branch() {}
265 };
266 
267 
268 class PropertyWrapper : public NodeWrapper<statefs_property>
269 {
271 
272  static const statefs_node node_template;
273 public:
274  PropertyWrapper(char const *name);
275  virtual ~PropertyWrapper();
276 
277  static PropertyWrapper *self_cast(::statefs_property *);
278  static PropertyWrapper const* self_cast(::statefs_property const*);
279 };
280 
282 {
283 public:
284  virtual ~APropertyAccessor();
285 
286  virtual int read(char *dst, statefs_size_t len, statefs_off_t off) =0;
287  virtual int write(char const*, statefs_size_t, statefs_off_t) =0;
288 };
289 
291 {
292 public:
293  AProperty(char const *name);
294  virtual ~AProperty();
295 
296  virtual int getattr() const =0;
297  virtual statefs_ssize_t size() const =0;
298  virtual APropertyAccessor* open(int flags) =0;
299 
300  virtual bool connect(::statefs_slot *) =0;
301  virtual void disconnect() =0;
302 
303  static AProperty *self_cast(::statefs_property *p);
304  static AProperty const* self_cast(::statefs_property const* p);
305 };
306 
307 template <typename T, typename HandleT>
309 {
310 public:
311  BasicPropertyAccessor(std::shared_ptr<T> p, HandleT *h)
312  : prop_(p), handle_(h) {}
313 
314  virtual int read(char *dst, statefs_size_t len, statefs_off_t off)
315  {
316  return prop_->read(handle_.get(), dst, len, off);
317  }
318 
319  virtual int write(char const *src, statefs_size_t len, statefs_off_t off)
320  {
321  return prop_->write(handle_.get(), src, len, off);
322  }
323 
324 protected:
325  std::shared_ptr<T> prop_;
326  std::unique_ptr<HandleT> handle_;
327 };
328 
329 template <typename T, typename HandleT>
330 BasicPropertyAccessor<T, HandleT>* mk_prop_accessor
331 (std::shared_ptr<T> p, HandleT *h)
332 {
333  return new BasicPropertyAccessor<T, HandleT>(p, h);
334 }
335 
336 template <typename T>
337 class APropertyOwner : public AProperty
338 {
339 public:
340  template <typename ... Args>
341  APropertyOwner(char const *name, Args&& ...args)
342  : AProperty(name)
343  , impl_(new T(this, args...))
344  {}
345 
346  virtual ~APropertyOwner() {}
347 
348  virtual int getattr() const { return impl_->getattr(); }
349  virtual statefs_ssize_t size() const { return impl_->size(); }
350  virtual APropertyAccessor* open(int flags) =0;
351 
352  virtual bool connect(::statefs_slot *s) { return impl_->connect(s); }
353  virtual void disconnect() { return impl_->disconnect(); }
354 
355  virtual void release() { return impl_->release(); }
356 
357 protected:
358  std::shared_ptr<T> impl_;
359 };
360 
361 template <typename T, typename HandleT>
363 {
364 public:
365  template <typename ... Args>
366  BasicPropertyOwner(char const *name, Args&& ...args)
367  : APropertyOwner<T>(name, args...)
368  {}
369 
370  template <typename ... Args>
371  BasicPropertyOwner(std::string const &name, Args&& ...args)
372  : APropertyOwner<T>(name.c_str(), args...)
373  {}
374 
375  virtual statefs::APropertyAccessor* open(int flags)
376  {
377  return statefs::mk_prop_accessor(this->impl_, new HandleT());
378  }
379 
380  std::shared_ptr<T> get_impl() { return this->impl_; }
381 };
382 
383 class Namespace : public Branch<statefs_namespace>
384 {
386  static const statefs_node node_template;
387 
388 public:
389  Namespace(char const *name);
390  virtual ~Namespace();
391 };
392 
393 class AProvider : public Branch<statefs_provider>
394 {
395 public:
396  AProvider(char const *name, statefs_server *server);
397  virtual ~AProvider();
398 
399 protected:
400  static AProvider* self_cast();
401 
402  void event(statefs_event);
403 
404 private:
406 
407  static const statefs_io io_template;
408  static const statefs_node node_template;
409 
410  static int getattr(::statefs_property const *);
411  static statefs_ssize_t size(::statefs_property const *);
412  static statefs_handle_t open(::statefs_property *self, int flags);
413  static int read(statefs_handle_t h, char *dst, statefs_size_t len, statefs_off_t off);
414  static int write(statefs_handle_t, char const*, statefs_size_t, statefs_off_t);
415  static void close(statefs_handle_t);
416  static bool connect(::statefs_property *, ::statefs_slot *);
417  static void disconnect(::statefs_property *);
418 
419  void init_data();
420 
421  statefs_server *server_;
422 };
423 
424 // class Namespace : public ABranch
425 // {
426 // static statefs_node node_template;
427 // protected:
428 // typedef statefs::BranchWrapper<statefs_namespace> data_type;
429 // public:
430 // static Namespace *self_cast(statefs_branch*);
431 // static Namespace const* self_cast(statefs_branch const*);
432 
433 // Namespace(char const* name)
434 // : prop_(name, node_template)
435 // {
436 // }
437 
438 // virtual statefs_node *get_node()
439 // {
440 // return &prop_.node;
441 // }
442 // virtual statefs_node const* get_node() const
443 // {
444 // return &prop_.node;
445 // }
446 
447 // virtual statefs_node_type get_type() const
448 // {
449 // return prop_.node.type;
450 // }
451 
452 // protected:
453 // data_type data_;
454 // static data_type Namespace::* data_offset_;
455 // };
456 
457 extern template class NodeWrapper<statefs_property>;
458 extern template class NodeWrapper<statefs_namespace>;
459 extern template class NodeWrapper<statefs_provider>;
460 
461 extern template class BranchWrapper<statefs_provider>;
462 extern template class BranchWrapper<statefs_namespace>;
463 
464 } // namespace
465 
466 
467 #endif // _STATEFS_PROVIDER_HPP_