COSA
An Object-Oriented Platform for Arduino Programming
Registry.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_REGISTRY_HH
22 #define COSA_REGISTRY_HH
23 
24 #include "Cosa/Types.h"
25 #include "Cosa/EEPROM.hh"
26 #include "Cosa/IOStream.hh"
27 
36 class Registry {
37 public:
41  enum type_t {
42  ITEM = 0,
43  ITEM_LIST = 1,
44  ACTION = 2,
45  BLOB = 3,
46  APPL = 4
47  } __attribute__((packed));
48 
52  enum storage_t {
53  IN_PROGMEM = 0,
54  IN_SRAM = 1,
55  IN_EEMEM = 2,
56  } __attribute__((packed));
57 
59  static const uint8_t STORAGE_MASK = 0x7f;
60 
62  static const uint8_t READONLY = 0x80;
63 
67  struct item_t {
70  uint8_t attr;
71  };
72 
74  typedef const PROGMEM item_t* item_P;
75 
77  typedef const PROGMEM item_P* item_vec_P;
78 
84  static type_t get_type(item_P item)
85  {
86  return ((type_t) pgm_read_byte(&item->type));
87  }
88 
95  static str_P get_name(item_P item)
96  __attribute__((always_inline))
97  {
98  return ((str_P) pgm_read_word(&item->name));
99  }
100 
106  static storage_t get_storage(item_P item)
107  __attribute__((always_inline))
108  {
109  return ((storage_t) (pgm_read_byte(&item->attr) & STORAGE_MASK));
110  }
111 
117  static bool is_readonly(item_P item)
118  __attribute__((always_inline))
119  {
120  return ((pgm_read_byte(&item->attr) & READONLY) != 0);
121  }
122 
126  struct item_list_t {
128  uint8_t length;
129  item_vec_P list;
130  };
131 
133  typedef const PROGMEM item_list_t* item_list_P;
134 
142  static item_list_P to_list(item_P item)
143  __attribute__((always_inline))
144  {
145  return (get_type(item) == ITEM_LIST ? (item_list_P) item : NULL);
146  }
147 
153  static int get_length(item_list_P list)
154  __attribute__((always_inline))
155  {
156  if (UNLIKELY(get_type(&list->item) != ITEM_LIST)) return (EINVAL);
157  return ((int) pgm_read_byte(&list->length));
158  }
159 
163  class Iterator {
164  private:
165  item_vec_P m_vec;
166  uint8_t m_length;
167  uint8_t m_next;
168  public:
173  Iterator(item_list_P list) :
174  m_vec((item_vec_P) pgm_read_word(&list->list)),
175  m_length((uint8_t) pgm_read_byte(&list->length)),
176  m_next(0)
177  {}
178 
182  item_P next()
183  __attribute__((always_inline))
184  {
185  if (UNLIKELY(m_next == m_length)) return (NULL);
186  return ((item_P) pgm_read_word(&m_vec[m_next++]));
187  }
188 
192  void reset()
193  __attribute__((always_inline))
194  {
195  m_next = 0;
196  }
197  };
198 
203  class Action {
204  public:
214  virtual int run(void* buf, size_t size) = 0;
215  };
216 
220  struct action_t {
223  };
224 
226  typedef const PROGMEM action_t* action_P;
227 
235  static action_P to_action(item_P item)
236  __attribute__((always_inline))
237  {
238  return (get_type(item) == ACTION ? (action_P) item : NULL);
239  }
240 
251  static int run(action_P action, void* buf, size_t size);
252 
257  struct blob_t {
259  void* value;
260  size_t size;
261  };
262 
264  typedef const PROGMEM blob_t* blob_P;
265 
274  static blob_P to_blob(item_P item)
275  {
276  return (get_type(item) >= BLOB ? (blob_P) item : NULL);
277  }
278 
289  int get_value(blob_P blob, void* buf, size_t len);
290 
299  template<class T> bool get_value(blob_P blob, T* value)
300  {
301  return (get_value(blob, value, sizeof(T)) == sizeof(T));
302  }
303 
316  int set_value(blob_P blob, const void* buf, size_t len);
317 
327  template<class T> bool set_value(blob_P blob, const T* value)
328  {
329  return (set_value(blob, value, sizeof(T)) == sizeof(T));
330  }
331 
333  static const size_t PATH_MAX = 8;
334 
340  Registry(item_list_P root, EEPROM::Device* eeprom = NULL) :
341  m_root(root),
342  m_eeprom(eeprom == NULL ? &EEPROM::Device::eeprom : eeprom)
343  {}
344 
352  item_P lookup(const uint8_t* path = NULL, size_t count = 0);
353 
354  void print(IOStream& outs, const uint8_t* path, size_t count);
355 
367  int apply(const uint8_t* path, size_t count, void* buf, size_t len)
368  {
369  return (run(to_action(lookup(path, count)), buf, len));
370  }
371 
372 private:
374  item_list_P m_root;
375 
377  EEPROM::Device* m_eeprom;
378 };
379 
387 
395 
408 #define REGISTRY_BEGIN(var,name) \
409  const char var ## _name[] __PROGMEM = name; \
410  const Registry::item_P var ## _list[] __PROGMEM = {
411 
418 #define REGISTRY_LIST_ITEM(var) &var.item,
419 #define REGISTRY_BLOB_ITEM(var) &var ## _blob.item,
420 #define REGISTRY_ACTION_ITEM(var) &var ## _action.item,
421 
426 #define REGISTRY_END(var) \
427  }; \
428  const Registry::item_list_t var __PROGMEM = { \
429  { \
430  Registry::ITEM_LIST, \
431  (str_P) var ## _name, \
432  Registry::IN_PROGMEM | Registry::READONLY \
433  }, \
434  membersof(var ## _list), \
435  var ## _list \
436  };
437 
443 #define REGISTRY_ACTION(var,name) \
444  const char var ## _name[] __PROGMEM = name; \
445  const Registry::action_t var ## _action __PROGMEM = { \
446  { \
447  Registry::ACTION, \
448  (str_P) var ## _name, \
449  Registry::IN_SRAM | Registry::READONLY \
450  }, \
451  &var \
452  };
453 
462 #define REGISTRY_BLOB(var,name,mem,readonly) \
463  const char var ## _blob_name[] __PROGMEM = name; \
464  const Registry::blob_t var ## _blob __PROGMEM = { \
465  { \
466  Registry::BLOB, \
467  (str_P) var ## _blob_name, \
468  Registry::IN_ ## mem | (readonly << 7) \
469  }, \
470  (void*) &var, \
471  sizeof(var) \
472  };
473 
483 #define REGISTRY_BLOB_VAR(type,var,name,value,readonly) \
484  static type var = value; \
485  REGISTRY_BLOB(var,name,SRAM,readonly)
486 
495 #define REGISTRY_BLOB_STRUCT(type,var,name,readonly) \
496  static type var; \
497  REGISTRY_BLOB(var,name,SRAM,readonly)
498 
507 #define REGISTRY_BLOB_PSTR(var,name,value) \
508  static const char var[] __PROGMEM = value; \
509  REGISTRY_BLOB(var,name,PROGMEM,true)
510 
511 #endif
512 
item_P lookup(const uint8_t *path=NULL, size_t count=0)
Definition: Registry.cpp:24
General binary object.
Definition: Registry.hh:45
type_t type
Item type tag(ITEM).
Definition: Registry.hh:68
#define EINVAL
Definition: Errno.h:49
item_vec_P list
Item vector in program memory.
Definition: Registry.hh:129
static blob_P to_blob(item_P item)
Definition: Registry.hh:274
Item descriptor.
Definition: Registry.hh:42
const item_P * item_vec_P
Definition: Registry.hh:77
size_t size
Size of object.
Definition: Registry.hh:260
#define NULL
Definition: Types.h:101
Definition: EEPROM.hh:33
static const size_t PATH_MAX
Definition: Registry.hh:333
uint8_t attr
Attributes.
Definition: Registry.hh:70
bool get_value(blob_P blob, T *value)
Definition: Registry.hh:299
static int get_length(item_list_P list)
Definition: Registry.hh:153
static item_list_P to_list(item_P item)
Definition: Registry.hh:142
static const uint8_t READONLY
Definition: Registry.hh:62
item_t item
Item header(ITEM_LIST).
Definition: Registry.hh:127
str_P name
Name string in program memory.
Definition: Registry.hh:69
item_t item
Item header(>= BLOB).
Definition: Registry.hh:258
int apply(const uint8_t *path, size_t count, void *buf, size_t len)
Definition: Registry.hh:367
Application binary object.
Definition: Registry.hh:46
Action function.
Definition: Registry.hh:44
In program memory.
Definition: Registry.hh:53
const item_list_t * item_list_P
Definition: Registry.hh:133
List of items.
Definition: Registry.hh:43
int get_value(blob_P blob, void *buf, size_t len)
Definition: Registry.cpp:97
const class prog_str * str_P
Definition: Types.h:187
const blob_t * blob_P
Definition: Registry.hh:264
void print(IOStream &outs, const uint8_t *path, size_t count)
Definition: Registry.cpp:54
Iterator(item_list_P list)
Definition: Registry.hh:173
Action * obj
Pointer to action handler instance.
Definition: Registry.hh:222
bool set_value(blob_P blob, const T *value)
Definition: Registry.hh:327
void * value
Pointer to value.
Definition: Registry.hh:259
static type_t get_type(item_P item)
Definition: Registry.hh:84
static str_P get_name(item_P item)
Definition: Registry.hh:95
IOStream & operator<<(IOStream &outs, Registry::item_P item)
Definition: Registry.cpp:149
uint8_t length
Item vector length (for boundary checking).
Definition: Registry.hh:128
static storage_t get_storage(item_P item)
Definition: Registry.hh:106
const item_t * item_P
Definition: Registry.hh:74
const action_t * action_P
Definition: Registry.hh:226
static int run(action_P action, void *buf, size_t size)
Definition: Registry.cpp:82
static const uint8_t STORAGE_MASK
Definition: Registry.hh:59
Registry(item_list_P root, EEPROM::Device *eeprom=NULL)
Definition: Registry.hh:340
#define UNLIKELY(x)
Definition: Types.h:153
static bool is_readonly(item_P item)
Definition: Registry.hh:117
In eeprom.
Definition: Registry.hh:55
In data memory.
Definition: Registry.hh:54
static action_P to_action(item_P item)
Definition: Registry.hh:235
item_t item
Item header(ACTION).
Definition: Registry.hh:221
int set_value(blob_P blob, const void *buf, size_t len)
Definition: Registry.cpp:124