COSA
An Object-Oriented Platform for Arduino Programming
Registry.cpp
Go to the documentation of this file.
1 
21 #include "Registry.hh"
22 
24 Registry::lookup(const uint8_t* path, size_t count)
25 {
26  // Check for root path
27  item_P item = (item_P) m_root;
28  if (UNLIKELY(path == NULL)) return (item);
29 
30  // Paths should not exceed the maximum length
31  if (UNLIKELY(count > PATH_MAX)) return (NULL);
32  for (uint8_t i = 0; i < count; i++) {
33  // Check that the current item is a list
34  uint8_t ix = path[i];
35  uint8_t nx = i + 1;
36  type_t type = (type_t) pgm_read_byte(&item->type);
37  if ((nx < count) && (type != ITEM_LIST)) return (NULL);
38 
39  // Check that the current index is within the list length
40  item_list_P items = (item_list_P) item;
41  uint8_t len = pgm_read_byte(&items->length);
42  if (ix >= len) return (NULL);
43 
44  // Read the item and step to the next path index
45  item_vec_P vec = (item_vec_P) pgm_read_word(&items->list);
46  item = (item_P) pgm_read_word(&vec[ix]);
47  }
48 
49  // Return path indexed item
50  return (item);
51 }
52 
53 void
54 Registry::print(IOStream& outs, const uint8_t* path, size_t count)
55 {
56  // Check for root path
57  item_P item = (item_P) m_root;
58  if (UNLIKELY(path == NULL)) return;
59 
60  // Paths should not exceed the maximum length
61  if (UNLIKELY(count > PATH_MAX)) return;
62  for (uint8_t i = 0; i < count; i++) {
63  // Check that the current item is a list
64  uint8_t ix = path[i];
65  uint8_t nx = i + 1;
66  type_t type = (type_t) pgm_read_byte(&item->type);
67  if ((nx < count) && (type != ITEM_LIST)) return;
68 
69  // Check that the current index is within the list length
70  item_list_P items = (item_list_P) item;
71  uint8_t len = pgm_read_byte(&items->length);
72  if (ix >= len) return;
73 
74  // Read the item and step to the next path index
75  item_vec_P vec = (item_vec_P) pgm_read_word(&items->list);
76  item = (item_P) pgm_read_word(&vec[ix]);
77  outs << '/' << get_name(item);
78  }
79 }
80 
81 int
82 Registry::run(action_P action, void* buf, size_t size)
83 {
84  // Sanity check the parameters
85  if (UNLIKELY(action == NULL)) return (EINVAL);
86  if (UNLIKELY(pgm_read_byte(&action->item.type) != ACTION)) return (EINVAL);
87 
88  // Access the action object
89  Action* obj = (Action*) pgm_read_word(&action->obj);
90  if (UNLIKELY(obj == NULL)) return (EINVAL);
91 
92  // And run the member function
93  return (obj->run(buf, size));
94 }
95 
96 int
97 Registry::get_value(blob_P blob, void* buf, size_t len)
98 {
99  // Sanity check the parameters
100  if (UNLIKELY(len == 0)) return (0);
101  if (UNLIKELY((blob == NULL) || (buf == NULL))) return (EINVAL);
102  if (UNLIKELY(pgm_read_byte(&blob->item.type) < BLOB)) return (EINVAL);
103 
104  // Check size of blob
105  size_t size = (size_t) pgm_read_word(&blob->size);
106  if (UNLIKELY(size == 0)) return (0);
107  if (UNLIKELY(size > len)) return (E2BIG);
108 
109  // Check where the value is stored and copy into buffer
110  storage_t storage = get_storage(&blob->item);
111  if (storage == IN_PROGMEM)
112  memcpy_P(buf, (const void*) pgm_read_word(&blob->value), size);
113  else if (storage == IN_SRAM)
114  memcpy(buf, (const void*) pgm_read_word(&blob->value), size);
115  else if (storage == IN_EEMEM && m_eeprom != NULL)
116  m_eeprom->read(buf, (const void*) pgm_read_word(&blob->value), size);
117  else return (EINVAL);
118 
119  // Return the number of bytes read
120  return (size);
121 }
122 
123 int
124 Registry::set_value(blob_P blob, const void* buf, size_t len)
125 {
126  // Sanity check the parameters
127  if (UNLIKELY(len == 0)) return (0);
128  if (UNLIKELY((blob == NULL) || (buf == NULL))) return (EINVAL);
129  if (UNLIKELY(pgm_read_byte(&blob->item.type) < BLOB)) return (EINVAL);
130  if (UNLIKELY(is_readonly(&blob->item))) return (EACCES);
131 
132  // Check size of blob against given value in buffer
133  size_t size = (size_t) pgm_read_word(&blob->size);
134  if (UNLIKELY(size == 0)) return (0);
135  if (UNLIKELY(size != len)) return (E2BIG);
136 
137  // Check where the value is stored and copy into buffer
138  storage_t storage = get_storage(&blob->item);
139  if (storage == IN_SRAM)
140  memcpy((void*) pgm_read_word(&blob->value), buf, size);
141  else if (storage == IN_EEMEM && m_eeprom != NULL)
142  m_eeprom->write((void*) pgm_read_word(&blob->value), buf, size);
143  else return (EINVAL);
144 
145  // Return the number of bytes written
146  return (size);
147 }
148 
150 {
151  outs << PSTR("item@") << (void*) item;
152  if (item == NULL) {
153  outs << PSTR("(NULL)");
154  return (outs);
155  }
156  outs << PSTR("(type = ");
157  uint8_t type = Registry::get_type(item);
158  switch (type) {
159  case Registry::ITEM:
160  outs << PSTR("ITEM");
161  break;
162  case Registry::ITEM_LIST:
163  outs << PSTR("ITEM_LIST");
164  break;
165  case Registry::ACTION:
166  outs << PSTR("ACTION");
167  break;
168  case Registry::BLOB:
169  outs << PSTR("BLOB");
170  break;
171  default:
172  outs << PSTR("APPL(") << type << ')';
173  }
174  outs << PSTR(", name = ") << Registry::get_name(item);
175  outs << PSTR(", storage = ");
176  switch (Registry::get_storage(item)) {
177  case Registry::IN_SRAM:
178  outs << PSTR("SRAM");
179  break;
181  outs << PSTR("PROGMEM");
182  break;
183  case Registry::IN_EEMEM:
184  outs << PSTR("EEMEM");
185  break;
186  default:
187  outs << PSTR("???");
188  }
189  if (Registry::is_readonly(item)) outs << PSTR(", readonly");
190  outs << PSTR(")");
191  return (outs);
192 }
193 
195 {
196  outs << (Registry::item_P) list << endl;
197  if (list == NULL) return (outs);
198  Registry::Iterator iter(list);
199  Registry::item_P item;
200  while ((item = iter.next()) != NULL)
201  outs << item << endl;
202  return (outs);
203 }
204 
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
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
static const size_t PATH_MAX
Definition: Registry.hh:333
#define EACCES
Definition: Errno.h:40
#define PSTR(s)
Definition: Types.h:202
item_t item
Item header(>= BLOB).
Definition: Registry.hh:258
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
virtual int write(void *dest, const void *src, size_t size)
Definition: EEPROM.cpp:40
void print(IOStream &outs, const uint8_t *path, size_t count)
Definition: Registry.cpp:54
virtual int read(void *dest, const void *src, size_t size)
Definition: EEPROM.cpp:30
Action * obj
Pointer to action handler instance.
Definition: Registry.hh:222
void * value
Pointer to value.
Definition: Registry.hh:259
IOStream & endl(IOStream &outs)
Definition: IOStream.hh:817
static type_t get_type(item_P item)
Definition: Registry.hh:84
static str_P get_name(item_P item)
Definition: Registry.hh:95
#define E2BIG
Definition: Errno.h:34
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
IOStream & operator<<(IOStream &outs, Registry::item_P item)
Definition: Registry.cpp:149
static int run(action_P action, void *buf, size_t size)
Definition: Registry.cpp:82
#define UNLIKELY(x)
Definition: Types.h:153
static bool is_readonly(item_P item)
Definition: Registry.hh:117
In eeprom.
Definition: Registry.hh:55
virtual int run(void *buf, size_t size)=0
In data memory.
Definition: Registry.hh:54
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