/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INRIA, Gustavo Carneiro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Authors: Gustavo Carneiro , * Mathieu Lacage */ #include "object.h" #include "assert.h" #include "singleton.h" #include "attribute.h" #include "trace-source-accessor.h" #include "log.h" #include "string.h" #include #include NS_LOG_COMPONENT_DEFINE ("Object"); /********************************************************************* * Helper code *********************************************************************/ namespace { class IidManager { public: IidManager (); uint16_t AllocateUid (std::string name); void SetParent (uint16_t uid, uint16_t parent); void SetTypeName (uint16_t uid, std::string typeName); void SetGroupName (uint16_t uid, std::string groupName); void AddConstructor (uint16_t uid, ns3::CallbackBase callback); void HideFromDocumentation (uint16_t uid); uint16_t GetUid (std::string name) const; std::string GetName (uint16_t uid) const; uint16_t GetParent (uint16_t uid) const; std::string GetTypeName (uint16_t uid) const; std::string GetGroupName (uint16_t uid) const; ns3::CallbackBase GetConstructor (uint16_t uid); bool HasConstructor (uint16_t uid); uint32_t GetRegisteredN (void); uint16_t GetRegistered (uint32_t i); void AddAttribute (uint16_t uid, std::string name, std::string help, uint32_t flags, ns3::Attribute initialValue, ns3::Ptr spec, ns3::Ptr checker); uint32_t GetAttributeListN (uint16_t uid) const; std::string GetAttributeName (uint16_t uid, uint32_t i) const; std::string GetAttributeHelp (uint16_t uid, uint32_t i) const; uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const; ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const; ns3::Ptr GetAttributeAccessor (uint16_t uid, uint32_t i) const; ns3::Ptr GetAttributeChecker (uint16_t uid, uint32_t i) const; void AddTraceSource (uint16_t uid, std::string name, std::string help, ns3::Ptr accessor); uint32_t GetTraceSourceN (uint16_t uid) const; std::string GetTraceSourceName (uint16_t uid, uint32_t i) const; std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const; ns3::Ptr GetTraceSourceAccessor (uint16_t uid, uint32_t i) const; bool MustHideFromDocumentation (uint16_t uid) const; private: struct AttributeInformation { std::string name; std::string help; uint32_t flags; ns3::Attribute initialValue; ns3::Ptr param; ns3::Ptr checker; }; struct TraceSourceInformation { std::string name; std::string help; ns3::Ptr accessor; }; struct IidInformation { std::string name; uint16_t parent; std::string typeName; std::string groupName; bool hasConstructor; ns3::CallbackBase constructor; bool mustHideFromDocumentation; std::vector attributes; std::vector traceSources; }; typedef std::vector::const_iterator Iterator; struct IidManager::IidInformation *LookupInformation (uint16_t uid) const; std::vector m_information; }; IidManager::IidManager () {} uint16_t IidManager::AllocateUid (std::string name) { uint16_t j = 1; for (Iterator i = m_information.begin (); i != m_information.end (); i++) { if (i->name == name) { NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name); return 0; } j++; } struct IidInformation information; information.name = name; information.parent = 0; information.typeName = ""; information.groupName = ""; information.hasConstructor = false; information.mustHideFromDocumentation = false; m_information.push_back (information); uint32_t uid = m_information.size (); NS_ASSERT (uid <= 0xffff); return uid; } struct IidManager::IidInformation * IidManager::LookupInformation (uint16_t uid) const { NS_ASSERT (uid <= m_information.size ()); return const_cast (&m_information[uid-1]); } void IidManager::SetParent (uint16_t uid, uint16_t parent) { NS_ASSERT (parent <= m_information.size ()); struct IidInformation *information = LookupInformation (uid); information->parent = parent; } void IidManager::SetTypeName (uint16_t uid, std::string typeName) { struct IidInformation *information = LookupInformation (uid); information->typeName = typeName; } void IidManager::SetGroupName (uint16_t uid, std::string groupName) { struct IidInformation *information = LookupInformation (uid); information->groupName = groupName; } void IidManager::HideFromDocumentation (uint16_t uid) { struct IidInformation *information = LookupInformation (uid); information->mustHideFromDocumentation = true; } void IidManager::AddConstructor (uint16_t uid, ns3::CallbackBase callback) { struct IidInformation *information = LookupInformation (uid); if (information->hasConstructor) { NS_FATAL_ERROR (information->name<<" already has a constructor."); } information->hasConstructor = true; information->constructor = callback; } uint16_t IidManager::GetUid (std::string name) const { uint32_t j = 1; for (Iterator i = m_information.begin (); i != m_information.end (); i++) { if (i->name == name) { NS_ASSERT (j <= 0xffff); return j; } j++; } return 0; } std::string IidManager::GetName (uint16_t uid) const { struct IidInformation *information = LookupInformation (uid); return information->name; } uint16_t IidManager::GetParent (uint16_t uid) const { struct IidInformation *information = LookupInformation (uid); return information->parent; } std::string IidManager::GetTypeName (uint16_t uid) const { struct IidInformation *information = LookupInformation (uid); return information->typeName; } std::string IidManager::GetGroupName (uint16_t uid) const { struct IidInformation *information = LookupInformation (uid); return information->groupName; } ns3::CallbackBase IidManager::GetConstructor (uint16_t uid) { struct IidInformation *information = LookupInformation (uid); if (!information->hasConstructor) { NS_FATAL_ERROR ("Requested constructor for "<name<<" but it does not have one."); } return information->constructor; } bool IidManager::HasConstructor (uint16_t uid) { struct IidInformation *information = LookupInformation (uid); return information->hasConstructor; } uint32_t IidManager::GetRegisteredN (void) { return m_information.size (); } uint16_t IidManager::GetRegistered (uint32_t i) { return i + 1; } void IidManager::AddAttribute (uint16_t uid, std::string name, std::string help, uint32_t flags, ns3::Attribute initialValue, ns3::Ptr spec, ns3::Ptr checker) { struct IidInformation *information = LookupInformation (uid); for (std::vector::const_iterator j = information->attributes.begin (); j != information->attributes.end (); j++) { if (j->name == name) { NS_FATAL_ERROR ("Registered the same attribute twice name=\""<name<<"\""); return; } } struct AttributeInformation param; param.name = name; param.help = help; param.flags = flags; param.initialValue = initialValue; param.param = spec; param.checker = checker; information->attributes.push_back (param); } uint32_t IidManager::GetAttributeListN (uint16_t uid) const { struct IidInformation *information = LookupInformation (uid); return information->attributes.size (); } std::string IidManager::GetAttributeName (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->attributes.size ()); return information->attributes[i].name; } std::string IidManager::GetAttributeHelp (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->attributes.size ()); return information->attributes[i].help; } uint32_t IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->attributes.size ()); return information->attributes[i].flags; } ns3::Attribute IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->attributes.size ()); return information->attributes[i].initialValue; } ns3::Ptr IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->attributes.size ()); return information->attributes[i].param; } ns3::Ptr IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->attributes.size ()); return information->attributes[i].checker; } void IidManager::AddTraceSource (uint16_t uid, std::string name, std::string help, ns3::Ptr accessor) { struct IidInformation *information = LookupInformation (uid); struct TraceSourceInformation source; source.name = name; source.help = help; source.accessor = accessor; information->traceSources.push_back (source); } uint32_t IidManager::GetTraceSourceN (uint16_t uid) const { struct IidInformation *information = LookupInformation (uid); return information->traceSources.size (); } std::string IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->traceSources.size ()); return information->traceSources[i].name; } std::string IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->traceSources.size ()); return information->traceSources[i].help; } ns3::Ptr IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const { struct IidInformation *information = LookupInformation (uid); NS_ASSERT (i < information->traceSources.size ()); return information->traceSources[i].accessor; } bool IidManager::MustHideFromDocumentation (uint16_t uid) const { struct IidInformation *information = LookupInformation (uid); return information->mustHideFromDocumentation; } } // anonymous namespace namespace ns3 { /********************************************************************* * The TypeId class *********************************************************************/ TypeId::TypeId () : m_tid (0) {} TypeId::TypeId (const char *name) { uint16_t uid = Singleton::Get ()->AllocateUid (name); NS_ASSERT (uid != 0); m_tid = uid; } TypeId::TypeId (uint16_t tid) : m_tid (tid) {} TypeId::~TypeId () {} TypeId TypeId::LookupByName (std::string name) { uint16_t uid = Singleton::Get ()->GetUid (name); NS_ASSERT (uid != 0); return TypeId (uid); } bool TypeId::LookupByNameFailSafe (std::string name, TypeId *tid) { uint16_t uid = Singleton::Get ()->GetUid (name); if (uid == 0) { return false; } *tid = TypeId (uid); return true; } bool TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info) { std::string::size_type pos = fullName.rfind ("::"); if (pos == std::string::npos) { return 0; } std::string tidName = fullName.substr (0, pos); std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2)); TypeId tid; bool ok = LookupByNameFailSafe (tidName, &tid); if (!ok) { return false; } return tid.LookupAttributeByName (paramName, info); } uint32_t TypeId::GetRegisteredN (void) { return Singleton::Get ()->GetRegisteredN (); } TypeId TypeId::GetRegistered (uint32_t i) { return TypeId (Singleton::Get ()->GetRegistered (i)); } bool TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const { TypeId tid; TypeId nextTid = *this; do { tid = nextTid; for (uint32_t i = 0; i < tid.GetAttributeListN (); i++) { std::string paramName = tid.GetAttributeName (i); if (paramName == name) { info->accessor = tid.GetAttributeAccessor (i); info->flags = tid.GetAttributeFlags (i); info->initialValue = tid.GetAttributeInitialValue (i); info->checker = tid.GetAttributeChecker (i); return true; } } nextTid = tid.GetParent (); } while (nextTid != tid); return false; } TypeId TypeId::SetParent (TypeId tid) { Singleton::Get ()->SetParent (m_tid, tid.m_tid); return *this; } TypeId TypeId::SetGroupName (std::string groupName) { Singleton::Get ()->SetGroupName (m_tid, groupName); return *this; } TypeId TypeId::SetTypeName (std::string typeName) { Singleton::Get ()->SetTypeName (m_tid, typeName); return *this; } TypeId TypeId::GetParent (void) const { uint16_t parent = Singleton::Get ()->GetParent (m_tid); return TypeId (parent); } std::string TypeId::GetGroupName (void) const { std::string groupName = Singleton::Get ()->GetGroupName (m_tid); return groupName; } std::string TypeId::GetTypeName (void) const { std::string typeName = Singleton::Get ()->GetTypeName (m_tid); return typeName; } std::string TypeId::GetName (void) const { std::string name = Singleton::Get ()->GetName (m_tid); return name; } bool TypeId::HasConstructor (void) const { bool hasConstructor = Singleton::Get ()->HasConstructor (m_tid); return hasConstructor; } void TypeId::DoAddConstructor (CallbackBase cb) { Singleton::Get ()->AddConstructor (m_tid, cb); } TypeId TypeId::AddAttribute (std::string name, std::string help, Attribute initialValue, Ptr param, Ptr checker) { Singleton::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker); return *this; } TypeId TypeId::AddAttribute (std::string name, std::string help, uint32_t flags, Attribute initialValue, Ptr param, Ptr checker) { Singleton::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker); return *this; } CallbackBase TypeId::LookupConstructor (void) const { CallbackBase constructor = Singleton::Get ()->GetConstructor (m_tid); return constructor; } Ptr TypeId::CreateObject (void) const { return CreateObject (AttributeList ()); } Ptr TypeId::CreateObject (const AttributeList &attributes) const { CallbackBase cb = LookupConstructor (); Callback,const AttributeList &> realCb; realCb.Assign (cb); Ptr object = realCb (attributes); return object; } bool TypeId::MustHideFromDocumentation (void) const { bool mustHide = Singleton::Get ()->MustHideFromDocumentation (m_tid); return mustHide; } uint32_t TypeId::GetAttributeListN (void) const { uint32_t n = Singleton::Get ()->GetAttributeListN (m_tid); return n; } std::string TypeId::GetAttributeName (uint32_t i) const { std::string name = Singleton::Get ()->GetAttributeName (m_tid, i); return name; } std::string TypeId::GetAttributeHelp (uint32_t i) const { std::string help = Singleton::Get ()->GetAttributeHelp (m_tid, i); return help; } std::string TypeId::GetAttributeFullName (uint32_t i) const { return GetName () + "::" + GetAttributeName (i); } Attribute TypeId::GetAttributeInitialValue (uint32_t i) const { Attribute value = Singleton::Get ()->GetAttributeInitialValue (m_tid, i); return value; } Ptr TypeId::GetAttributeAccessor (uint32_t i) const { // Used exclusively by the Object class. Ptr param = Singleton::Get ()->GetAttributeAccessor (m_tid, i); return param; } uint32_t TypeId::GetAttributeFlags (uint32_t i) const { // Used exclusively by the Object class. uint32_t flags = Singleton::Get ()->GetAttributeFlags (m_tid, i); return flags; } Ptr TypeId::GetAttributeChecker (uint32_t i) const { // Used exclusively by the Object class. Ptr checker = Singleton::Get ()->GetAttributeChecker (m_tid, i); return checker; } uint32_t TypeId::GetTraceSourceN (void) const { return Singleton::Get ()->GetTraceSourceN (m_tid); } std::string TypeId::GetTraceSourceName (uint32_t i) const { return Singleton::Get ()->GetTraceSourceName (m_tid, i); } std::string TypeId::GetTraceSourceHelp (uint32_t i) const { return Singleton::Get ()->GetTraceSourceHelp (m_tid, i); } Ptr TypeId::GetTraceSourceAccessor (uint32_t i) const { return Singleton::Get ()->GetTraceSourceAccessor (m_tid, i); } TypeId TypeId::AddTraceSource (std::string name, std::string help, Ptr accessor) { Singleton::Get ()->AddTraceSource (m_tid, name, help, accessor); return *this; } TypeId TypeId::HideFromDocumentation (void) { Singleton::Get ()->HideFromDocumentation (m_tid); return *this; } Ptr TypeId::LookupTraceSourceByName (std::string name) const { TypeId tid; TypeId nextTid = *this; do { tid = nextTid; for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++) { std::string srcName = tid.GetTraceSourceName (i); if (srcName == name) { return tid.GetTraceSourceAccessor (i); } } nextTid = tid.GetParent (); } while (nextTid != tid); return 0; } std::ostream & operator << (std::ostream &os, TypeId tid) { os << tid.GetName (); return os; } std::istream & operator >> (std::istream &is, TypeId &tid) { std::string tidString; is >> tidString; bool ok = TypeId::LookupByNameFailSafe (tidString, &tid); if (!ok) { is.setstate (std::ios_base::badbit); } return is; } ATTRIBUTE_HELPER_CPP (TypeId); bool operator == (TypeId a, TypeId b) { return a.m_tid == b.m_tid; } bool operator != (TypeId a, TypeId b) { return a.m_tid != b.m_tid; } /********************************************************************* * The AttributeList container implementation *********************************************************************/ AttributeList::AttributeList () {} AttributeList::AttributeList (const AttributeList &o) { for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++) { struct Attr attr; attr.checker = i->checker; attr.value = i->value.Copy (); m_attributes.push_back (attr); } } AttributeList & AttributeList::operator = (const AttributeList &o) { Reset (); for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++) { struct Attr attr; attr.checker = i->checker; attr.value = i->value.Copy (); m_attributes.push_back (attr); } return *this; } AttributeList::~AttributeList () { Reset (); } void AttributeList::Set (std::string name, Attribute value) { struct TypeId::AttributeInfo info; bool ok = TypeId::LookupAttributeByFullName (name, &info); if (!ok) { NS_FATAL_ERROR ("Could not find attribute "< checker, Attribute value) { // get rid of any previous value stored in this // vector of values. for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++) { if (k->checker == checker) { m_attributes.erase (k); break; } } // store the new value. struct Attr attr; attr.checker = checker; attr.value = value.Copy (); m_attributes.push_back (attr); } bool AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value) { if (info->checker == 0) { return false; } bool ok = info->checker->Check (value); if (!ok) { // attempt to convert to string. const StringValue *str = value.DynCast (); if (str == 0) { return false; } // attempt to convert back to value. Attribute v = info->checker->Create (); ok = v.DeserializeFromString (str->Get ().Get (), info->checker); if (!ok) { return false; } ok = info->checker->Check (v); if (!ok) { return false; } value = v; } DoSetOne (info->checker, value); return true; } void AttributeList::Reset (void) { m_attributes.clear (); } AttributeList * AttributeList::GetGlobal (void) { return Singleton::Get (); } std::string AttributeList::LookupAttributeFullNameByChecker (Ptr checker) const { for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++) { TypeId tid = TypeId::GetRegistered (i); for (uint32_t j = 0; j < tid.GetAttributeListN (); j++) { if (checker == tid.GetAttributeChecker (j)) { return tid.GetAttributeFullName (j); } } } NS_FATAL_ERROR ("Could not find requested Accessor."); // quiet compiler. return ""; } std::string AttributeList::SerializeToString (void) const { std::ostringstream oss; for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++) { std::string name = LookupAttributeFullNameByChecker (i->checker); oss << name << "=" << i->value.SerializeToString (i->checker); if (i != m_attributes.end ()) { oss << "|"; } } return oss.str (); } bool AttributeList::DeserializeFromString (std::string str) { Reset (); std::string::size_type cur; cur = 0; do { std::string::size_type equal = str.find ("=", cur); if (equal == std::string::npos) { // XXX: invalid attribute. break; } else { std::string name = str.substr (cur, equal-cur); struct TypeId::AttributeInfo info; if (!TypeId::LookupAttributeByFullName (name, &info)) { // XXX invalid name. break; } else { std::string::size_type next = str.find ("|", cur); std::string value; if (next == std::string::npos) { value = str.substr (equal+1, str.size () - (equal+1)); cur = str.size (); } else { value = str.substr (equal+1, next - (equal+1)); cur++; } Attribute val = info.checker->Create (); bool ok = val.DeserializeFromString (value, info.checker); if (!ok) { // XXX invalid value break; } else { DoSetOne (info.checker, val); } } } } while (cur != str.size ()); return true; } /********************************************************************* * The Object implementation *********************************************************************/ NS_OBJECT_ENSURE_REGISTERED (Object); static TypeId GetObjectIid (void) { TypeId tid = TypeId ("ns3::Object"); tid.SetParent (tid); return tid; } TypeId Object::GetTypeId (void) { static TypeId tid = GetObjectIid (); return tid; } Object::Object () : m_count (1), m_tid (Object::GetTypeId ()), m_disposed (false), m_collecting (false), m_next (this) {} Object::~Object () { m_next = 0; } void Object::Construct (const AttributeList &attributes) { // loop over the inheritance tree back to the Object base class. TypeId tid = m_tid; do { // loop over all attributes in object type NS_LOG_DEBUG ("construct tid="<checker == checker) { // We have a matching attribute value. DoSet (paramSpec, initial, checker, j->value); NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<< tid.GetAttributeName (i)<<"\""); found = true; break; } } if (!found) { // is this attribute stored in the global instance instance ? for (AttributeList::Attrs::const_iterator j = AttributeList::GetGlobal ()->m_attributes.begin (); j != AttributeList::GetGlobal ()->m_attributes.end (); j++) { if (j->checker == checker) { // We have a matching attribute value. DoSet (paramSpec, initial, checker, j->value); NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<< tid.GetAttributeName (i)<<"\" from global"); found = true; break; } } } if (!found) { // No matching attribute value so we set the default value. paramSpec->Set (this, initial); NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<< tid.GetAttributeName (i)<<"\" from initial value."); } } tid = tid.GetParent (); } while (tid != Object::GetTypeId ()); NotifyConstructionCompleted (); } bool Object::DoSet (Ptr spec, Attribute initialValue, Ptr checker, Attribute value) { bool ok = checker->Check (value); if (!ok) { // attempt to convert to string const StringValue *str = value.DynCast (); if (str == 0) { return false; } // attempt to convert back from string. Attribute v = checker->Create (); ok = v.DeserializeFromString (str->Get ().Get (), checker); if (!ok) { return false; } ok = checker->Check (v); if (!ok) { return false; } value = v; } ok = spec->Set (this, value); return ok; } void Object::SetAttribute (std::string name, Attribute value) { struct TypeId::AttributeInfo info; if (!m_tid.LookupAttributeByName (name, &info)) { NS_FATAL_ERROR ("Attribute name="< (); return tid; } BaseA () {} virtual void Dispose (void) {} }; class DerivedA : public BaseA { public: static ns3::TypeId GetTypeId (void) { static ns3::TypeId tid = ns3::TypeId ("DerivedA") .SetParent (BaseA::GetTypeId ()) .HideFromDocumentation () .AddConstructor (); return tid; } DerivedA () {} virtual void Dispose (void) { BaseA::Dispose (); } }; class BaseB : public ns3::Object { public: static ns3::TypeId GetTypeId (void) { static ns3::TypeId tid = ns3::TypeId ("BaseB") .SetParent (Object::GetTypeId ()) .HideFromDocumentation () .AddConstructor (); return tid; } BaseB () {} virtual void Dispose (void) {} }; class DerivedB : public BaseB { public: static ns3::TypeId GetTypeId (void) { static ns3::TypeId tid = ns3::TypeId ("DerivedB") .SetParent (BaseB::GetTypeId ()) .HideFromDocumentation () .AddConstructor (); return tid; } DerivedB () {} virtual void Dispose (void) { BaseB::Dispose (); } }; NS_OBJECT_ENSURE_REGISTERED (BaseA); NS_OBJECT_ENSURE_REGISTERED (DerivedA); NS_OBJECT_ENSURE_REGISTERED (BaseB); NS_OBJECT_ENSURE_REGISTERED (DerivedB); } // namespace anonymous namespace ns3 { class ObjectTest : public Test { public: ObjectTest (); virtual bool RunTests (void); }; ObjectTest::ObjectTest () : Test ("Object") {} bool ObjectTest::RunTests (void) { bool result = true; Ptr baseA = CreateObject (); NS_TEST_ASSERT_EQUAL (baseA->GetObject (), baseA); NS_TEST_ASSERT_EQUAL (baseA->GetObject (DerivedA::GetTypeId ()), 0); NS_TEST_ASSERT_EQUAL (baseA->GetObject (), 0); baseA = CreateObject (); NS_TEST_ASSERT_EQUAL (baseA->GetObject (), baseA); NS_TEST_ASSERT_EQUAL (baseA->GetObject (DerivedA::GetTypeId ()), baseA); NS_TEST_ASSERT_UNEQUAL (baseA->GetObject (), 0); baseA = CreateObject (); Ptr baseB = CreateObject (); Ptr baseBCopy = baseB; baseA->AggregateObject (baseB); NS_TEST_ASSERT_UNEQUAL (baseA->GetObject (), 0); NS_TEST_ASSERT_EQUAL (baseA->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseA->GetObject (), 0); NS_TEST_ASSERT_EQUAL (baseA->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_EQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_EQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject (), 0); baseA = CreateObject (); baseB = CreateObject (); baseBCopy = baseB; baseA->AggregateObject (baseB); NS_TEST_ASSERT_UNEQUAL (baseA->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseA->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseB->GetObject (), 0) baseA = CreateObject (); baseB = CreateObject (); baseA->AggregateObject (baseB); baseA = 0; baseA = baseB->GetObject (); // Test the object creation code of TypeId Ptr a = BaseA::GetTypeId ().CreateObject (); NS_TEST_ASSERT_EQUAL (a->GetObject (), a); NS_TEST_ASSERT_EQUAL (a->GetObject (DerivedA::GetTypeId ()), 0); NS_TEST_ASSERT_EQUAL (a->GetObject (), 0); a = DerivedA::GetTypeId ().CreateObject (); NS_TEST_ASSERT_EQUAL (a->GetObject (), a); NS_TEST_ASSERT_EQUAL (a->GetObject (DerivedA::GetTypeId ()), a); NS_TEST_ASSERT_UNEQUAL (a->GetObject (), 0); return result; } static ObjectTest g_interfaceObjectTests; } // namespace ns3 #endif /* RUN_SELF_TESTS */