A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
type-id.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "type-id.h"
21 #include "singleton.h"
22 #include "trace-source-accessor.h"
23 #include <vector>
24 #include <sstream>
25 
26 /*********************************************************************
27  * Helper code
28  *********************************************************************/
29 
30 namespace {
31 
33 {
34 public:
35  IidManager ();
36  uint16_t AllocateUid (std::string name);
37  void SetParent (uint16_t uid, uint16_t parent);
38  void SetGroupName (uint16_t uid, std::string groupName);
39  void AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback);
40  void HideFromDocumentation (uint16_t uid);
41  uint16_t GetUid (std::string name) const;
42  std::string GetName (uint16_t uid) const;
43  uint16_t GetParent (uint16_t uid) const;
44  std::string GetGroupName (uint16_t uid) const;
45  ns3::Callback<ns3::ObjectBase *> GetConstructor (uint16_t uid) const;
46  bool HasConstructor (uint16_t uid) const;
47  uint32_t GetRegisteredN (void) const;
48  uint16_t GetRegistered (uint32_t i) const;
49  void AddAttribute (uint16_t uid,
50  std::string name,
51  std::string help,
52  uint32_t flags,
56  void SetAttributeInitialValue(uint16_t uid,
57  uint32_t i,
59  uint32_t GetAttributeN (uint16_t uid) const;
60  struct ns3::TypeId::AttributeInformation GetAttribute(uint16_t uid, uint32_t i) const;
61  void AddTraceSource (uint16_t uid,
62  std::string name,
63  std::string help,
65  uint32_t GetTraceSourceN (uint16_t uid) const;
66  struct ns3::TypeId::TraceSourceInformation GetTraceSource(uint16_t uid, uint32_t i) const;
67  bool MustHideFromDocumentation (uint16_t uid) const;
68 
69 private:
70  bool HasTraceSource (uint16_t uid, std::string name);
71  bool HasAttribute (uint16_t uid, std::string name);
72 
73  struct IidInformation {
74  std::string name;
75  uint16_t parent;
76  std::string groupName;
80  std::vector<struct ns3::TypeId::AttributeInformation> attributes;
81  std::vector<struct ns3::TypeId::TraceSourceInformation> traceSources;
82  };
83  typedef std::vector<struct IidInformation>::const_iterator Iterator;
84 
85  struct IidManager::IidInformation *LookupInformation (uint16_t uid) const;
86 
87  std::vector<struct IidInformation> m_information;
88 };
89 
90 IidManager::IidManager ()
91 {
92 }
93 
94 uint16_t
95 IidManager::AllocateUid (std::string name)
96 {
97  uint16_t j = 1;
98  for (Iterator i = m_information.begin (); i != m_information.end (); i++)
99  {
100  if (i->name == name)
101  {
102  NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
103  return 0;
104  }
105  j++;
106  }
107  struct IidInformation information;
108  information.name = name;
109  information.parent = 0;
110  information.groupName = "";
111  information.hasConstructor = false;
112  information.mustHideFromDocumentation = false;
113  m_information.push_back (information);
114  uint32_t uid = m_information.size ();
115  NS_ASSERT (uid <= 0xffff);
116  return uid;
117 }
118 
120 IidManager::LookupInformation (uint16_t uid) const
121 {
122  NS_ASSERT (uid <= m_information.size () && uid != 0);
123  return const_cast<struct IidInformation *> (&m_information[uid-1]);
124 }
125 
126 void
127 IidManager::SetParent (uint16_t uid, uint16_t parent)
128 {
129  NS_ASSERT (parent <= m_information.size ());
130  struct IidInformation *information = LookupInformation (uid);
131  information->parent = parent;
132 }
133 void
134 IidManager::SetGroupName (uint16_t uid, std::string groupName)
135 {
136  struct IidInformation *information = LookupInformation (uid);
137  information->groupName = groupName;
138 }
139 void
140 IidManager::HideFromDocumentation (uint16_t uid)
141 {
142  struct IidInformation *information = LookupInformation (uid);
143  information->mustHideFromDocumentation = true;
144 }
145 
146 void
147 IidManager::AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback)
148 {
149  struct IidInformation *information = LookupInformation (uid);
150  if (information->hasConstructor)
151  {
152  NS_FATAL_ERROR (information->name<<" already has a constructor.");
153  }
154  information->hasConstructor = true;
155  information->constructor = callback;
156 }
157 
158 uint16_t
159 IidManager::GetUid (std::string name) const
160 {
161  uint32_t j = 1;
162  for (Iterator i = m_information.begin (); i != m_information.end (); i++)
163  {
164  if (i->name == name)
165  {
166  NS_ASSERT (j <= 0xffff);
167  return j;
168  }
169  j++;
170  }
171  return 0;
172 }
173 std::string
174 IidManager::GetName (uint16_t uid) const
175 {
176  struct IidInformation *information = LookupInformation (uid);
177  return information->name;
178 }
179 uint16_t
180 IidManager::GetParent (uint16_t uid) const
181 {
182  struct IidInformation *information = LookupInformation (uid);
183  return information->parent;
184 }
185 std::string
186 IidManager::GetGroupName (uint16_t uid) const
187 {
188  struct IidInformation *information = LookupInformation (uid);
189  return information->groupName;
190 }
191 
193 IidManager::GetConstructor (uint16_t uid) const
194 {
195  struct IidInformation *information = LookupInformation (uid);
196  if (!information->hasConstructor)
197  {
198  NS_FATAL_ERROR ("Requested constructor for "<<information->name<<" but it does not have one.");
199  }
200  return information->constructor;
201 }
202 
203 bool
204 IidManager::HasConstructor (uint16_t uid) const
205 {
206  struct IidInformation *information = LookupInformation (uid);
207  return information->hasConstructor;
208 }
209 
210 uint32_t
211 IidManager::GetRegisteredN (void) const
212 {
213  return m_information.size ();
214 }
215 uint16_t
216 IidManager::GetRegistered (uint32_t i) const
217 {
218  return i + 1;
219 }
220 
221 bool
222 IidManager::HasAttribute (uint16_t uid,
223  std::string name)
224 {
225  struct IidInformation *information = LookupInformation (uid);
226  while (true)
227  {
228  for (std::vector<struct ns3::TypeId::AttributeInformation>::const_iterator i = information->attributes.begin ();
229  i != information->attributes.end (); ++i)
230  {
231  if (i->name == name)
232  {
233  return true;
234  }
235  }
236  struct IidInformation *parent = LookupInformation (information->parent);
237  if (parent == information)
238  {
239  // top of inheritance tree
240  return false;
241  }
242  // check parent
243  information = parent;
244  }
245  return false;
246 }
247 
248 void
249 IidManager::AddAttribute (uint16_t uid,
250  std::string name,
251  std::string help,
252  uint32_t flags,
256 {
257  struct IidInformation *information = LookupInformation (uid);
258  if (HasAttribute (uid, name))
259  {
260  NS_FATAL_ERROR ("Attribute \"" << name << "\" already registered on tid=\"" <<
261  information->name << "\"");
262  }
264  info.name = name;
265  info.help = help;
266  info.flags = flags;
267  info.initialValue = initialValue;
269  info.accessor = accessor;
270  info.checker = checker;
271  information->attributes.push_back (info);
272 }
273 void
275  uint32_t i,
277 {
278  struct IidInformation *information = LookupInformation (uid);
279  NS_ASSERT (i < information->attributes.size ());
280  information->attributes[i].initialValue = initialValue;
281 }
282 
283 
284 
285 uint32_t
286 IidManager::GetAttributeN (uint16_t uid) const
287 {
288  struct IidInformation *information = LookupInformation (uid);
289  return information->attributes.size ();
290 }
292 IidManager::GetAttribute(uint16_t uid, uint32_t i) const
293 {
294  struct IidInformation *information = LookupInformation (uid);
295  NS_ASSERT (i < information->attributes.size ());
296  return information->attributes[i];
297 }
298 
299 bool
300 IidManager::HasTraceSource (uint16_t uid,
301  std::string name)
302 {
303  struct IidInformation *information = LookupInformation (uid);
304  while (true)
305  {
306  for (std::vector<struct ns3::TypeId::TraceSourceInformation>::const_iterator i = information->traceSources.begin ();
307  i != information->traceSources.end (); ++i)
308  {
309  if (i->name == name)
310  {
311  return true;
312  }
313  }
314  struct IidInformation *parent = LookupInformation (information->parent);
315  if (parent == information)
316  {
317  // top of inheritance tree
318  return false;
319  }
320  // check parent
321  information = parent;
322  }
323  return false;
324 }
325 
326 void
327 IidManager::AddTraceSource (uint16_t uid,
328  std::string name,
329  std::string help,
331 {
332  struct IidInformation *information = LookupInformation (uid);
333  if (HasTraceSource (uid, name))
334  {
335  NS_FATAL_ERROR ("Trace source \"" << name << "\" already registered on tid=\"" <<
336  information->name << "\"");
337  }
339  source.name = name;
340  source.help = help;
341  source.accessor = accessor;
342  information->traceSources.push_back (source);
343 }
344 uint32_t
345 IidManager::GetTraceSourceN (uint16_t uid) const
346 {
347  struct IidInformation *information = LookupInformation (uid);
348  return information->traceSources.size ();
349 }
351 IidManager::GetTraceSource(uint16_t uid, uint32_t i) const
352 {
353  struct IidInformation *information = LookupInformation (uid);
354  NS_ASSERT (i < information->traceSources.size ());
355  return information->traceSources[i];
356 }
357 bool
358 IidManager::MustHideFromDocumentation (uint16_t uid) const
359 {
360  struct IidInformation *information = LookupInformation (uid);
361  return information->mustHideFromDocumentation;
362 }
363 
364 } // anonymous namespace
365 
366 namespace ns3 {
367 
368 /*********************************************************************
369  * The TypeId class
370  *********************************************************************/
371 
372 TypeId::TypeId (const char *name)
373 {
374  uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
375  NS_ASSERT (uid != 0);
376  m_tid = uid;
377 }
378 
379 
380 TypeId::TypeId (uint16_t tid)
381  : m_tid (tid)
382 {
383 }
384 TypeId
385 TypeId::LookupByName (std::string name)
386 {
387  uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
388  NS_ASSERT_MSG (uid != 0, "Assert in TypeId::LookupByName: " << name << " not found");
389  return TypeId (uid);
390 }
391 bool
392 TypeId::LookupByNameFailSafe (std::string name, TypeId *tid)
393 {
394  uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
395  if (uid == 0)
396  {
397  return false;
398  }
399  *tid = TypeId (uid);
400  return true;
401 }
402 
403 uint32_t
405 {
406  return Singleton<IidManager>::Get ()->GetRegisteredN ();
407 }
408 TypeId
410 {
412 }
413 
414 bool
415 TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInformation *info) const
416 {
417  TypeId tid;
418  TypeId nextTid = *this;
419  do {
420  tid = nextTid;
421  for (uint32_t i = 0; i < tid.GetAttributeN (); i++)
422  {
423  struct TypeId::AttributeInformation tmp = tid.GetAttribute(i);
424  if (tmp.name == name)
425  {
426  *info = tmp;
427  return true;
428  }
429  }
430  nextTid = tid.GetParent ();
431  } while (nextTid != tid);
432  return false;
433 }
434 
435 TypeId
437 {
438  Singleton<IidManager>::Get ()->SetParent (m_tid, tid.m_tid);
439  return *this;
440 }
441 TypeId
442 TypeId::SetGroupName (std::string groupName)
443 {
444  Singleton<IidManager>::Get ()->SetGroupName (m_tid, groupName);
445  return *this;
446 }
447 TypeId
448 TypeId::GetParent (void) const
449 {
450  uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
451  return TypeId (parent);
452 }
453 bool
454 TypeId::HasParent (void) const
455 {
456  uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
457  return parent != m_tid;
458 }
459 bool
461 {
462  TypeId tmp = *this;
463  while (tmp != other && tmp != tmp.GetParent ())
464  {
465  tmp = tmp.GetParent ();
466  }
467  return tmp == other && *this != other;
468 }
469 std::string
471 {
472  std::string groupName = Singleton<IidManager>::Get ()->GetGroupName (m_tid);
473  return groupName;
474 }
475 
476 std::string
477 TypeId::GetName (void) const
478 {
479  std::string name = Singleton<IidManager>::Get ()->GetName (m_tid);
480  return name;
481 }
482 
483 bool
485 {
486  bool hasConstructor = Singleton<IidManager>::Get ()->HasConstructor (m_tid);
487  return hasConstructor;
488 }
489 
490 void
492 {
493  Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb);
494 }
495 
496 TypeId
497 TypeId::AddAttribute (std::string name,
498  std::string help,
499  const AttributeValue &initialValue,
502 {
503  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue.Copy (), accessor, checker);
504  return *this;
505 }
506 
507 TypeId
508 TypeId::AddAttribute (std::string name,
509  std::string help,
510  uint32_t flags,
511  const AttributeValue &initialValue,
514 {
515  Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue.Copy (), accessor, checker);
516  return *this;
517 }
518 
519 bool
521  Ptr<const AttributeValue> initialValue)
522 {
523  Singleton<IidManager>::Get ()->SetAttributeInitialValue (m_tid, i, initialValue);
524  return true;
525 }
526 
527 
530 {
531  Callback<ObjectBase *> cb = Singleton<IidManager>::Get ()->GetConstructor (m_tid);
532  return cb;
533 }
534 
535 bool
537 {
538  bool mustHide = Singleton<IidManager>::Get ()->MustHideFromDocumentation (m_tid);
539  return mustHide;
540 }
541 
542 uint32_t
544 {
545  uint32_t n = Singleton<IidManager>::Get ()->GetAttributeN (m_tid);
546  return n;
547 }
549 TypeId::GetAttribute(uint32_t i) const
550 {
551  return Singleton<IidManager>::Get ()->GetAttribute(m_tid, i);
552 }
553 std::string
555 {
557  return GetName () + "::" + info.name;
558 }
559 
560 uint32_t
562 {
563  return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
564 }
566 TypeId::GetTraceSource(uint32_t i) const
567 {
568  return Singleton<IidManager>::Get ()->GetTraceSource(m_tid, i);
569 }
570 
571 TypeId
572 TypeId::AddTraceSource (std::string name,
573  std::string help,
575 {
576  Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
577  return *this;
578 }
579 
580 TypeId
582 {
583  Singleton<IidManager>::Get ()->HideFromDocumentation (m_tid);
584  return *this;
585 }
586 
587 
589 TypeId::LookupTraceSourceByName (std::string name) const
590 {
591  TypeId tid;
592  TypeId nextTid = *this;
593  do {
594  tid = nextTid;
595  for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
596  {
597  struct TypeId::TraceSourceInformation info = tid.GetTraceSource (i);
598  if (info.name == name)
599  {
600  return info.accessor;
601  }
602  }
603  nextTid = tid.GetParent ();
604  } while (nextTid != tid);
605  return 0;
606 }
607 
608 uint16_t
609 TypeId::GetUid (void) const
610 {
611  return m_tid;
612 }
613 void
614 TypeId::SetUid (uint16_t tid)
615 {
616  m_tid = tid;
617 }
618 
619 std::ostream & operator << (std::ostream &os, TypeId tid)
620 {
621  os << tid.GetName ();
622  return os;
623 }
624 std::istream & operator >> (std::istream &is, TypeId &tid)
625 {
626  std::string tidString;
627  is >> tidString;
628  bool ok = TypeId::LookupByNameFailSafe (tidString, &tid);
629  if (!ok)
630  {
631  is.setstate (std::ios_base::badbit);
632  }
633  return is;
634 }
635 
636 
637 ATTRIBUTE_HELPER_CPP (TypeId);
638 
640 {
641  return a.m_tid < b.m_tid;
642 }
643 
644 } // namespace ns3