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

(-)a/src/common/tags.cc (-6 / +61 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 62-73   TagRegistry::PrettyPrint (uint32_t uid, Link Here 
62
  NS_ASSERT (uid > 0);
71
  NS_ASSERT (uid > 0);
63
  uint32_t index = uid - 1;
72
  uint32_t index = uid - 1;
64
  NS_ASSERT (m_registry.size () > index);
73
  NS_ASSERT (m_registry.size () > index);
65
  PrettyPrinter prettyPrinter = m_registry[index].second;
74
  PrettyPrinter prettyPrinter = m_registry[index].printer;
66
  if (prettyPrinter != 0) 
75
  if (prettyPrinter != 0) 
67
    {
76
    {
68
      prettyPrinter (buf, os);
77
      prettyPrinter (buf, os);
69
    }
78
    }
70
}
79
}
80
void 
81
TagRegistry::Destruct (uint32_t uid, uint8_t buf[Tags::SIZE])
82
{
83
  NS_ASSERT (uid > 0);
84
  uint32_t index = uid - 1;
85
  NS_ASSERT (m_registry.size () > index);
86
  Destructor destructor = m_registry[index].destructor;
87
  NS_ASSERT (destructor != 0);
88
  destructor (buf);
89
}
90
71
91
72
92
73
#ifdef USE_FREE_LIST
93
#ifdef USE_FREE_LIST
 Lines 212-217   struct myTagZ { Link Here 
212
  uint8_t z;
232
  uint8_t z;
213
};
233
};
214
234
235
class MySmartTag 
236
{
237
public:
238
  MySmartTag ()
239
  {
240
    std::cout << "construct" << std::endl;
241
  }
242
  MySmartTag (const MySmartTag &o)
243
  {
244
    std::cout << "copy" << std::endl;
245
  }
246
  ~MySmartTag ()
247
  {
248
    std::cout << "destruct" << std::endl;
249
  }
250
  MySmartTag &operator = (const MySmartTag &o)
251
  {
252
    std::cout << "assign" << std::endl;
253
    return *this;
254
  }
255
  static void PrettyPrinterCb (const MySmartTag *a, std::ostream &os)
256
  {}
257
};
258
215
static void 
259
static void 
216
myTagAPrettyPrinterCb (struct myTagA const*a, std::ostream &os)
260
myTagAPrettyPrinterCb (struct myTagA const*a, std::ostream &os)
217
{
261
{
 Lines 243-248   static TagRegistration<struct myTagC> gM Link Here 
243
static TagRegistration<struct myTagC> gMyTagCRegistration ("C", &myTagCPrettyPrinterCb);
287
static TagRegistration<struct myTagC> gMyTagCRegistration ("C", &myTagCPrettyPrinterCb);
244
static TagRegistration<struct myTagZ> g_myTagZRegistration ("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", 
288
static TagRegistration<struct myTagZ> g_myTagZRegistration ("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", 
245
                                                            &myTagZPrettyPrinterCb);
289
                                                            &myTagZPrettyPrinterCb);
290
static TagRegistration<MySmartTag> g_myTagSmartRegistration ("SmartTag", &MySmartTag::PrettyPrinterCb);
246
291
247
292
248
TagsTest::TagsTest ()
293
TagsTest::TagsTest ()
 Lines 313-318   TagsTest::RunTests (void) Link Here 
313
      ok = false;
358
      ok = false;
314
    }
359
    }
315
  struct myTagB oB;
360
  struct myTagB oB;
361
  oB.b = 1;
316
  other.Peek (oB);
362
  other.Peek (oB);
317
  if (oB.b != 0xff) 
363
  if (oB.b != 0xff) 
318
    {
364
    {
 Lines 348-354   TagsTest::RunTests (void) Link Here 
348
  other = tags;
394
  other = tags;
349
  Tags another = other;
395
  Tags another = other;
350
  struct myTagC c;
396
  struct myTagC c;
351
  c.c[0] = 0x66;
397
  memset (c.c, 0x66, 16);
352
  another.Add (c);
398
  another.Add (c);
353
  c.c[0] = 0;
399
  c.c[0] = 0;
354
  another.Peek (c);
400
  another.Peek (c);
 Lines 369-374   TagsTest::RunTests (void) Link Here 
369
415
370
  struct myTagZ tagZ;
416
  struct myTagZ tagZ;
371
  Tags testLastTag;
417
  Tags testLastTag;
418
  tagZ.z = 0;
372
  testLastTag.Add (tagZ);
419
  testLastTag.Add (tagZ);
373
  g_z = false;
420
  g_z = false;
374
  testLastTag.PrettyPrint (std::cout);
421
  testLastTag.PrettyPrint (std::cout);
 Lines 377-382   TagsTest::RunTests (void) Link Here 
377
      ok = false;
424
      ok = false;
378
    }
425
    }
379
426
427
  MySmartTag smartTag;
428
  {
429
    Tags tmp;
430
    tmp.Add (smartTag);
431
    tmp.Peek (smartTag);
432
    tmp.Remove (smartTag);
433
  }
434
380
  return ok;
435
  return ok;
381
}
436
}
382
437
(-)a/src/common/tags.h (-11 / +29 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-305   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;
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;

Return to bug 15