00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "type-id.h"
00021 #include "singleton.h"
00022 #include "trace-source-accessor.h"
00023 #include <vector>
00024 #include <sstream>
00025
00026
00027
00028
00029
00030 namespace {
00031
00032 class IidManager
00033 {
00034 public:
00035 IidManager ();
00036 uint16_t AllocateUid (std::string name);
00037 void SetParent (uint16_t uid, uint16_t parent);
00038 void SetGroupName (uint16_t uid, std::string groupName);
00039 void AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback);
00040 void HideFromDocumentation (uint16_t uid);
00041 uint16_t GetUid (std::string name) const;
00042 std::string GetName (uint16_t uid) const;
00043 uint16_t GetParent (uint16_t uid) const;
00044 std::string GetGroupName (uint16_t uid) const;
00045 ns3::Callback<ns3::ObjectBase *> GetConstructor (uint16_t uid) const;
00046 bool HasConstructor (uint16_t uid) const;
00047 uint32_t GetRegisteredN (void) const;
00048 uint16_t GetRegistered (uint32_t i) const;
00049 void AddAttribute (uint16_t uid,
00050 std::string name,
00051 std::string help,
00052 uint32_t flags,
00053 ns3::Ptr<const ns3::AttributeValue> initialValue,
00054 ns3::Ptr<const ns3::AttributeAccessor> spec,
00055 ns3::Ptr<const ns3::AttributeChecker> checker);
00056 uint32_t GetAttributeN (uint16_t uid) const;
00057 std::string GetAttributeName (uint16_t uid, uint32_t i) const;
00058 std::string GetAttributeHelp (uint16_t uid, uint32_t i) const;
00059 uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const;
00060 ns3::Ptr<const ns3::AttributeValue> GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
00061 ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
00062 ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
00063 void AddTraceSource (uint16_t uid,
00064 std::string name,
00065 std::string help,
00066 ns3::Ptr<const ns3::TraceSourceAccessor> accessor);
00067 uint32_t GetTraceSourceN (uint16_t uid) const;
00068 std::string GetTraceSourceName (uint16_t uid, uint32_t i) const;
00069 std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const;
00070 ns3::Ptr<const ns3::TraceSourceAccessor> GetTraceSourceAccessor (uint16_t uid, uint32_t i) const;
00071 bool MustHideFromDocumentation (uint16_t uid) const;
00072
00073 private:
00074 struct AttributeInformation {
00075 std::string name;
00076 std::string help;
00077 uint32_t flags;
00078 ns3::Ptr<const ns3::AttributeValue> initialValue;
00079 ns3::Ptr<const ns3::AttributeAccessor> param;
00080 ns3::Ptr<const ns3::AttributeChecker> checker;
00081 };
00082 struct TraceSourceInformation {
00083 std::string name;
00084 std::string help;
00085 ns3::Ptr<const ns3::TraceSourceAccessor> accessor;
00086 };
00087 struct IidInformation {
00088 std::string name;
00089 uint16_t parent;
00090 std::string groupName;
00091 bool hasConstructor;
00092 ns3::Callback<ns3::ObjectBase *> constructor;
00093 bool mustHideFromDocumentation;
00094 std::vector<struct AttributeInformation> attributes;
00095 std::vector<struct TraceSourceInformation> traceSources;
00096 };
00097 typedef std::vector<struct IidInformation>::const_iterator Iterator;
00098
00099 struct IidManager::IidInformation *LookupInformation (uint16_t uid) const;
00100
00101 std::vector<struct IidInformation> m_information;
00102 };
00103
00104 IidManager::IidManager ()
00105 {}
00106
00107 uint16_t
00108 IidManager::AllocateUid (std::string name)
00109 {
00110 uint16_t j = 1;
00111 for (Iterator i = m_information.begin (); i != m_information.end (); i++)
00112 {
00113 if (i->name == name)
00114 {
00115 NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
00116 return 0;
00117 }
00118 j++;
00119 }
00120 struct IidInformation information;
00121 information.name = name;
00122 information.parent = 0;
00123 information.groupName = "";
00124 information.hasConstructor = false;
00125 information.mustHideFromDocumentation = false;
00126 m_information.push_back (information);
00127 uint32_t uid = m_information.size ();
00128 NS_ASSERT (uid <= 0xffff);
00129 return uid;
00130 }
00131
00132 struct IidManager::IidInformation *
00133 IidManager::LookupInformation (uint16_t uid) const
00134 {
00135 NS_ASSERT (uid <= m_information.size () && uid != 0);
00136 return const_cast<struct IidInformation *> (&m_information[uid-1]);
00137 }
00138
00139 void
00140 IidManager::SetParent (uint16_t uid, uint16_t parent)
00141 {
00142 NS_ASSERT (parent <= m_information.size ());
00143 struct IidInformation *information = LookupInformation (uid);
00144 information->parent = parent;
00145 }
00146 void
00147 IidManager::SetGroupName (uint16_t uid, std::string groupName)
00148 {
00149 struct IidInformation *information = LookupInformation (uid);
00150 information->groupName = groupName;
00151 }
00152 void
00153 IidManager::HideFromDocumentation (uint16_t uid)
00154 {
00155 struct IidInformation *information = LookupInformation (uid);
00156 information->mustHideFromDocumentation = true;
00157 }
00158
00159 void
00160 IidManager::AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback)
00161 {
00162 struct IidInformation *information = LookupInformation (uid);
00163 if (information->hasConstructor)
00164 {
00165 NS_FATAL_ERROR (information->name<<" already has a constructor.");
00166 }
00167 information->hasConstructor = true;
00168 information->constructor = callback;
00169 }
00170
00171 uint16_t
00172 IidManager::GetUid (std::string name) const
00173 {
00174 uint32_t j = 1;
00175 for (Iterator i = m_information.begin (); i != m_information.end (); i++)
00176 {
00177 if (i->name == name)
00178 {
00179 NS_ASSERT (j <= 0xffff);
00180 return j;
00181 }
00182 j++;
00183 }
00184 return 0;
00185 }
00186 std::string
00187 IidManager::GetName (uint16_t uid) const
00188 {
00189 struct IidInformation *information = LookupInformation (uid);
00190 return information->name;
00191 }
00192 uint16_t
00193 IidManager::GetParent (uint16_t uid) const
00194 {
00195 struct IidInformation *information = LookupInformation (uid);
00196 return information->parent;
00197 }
00198 std::string
00199 IidManager::GetGroupName (uint16_t uid) const
00200 {
00201 struct IidInformation *information = LookupInformation (uid);
00202 return information->groupName;
00203 }
00204
00205 ns3::Callback<ns3::ObjectBase *>
00206 IidManager::GetConstructor (uint16_t uid) const
00207 {
00208 struct IidInformation *information = LookupInformation (uid);
00209 if (!information->hasConstructor)
00210 {
00211 NS_FATAL_ERROR ("Requested constructor for "<<information->name<<" but it does not have one.");
00212 }
00213 return information->constructor;
00214 }
00215
00216 bool
00217 IidManager::HasConstructor (uint16_t uid) const
00218 {
00219 struct IidInformation *information = LookupInformation (uid);
00220 return information->hasConstructor;
00221 }
00222
00223 uint32_t
00224 IidManager::GetRegisteredN (void) const
00225 {
00226 return m_information.size ();
00227 }
00228 uint16_t
00229 IidManager::GetRegistered (uint32_t i) const
00230 {
00231 return i + 1;
00232 }
00233
00234 void
00235 IidManager::AddAttribute (uint16_t uid,
00236 std::string name,
00237 std::string help,
00238 uint32_t flags,
00239 ns3::Ptr<const ns3::AttributeValue> initialValue,
00240 ns3::Ptr<const ns3::AttributeAccessor> spec,
00241 ns3::Ptr<const ns3::AttributeChecker> checker)
00242 {
00243 struct IidInformation *information = LookupInformation (uid);
00244 for (std::vector<struct AttributeInformation>::const_iterator j = information->attributes.begin ();
00245 j != information->attributes.end (); j++)
00246 {
00247 if (j->name == name)
00248 {
00249 NS_FATAL_ERROR ("Registered the same attribute twice name=\""<<name<<"\" in TypeId=\""<<information->name<<"\"");
00250 return;
00251 }
00252 }
00253 struct AttributeInformation param;
00254 param.name = name;
00255 param.help = help;
00256 param.flags = flags;
00257 param.initialValue = initialValue;
00258 param.param = spec;
00259 param.checker = checker;
00260 information->attributes.push_back (param);
00261 }
00262
00263
00264 uint32_t
00265 IidManager::GetAttributeN (uint16_t uid) const
00266 {
00267 struct IidInformation *information = LookupInformation (uid);
00268 return information->attributes.size ();
00269 }
00270 std::string
00271 IidManager::GetAttributeName (uint16_t uid, uint32_t i) const
00272 {
00273 struct IidInformation *information = LookupInformation (uid);
00274 NS_ASSERT (i < information->attributes.size ());
00275 return information->attributes[i].name;
00276 }
00277 std::string
00278 IidManager::GetAttributeHelp (uint16_t uid, uint32_t i) const
00279 {
00280 struct IidInformation *information = LookupInformation (uid);
00281 NS_ASSERT (i < information->attributes.size ());
00282 return information->attributes[i].help;
00283 }
00284 uint32_t
00285 IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const
00286 {
00287 struct IidInformation *information = LookupInformation (uid);
00288 NS_ASSERT (i < information->attributes.size ());
00289 return information->attributes[i].flags;
00290 }
00291 ns3::Ptr<const ns3::AttributeValue>
00292 IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const
00293 {
00294 struct IidInformation *information = LookupInformation (uid);
00295 NS_ASSERT (i < information->attributes.size ());
00296 return information->attributes[i].initialValue;
00297 }
00298 ns3::Ptr<const ns3::AttributeAccessor>
00299 IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const
00300 {
00301 struct IidInformation *information = LookupInformation (uid);
00302 NS_ASSERT (i < information->attributes.size ());
00303 return information->attributes[i].param;
00304 }
00305 ns3::Ptr<const ns3::AttributeChecker>
00306 IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const
00307 {
00308 struct IidInformation *information = LookupInformation (uid);
00309 NS_ASSERT (i < information->attributes.size ());
00310 return information->attributes[i].checker;
00311 }
00312
00313 void
00314 IidManager::AddTraceSource (uint16_t uid,
00315 std::string name,
00316 std::string help,
00317 ns3::Ptr<const ns3::TraceSourceAccessor> accessor)
00318 {
00319 struct IidInformation *information = LookupInformation (uid);
00320 struct TraceSourceInformation source;
00321 source.name = name;
00322 source.help = help;
00323 source.accessor = accessor;
00324 information->traceSources.push_back (source);
00325 }
00326 uint32_t
00327 IidManager::GetTraceSourceN (uint16_t uid) const
00328 {
00329 struct IidInformation *information = LookupInformation (uid);
00330 return information->traceSources.size ();
00331 }
00332 std::string
00333 IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const
00334 {
00335 struct IidInformation *information = LookupInformation (uid);
00336 NS_ASSERT (i < information->traceSources.size ());
00337 return information->traceSources[i].name;
00338 }
00339 std::string
00340 IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const
00341 {
00342 struct IidInformation *information = LookupInformation (uid);
00343 NS_ASSERT (i < information->traceSources.size ());
00344 return information->traceSources[i].help;
00345 }
00346 ns3::Ptr<const ns3::TraceSourceAccessor>
00347 IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const
00348 {
00349 struct IidInformation *information = LookupInformation (uid);
00350 NS_ASSERT (i < information->traceSources.size ());
00351 return information->traceSources[i].accessor;
00352 }
00353 bool
00354 IidManager::MustHideFromDocumentation (uint16_t uid) const
00355 {
00356 struct IidInformation *information = LookupInformation (uid);
00357 return information->mustHideFromDocumentation;
00358 }
00359
00360 }
00361
00362 namespace ns3 {
00363
00364
00365
00366
00367
00368 TypeId::TypeId (const char *name)
00369 {
00370 uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
00371 NS_ASSERT (uid != 0);
00372 m_tid = uid;
00373 }
00374
00375
00376 TypeId::TypeId (uint16_t tid)
00377 : m_tid (tid)
00378 {}
00379 TypeId
00380 TypeId::LookupByName (std::string name)
00381 {
00382 uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
00383 NS_ASSERT_MSG (uid != 0, "Assert in TypeId::LookupByName: " << name << " not found");
00384 return TypeId (uid);
00385 }
00386 bool
00387 TypeId::LookupByNameFailSafe (std::string name, TypeId *tid)
00388 {
00389 uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
00390 if (uid == 0)
00391 {
00392 return false;
00393 }
00394 *tid = TypeId (uid);
00395 return true;
00396 }
00397
00398 bool
00399 TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info)
00400 {
00401 std::string::size_type pos = fullName.rfind ("::");
00402 if (pos == std::string::npos)
00403 {
00404 return 0;
00405 }
00406 std::string tidName = fullName.substr (0, pos);
00407 std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2));
00408 TypeId tid;
00409 bool ok = LookupByNameFailSafe (tidName, &tid);
00410 if (!ok)
00411 {
00412 return false;
00413 }
00414 return tid.LookupAttributeByName (paramName, info);
00415 }
00416 uint32_t
00417 TypeId::GetRegisteredN (void)
00418 {
00419 return Singleton<IidManager>::Get ()->GetRegisteredN ();
00420 }
00421 TypeId
00422 TypeId::GetRegistered (uint32_t i)
00423 {
00424 return TypeId (Singleton<IidManager>::Get ()->GetRegistered (i));
00425 }
00426
00427 bool
00428 TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const
00429 {
00430 TypeId tid;
00431 TypeId nextTid = *this;
00432 do {
00433 tid = nextTid;
00434 for (uint32_t i = 0; i < tid.GetAttributeN (); i++)
00435 {
00436 std::string paramName = tid.GetAttributeName (i);
00437 if (paramName == name)
00438 {
00439 info->accessor = tid.GetAttributeAccessor (i);
00440 info->flags = tid.GetAttributeFlags (i);
00441 info->initialValue = tid.GetAttributeInitialValue (i);
00442 info->checker = tid.GetAttributeChecker (i);
00443 return true;
00444 }
00445 }
00446 nextTid = tid.GetParent ();
00447 } while (nextTid != tid);
00448 return false;
00449 }
00450
00451 TypeId
00452 TypeId::SetParent (TypeId tid)
00453 {
00454 Singleton<IidManager>::Get ()->SetParent (m_tid, tid.m_tid);
00455 return *this;
00456 }
00457 TypeId
00458 TypeId::SetGroupName (std::string groupName)
00459 {
00460 Singleton<IidManager>::Get ()->SetGroupName (m_tid, groupName);
00461 return *this;
00462 }
00463 TypeId
00464 TypeId::GetParent (void) const
00465 {
00466 uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
00467 return TypeId (parent);
00468 }
00469 bool
00470 TypeId::HasParent (void) const
00471 {
00472 uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
00473 return parent != m_tid;
00474 }
00475 bool
00476 TypeId::IsChildOf (TypeId other) const
00477 {
00478 TypeId tmp = *this;
00479 while (tmp != other && tmp != tmp.GetParent ())
00480 {
00481 tmp = tmp.GetParent ();
00482 }
00483 return tmp == other && *this != other;
00484 }
00485 std::string
00486 TypeId::GetGroupName (void) const
00487 {
00488 std::string groupName = Singleton<IidManager>::Get ()->GetGroupName (m_tid);
00489 return groupName;
00490 }
00491
00492 std::string
00493 TypeId::GetName (void) const
00494 {
00495 std::string name = Singleton<IidManager>::Get ()->GetName (m_tid);
00496 return name;
00497 }
00498
00499 bool
00500 TypeId::HasConstructor (void) const
00501 {
00502 bool hasConstructor = Singleton<IidManager>::Get ()->HasConstructor (m_tid);
00503 return hasConstructor;
00504 }
00505
00506 void
00507 TypeId::DoAddConstructor (Callback<ObjectBase *> cb)
00508 {
00509 Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb);
00510 }
00511
00512 TypeId
00513 TypeId::AddAttribute (std::string name,
00514 std::string help,
00515 const AttributeValue &initialValue,
00516 Ptr<const AttributeAccessor> param,
00517 Ptr<const AttributeChecker> checker)
00518 {
00519 Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue.Copy (), param, checker);
00520 return *this;
00521 }
00522
00523 TypeId
00524 TypeId::AddAttribute (std::string name,
00525 std::string help,
00526 uint32_t flags,
00527 const AttributeValue &initialValue,
00528 Ptr<const AttributeAccessor> param,
00529 Ptr<const AttributeChecker> checker)
00530 {
00531 Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue.Copy (), param, checker);
00532 return *this;
00533 }
00534
00535 Callback<ObjectBase *>
00536 TypeId::GetConstructor (void) const
00537 {
00538 Callback<ObjectBase *> cb = Singleton<IidManager>::Get ()->GetConstructor (m_tid);
00539 return cb;
00540 }
00541
00542 bool
00543 TypeId::MustHideFromDocumentation (void) const
00544 {
00545 bool mustHide = Singleton<IidManager>::Get ()->MustHideFromDocumentation (m_tid);
00546 return mustHide;
00547 }
00548
00549 uint32_t
00550 TypeId::GetAttributeN (void) const
00551 {
00552 uint32_t n = Singleton<IidManager>::Get ()->GetAttributeN (m_tid);
00553 return n;
00554 }
00555 std::string
00556 TypeId::GetAttributeName (uint32_t i) const
00557 {
00558 std::string name = Singleton<IidManager>::Get ()->GetAttributeName (m_tid, i);
00559 return name;
00560 }
00561 std::string
00562 TypeId::GetAttributeHelp (uint32_t i) const
00563 {
00564 std::string help = Singleton<IidManager>::Get ()->GetAttributeHelp (m_tid, i);
00565 return help;
00566 }
00567 std::string
00568 TypeId::GetAttributeFullName (uint32_t i) const
00569 {
00570 return GetName () + "::" + GetAttributeName (i);
00571 }
00572 Ptr<const AttributeValue>
00573 TypeId::GetAttributeInitialValue (uint32_t i) const
00574 {
00575 Ptr<const AttributeValue> value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
00576 return value;
00577 }
00578 Ptr<const AttributeAccessor>
00579 TypeId::GetAttributeAccessor (uint32_t i) const
00580 {
00581
00582 Ptr<const AttributeAccessor> param = Singleton<IidManager>::Get ()->GetAttributeAccessor (m_tid, i);
00583 return param;
00584 }
00585 uint32_t
00586 TypeId::GetAttributeFlags (uint32_t i) const
00587 {
00588
00589 uint32_t flags = Singleton<IidManager>::Get ()->GetAttributeFlags (m_tid, i);
00590 return flags;
00591 }
00592 Ptr<const AttributeChecker>
00593 TypeId::GetAttributeChecker (uint32_t i) const
00594 {
00595
00596 Ptr<const AttributeChecker> checker = Singleton<IidManager>::Get ()->GetAttributeChecker (m_tid, i);
00597 return checker;
00598 }
00599
00600 uint32_t
00601 TypeId::GetTraceSourceN (void) const
00602 {
00603 return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
00604 }
00605 std::string
00606 TypeId::GetTraceSourceName (uint32_t i) const
00607 {
00608 return Singleton<IidManager>::Get ()->GetTraceSourceName (m_tid, i);
00609 }
00610 std::string
00611 TypeId::GetTraceSourceHelp (uint32_t i) const
00612 {
00613 return Singleton<IidManager>::Get ()->GetTraceSourceHelp (m_tid, i);
00614 }
00615 Ptr<const TraceSourceAccessor>
00616 TypeId::GetTraceSourceAccessor (uint32_t i) const
00617 {
00618 return Singleton<IidManager>::Get ()->GetTraceSourceAccessor (m_tid, i);
00619 }
00620
00621 TypeId
00622 TypeId::AddTraceSource (std::string name,
00623 std::string help,
00624 Ptr<const TraceSourceAccessor> accessor)
00625 {
00626 Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
00627 return *this;
00628 }
00629
00630 TypeId
00631 TypeId::HideFromDocumentation (void)
00632 {
00633 Singleton<IidManager>::Get ()->HideFromDocumentation (m_tid);
00634 return *this;
00635 }
00636
00637
00638 Ptr<const TraceSourceAccessor>
00639 TypeId::LookupTraceSourceByName (std::string name) const
00640 {
00641 TypeId tid;
00642 TypeId nextTid = *this;
00643 do {
00644 tid = nextTid;
00645 for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
00646 {
00647 std::string srcName = tid.GetTraceSourceName (i);
00648 if (srcName == name)
00649 {
00650 return tid.GetTraceSourceAccessor (i);
00651 }
00652 }
00653 nextTid = tid.GetParent ();
00654 } while (nextTid != tid);
00655 return 0;
00656 }
00657
00658 uint16_t
00659 TypeId::GetUid (void) const
00660 {
00661 return m_tid;
00662 }
00663 void
00664 TypeId::SetUid (uint16_t tid)
00665 {
00666 m_tid = tid;
00667 }
00668
00669 std::ostream & operator << (std::ostream &os, TypeId tid)
00670 {
00671 os << tid.GetName ();
00672 return os;
00673 }
00674 std::istream & operator >> (std::istream &is, TypeId &tid)
00675 {
00676 std::string tidString;
00677 is >> tidString;
00678 bool ok = TypeId::LookupByNameFailSafe (tidString, &tid);
00679 if (!ok)
00680 {
00681 is.setstate (std::ios_base::badbit);
00682 }
00683 return is;
00684 }
00685
00686
00687 ATTRIBUTE_HELPER_CPP (TypeId);
00688
00689 bool operator < (TypeId a, TypeId b)
00690 {
00691 return a.m_tid < b.m_tid;
00692 }
00693
00694 }