View | Details | Raw Unified | Return to bug 15
Collapse All | Expand All

(-)a/src/common/tags.cc (-5 / +56 lines)
 Lines 28-51   TagRegistry::TagsData TagRegistry::m_reg Link Here 
28
28
29
29
30
void 
30
void 
31
TagRegistry::Record (std::string uuid, PrettyPrinter prettyPrinter)
31
TagRegistry::Record (std::string uuid, PrettyPrinter prettyPrinter, Destructor destructor)
32
{
32
{
33
  NS_ASSERT (!m_sorted);
33
  NS_ASSERT (!m_sorted);
34
  m_registry.push_back (make_pair (uuid, prettyPrinter));
34
  struct TagInfoItem item;
35
  item.uuid = uuid;
36
  item.printer = prettyPrinter;
37
  item.destructor = destructor;
38
  m_registry.push_back (item);
39
}
40
bool 
41
TagRegistry::CompareItem (const struct TagInfoItem &a, const struct TagInfoItem &b)
42
{
43
  return a.uuid < b.uuid;
35
}
44
}
36
uint32_t 
45
uint32_t 
37
TagRegistry::LookupUid (std::string uuid)
46
TagRegistry::LookupUid (std::string uuid)
38
{
47
{
39
  if (!m_sorted) 
48
  if (!m_sorted) 
40
    {
49
    {
41
  	std::sort (m_registry.begin (), m_registry.end ());
50
      std::sort (m_registry.begin (), m_registry.end (), &TagRegistry::CompareItem);
42
  	m_sorted = true;
51
  	m_sorted = true;
43
    }
52
    }
44
  NS_ASSERT (m_sorted);
53
  NS_ASSERT (m_sorted);
45
  uint32_t uid = 1;
54
  uint32_t uid = 1;
46
  for (TagsDataCI i = m_registry.begin (); i != m_registry.end (); i++) 
55
  for (TagsDataCI i = m_registry.begin (); i != m_registry.end (); i++) 
47
    {
56
    {
48
  	if (i->first == uuid) 
57
  	if (i->uuid == uuid) 
49
        {
58
        {
50
  		return uid;
59
  		return uid;
51
        }
60
        }
 Lines 60-70   TagRegistry::PrettyPrint (uint32_t uid, Link Here 
60
TagRegistry::PrettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os)
69
TagRegistry::PrettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os)
61
{
70
{
62
  NS_ASSERT (m_registry.size () > uid);
71
  NS_ASSERT (m_registry.size () > uid);
63
  PrettyPrinter prettyPrinter = m_registry[uid].second;
72
  PrettyPrinter prettyPrinter = m_registry[uid].printer;
64
  if (prettyPrinter != 0) 
73
  if (prettyPrinter != 0) 
65
    {
74
    {
66
  	prettyPrinter (buf, os);
75
  	prettyPrinter (buf, os);
67
    }
76
    }
77
}
78
79
void 
80
TagRegistry::Destruct (uint32_t uid, uint8_t buf[Tags::SIZE])
81
{
82
  NS_ASSERT (m_registry.size () > uid);
83
  Destructor destructor = m_registry[uid].destructor;
84
  NS_ASSERT (destructor != 0);
85
  destructor (buf);
68
}
86
}
69
87
70
88
 Lines 202-207   struct myInvalidTag { Link Here 
202
  uint8_t invalid [Tags::SIZE+1];
220
  uint8_t invalid [Tags::SIZE+1];
203
};
221
};
204
222
223
class MySmartTag 
224
{
225
public:
226
  MySmartTag ()
227
  {
228
    std::cout << "construct" << std::endl;
229
  }
230
  MySmartTag (const MySmartTag &o)
231
  {
232
    std::cout << "copy" << std::endl;
233
  }
234
  ~MySmartTag ()
235
  {
236
    std::cout << "destruct" << std::endl;
237
  }
238
  MySmartTag &operator = (const MySmartTag &o)
239
  {
240
    std::cout << "assign" << std::endl;
241
    return *this;
242
  }
243
  static void PrettyPrinterCb (const MySmartTag *a, std::ostream &os)
244
  {}
245
};
246
205
static void 
247
static void 
206
myTagAPrettyPrinterCb (struct myTagA const*a, std::ostream &os)
248
myTagAPrettyPrinterCb (struct myTagA const*a, std::ostream &os)
207
{
249
{
 Lines 222-227   static TagRegistration<struct myTagA> gM Link Here 
222
static TagRegistration<struct myTagA> gMyTagARegistration ("A", &myTagAPrettyPrinterCb);
264
static TagRegistration<struct myTagA> gMyTagARegistration ("A", &myTagAPrettyPrinterCb);
223
static TagRegistration<struct myTagB> gMyTagBRegistration ("B", &myTagBPrettyPrinterCb);
265
static TagRegistration<struct myTagB> gMyTagBRegistration ("B", &myTagBPrettyPrinterCb);
224
static TagRegistration<struct myTagC> gMyTagCRegistration ("C", &myTagCPrettyPrinterCb);
266
static TagRegistration<struct myTagC> gMyTagCRegistration ("C", &myTagCPrettyPrinterCb);
267
static TagRegistration<MySmartTag> g_myTagSmartRegistration ("SmartTag", &MySmartTag::PrettyPrinterCb);
225
268
226
269
227
TagsTest::TagsTest ()
270
TagsTest::TagsTest ()
 Lines 318-323   TagsTest::RunTests (void) Link Here 
318
  //struct myInvalidTag invalid;
361
  //struct myInvalidTag invalid;
319
  //tags.add (&invalid);
362
  //tags.add (&invalid);
320
363
364
  MySmartTag smartTag;
365
  {
366
    Tags tmp;
367
    tmp.Add (smartTag);
368
    tmp.Peek (smartTag);
369
    tmp.Remove (smartTag);
370
  }
371
321
  return ok;
372
  return ok;
322
}
373
}
323
374
(-)a/src/common/tags.h (-11 / +28 lines)
 Lines 63-72   public: Link Here 
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);
 Lines 99-104   public: Link Here 
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
 Lines 117-132   class TagRegistry { Link Here 
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
};
 Lines 181-187   TagRegistration<T>::TagRegistration (std Link Here 
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>
 Lines 192-198   TagRegistration<T>::PrettyPrinterCb (uin Link Here 
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
 Lines 204-210   Tags::Add (T const&tag) Link Here 
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
    {
 Lines 214-220   Tags::Add (T const&tag) Link Here 
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
}
 Lines 232-244   Tags::Peek (T &tag) const Link Here 
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
    }
 Lines 294-299   Tags::RemoveAll (void) Link Here 
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;

Return to bug 15