|
|
| 63 |
}; |
63 |
}; |
| 64 |
private: |
64 |
private: |
| 65 |
struct TagData { |
65 |
struct TagData { |
|
|
66 |
uint8_t m_data[Tags::SIZE]; |
| 66 |
struct TagData *m_next; |
67 |
struct TagData *m_next; |
| 67 |
uint32_t m_id; |
68 |
uint32_t m_id; |
| 68 |
uint32_t m_count; |
69 |
uint32_t m_count; |
| 69 |
uint8_t m_data[Tags::SIZE]; |
|
|
| 70 |
}; |
70 |
}; |
| 71 |
|
71 |
|
| 72 |
bool Remove (uint32_t id); |
72 |
bool Remove (uint32_t id); |
|
|
| 99 |
TagRegistration<T> (std::string uuid, void(*fn) (T const*, std::ostream &)); |
99 |
TagRegistration<T> (std::string uuid, void(*fn) (T const*, std::ostream &)); |
| 100 |
private: |
100 |
private: |
| 101 |
static void PrettyPrinterCb (uint8_t *buf, std::ostream &os); |
101 |
static void PrettyPrinterCb (uint8_t *buf, std::ostream &os); |
|
|
102 |
static void DestructorCb (uint8_t *buf); |
| 102 |
static void(*m_prettyPrinter) (T const*, std::ostream &); |
103 |
static void(*m_prettyPrinter) (T const*, std::ostream &); |
| 103 |
}; |
104 |
}; |
| 104 |
|
105 |
|
|
|
| 117 |
class TagRegistry { |
118 |
class TagRegistry { |
| 118 |
public: |
119 |
public: |
| 119 |
typedef void (*PrettyPrinter) (uint8_t [Tags::SIZE], std::ostream &); |
120 |
typedef void (*PrettyPrinter) (uint8_t [Tags::SIZE], std::ostream &); |
| 120 |
static void Record (std::string uuid, PrettyPrinter prettyPrinter); |
121 |
typedef void (*Destructor) (uint8_t [Tags::SIZE]); |
|
|
122 |
static void Record (std::string uuid, PrettyPrinter prettyPrinter, Destructor destructor); |
| 121 |
/** |
123 |
/** |
| 122 |
* returns a numeric integer which uniquely identifies the input string. |
124 |
* returns a numeric integer which uniquely identifies the input string. |
| 123 |
* that integer cannot be zero which is a reserved value. |
125 |
* that integer cannot be zero which is a reserved value. |
| 124 |
*/ |
126 |
*/ |
| 125 |
static uint32_t LookupUid (std::string uuid); |
127 |
static uint32_t LookupUid (std::string uuid); |
| 126 |
static void PrettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os); |
128 |
static void PrettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os); |
| 127 |
private: |
129 |
static void Destruct (uint32_t uid, uint8_t buf[Tags::SIZE]); |
| 128 |
typedef std::vector<std::pair<std::string,PrettyPrinter> > TagsData; |
130 |
private: |
| 129 |
typedef std::vector<std::pair<std::string,PrettyPrinter> >::const_iterator TagsDataCI; |
131 |
struct TagInfoItem |
|
|
132 |
{ |
| 133 |
std::string uuid; |
| 134 |
PrettyPrinter printer; |
| 135 |
Destructor destructor; |
| 136 |
}; |
| 137 |
typedef std::vector<struct TagInfoItem> TagsData; |
| 138 |
typedef std::vector<struct TagInfoItem>::const_iterator TagsDataCI; |
| 139 |
static bool CompareItem (const struct TagInfoItem &a, const struct TagInfoItem &b); |
| 130 |
static bool m_sorted; |
140 |
static bool m_sorted; |
| 131 |
static TagsData m_registry; |
141 |
static TagsData m_registry; |
| 132 |
}; |
142 |
}; |
|
|
| 181 |
{ |
191 |
{ |
| 182 |
NS_ASSERT (sizeof (T) <= Tags::SIZE); |
192 |
NS_ASSERT (sizeof (T) <= Tags::SIZE); |
| 183 |
m_prettyPrinter = prettyPrinter; |
193 |
m_prettyPrinter = prettyPrinter; |
| 184 |
TagRegistry::Record (uuid, &TagRegistration<T>::PrettyPrinterCb); |
194 |
TagRegistry::Record (uuid, &TagRegistration<T>::PrettyPrinterCb, &TagRegistration<T>::DestructorCb); |
| 185 |
TypeUid<T>::Record (uuid); |
195 |
TypeUid<T>::Record (uuid); |
| 186 |
} |
196 |
} |
| 187 |
template <typename T> |
197 |
template <typename T> |
|
|
| 192 |
T *tag = reinterpret_cast<T *> (buf); |
202 |
T *tag = reinterpret_cast<T *> (buf); |
| 193 |
(*m_prettyPrinter) (tag, os); |
203 |
(*m_prettyPrinter) (tag, os); |
| 194 |
} |
204 |
} |
| 195 |
|
205 |
template <typename T> |
|
|
206 |
void |
| 207 |
TagRegistration<T>::DestructorCb (uint8_t *buf) |
| 208 |
{ |
| 209 |
T *tag = reinterpret_cast<T *> (buf); |
| 210 |
tag->~T (); |
| 211 |
} |
| 196 |
template <typename T> |
212 |
template <typename T> |
| 197 |
void (*TagRegistration<T>::m_prettyPrinter) (T const*, std::ostream &) = 0; |
213 |
void (*TagRegistration<T>::m_prettyPrinter) (T const*, std::ostream &) = 0; |
| 198 |
|
214 |
|
|
|
| 204 |
Tags::Add (T const&tag) |
220 |
Tags::Add (T const&tag) |
| 205 |
{ |
221 |
{ |
| 206 |
NS_ASSERT (sizeof (T) <= Tags::SIZE); |
222 |
NS_ASSERT (sizeof (T) <= Tags::SIZE); |
| 207 |
uint8_t const*buf = reinterpret_cast<uint8_t const*> (&tag); |
|
|
| 208 |
// ensure this id was not yet added |
223 |
// ensure this id was not yet added |
| 209 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) |
224 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) |
| 210 |
{ |
225 |
{ |
|
|
| 214 |
newStart->m_count = 1; |
229 |
newStart->m_count = 1; |
| 215 |
newStart->m_next = 0; |
230 |
newStart->m_next = 0; |
| 216 |
newStart->m_id = TypeUid<T>::GetUid (); |
231 |
newStart->m_id = TypeUid<T>::GetUid (); |
| 217 |
memcpy (newStart->m_data, buf, sizeof (T)); |
232 |
void *buf = &newStart->m_data; |
|
|
233 |
new (buf) T (tag); |
| 218 |
newStart->m_next = m_next; |
234 |
newStart->m_next = m_next; |
| 219 |
m_next = newStart; |
235 |
m_next = newStart; |
| 220 |
} |
236 |
} |
|
|
| 232 |
Tags::Peek (T &tag) const |
248 |
Tags::Peek (T &tag) const |
| 233 |
{ |
249 |
{ |
| 234 |
NS_ASSERT (sizeof (T) <= Tags::SIZE); |
250 |
NS_ASSERT (sizeof (T) <= Tags::SIZE); |
| 235 |
uint8_t *buf = reinterpret_cast<uint8_t *> (&tag); |
|
|
| 236 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) |
251 |
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) |
| 237 |
{ |
252 |
{ |
| 238 |
if (cur->m_id == TypeUid<T>::GetUid ()) |
253 |
if (cur->m_id == TypeUid<T>::GetUid ()) |
| 239 |
{ |
254 |
{ |
| 240 |
/* found tag */ |
255 |
/* found tag */ |
| 241 |
memcpy (buf, cur->m_data, sizeof (T)); |
256 |
T *data = reinterpret_cast<T *> (&cur->m_data); |
|
|
257 |
tag = T (*data); |
| 242 |
return true; |
258 |
return true; |
| 243 |
} |
259 |
} |
| 244 |
} |
260 |
} |
|
|
| 294 |
} |
310 |
} |
| 295 |
if (prev != 0) |
311 |
if (prev != 0) |
| 296 |
{ |
312 |
{ |
|
|
313 |
TagRegistry::Destruct (prev->m_id, prev->m_data); |
| 297 |
FreeData (prev); |
314 |
FreeData (prev); |
| 298 |
} |
315 |
} |
| 299 |
prev = cur; |
316 |
prev = cur; |
| 300 |
} |
317 |
} |
| 301 |
if (prev != 0) |
318 |
if (prev != 0) |
| 302 |
{ |
319 |
{ |
|
|
320 |
TagRegistry::Destruct (prev->m_id, prev->m_data); |
| 303 |
FreeData (prev); |
321 |
FreeData (prev); |
| 304 |
} |
322 |
} |
| 305 |
m_next = 0; |
323 |
m_next = 0; |