src/core/object-names.cc
changeset 4141 3f7f08d9daad
parent 4139 d45e62c78504
child 4145 bb930262e55c
--- a/src/core/object-names.cc	Tue Jan 20 17:39:18 2009 -0800
+++ b/src/core/object-names.cc	Tue Jan 20 18:29:06 2009 -0800
@@ -161,7 +161,55 @@
 bool
 NamesPriv::Add (std::string name, Ptr<Object> object)
 {
-  return Add (Ptr<Object> (0, false), name, object);
+  NS_LOG_FUNCTION (name << object);
+  //
+  // This is the simple, easy to use version of Add, so we want it to be flexible.
+  //
+  // If we are provided a name that doesn't begin with "/Names", we assume 
+  // that the caller has given us a shortname that she wants added to the root
+  // namespace.  This results in a call to the "real" Add with context set to 
+  // zero, indicating what we want to do.
+  //
+  // If we are given a name that begins with "/Names/" we assume that this is a
+  // fullname to the object we want to create.  We split the fullname into a 
+  // context string and and a final segment and then call the "Real" Add.
+  //
+  std::string namespaceName = "/Names";
+  std::string::size_type offset = name.find (namespaceName);
+  if (offset == 0)
+    {
+      //
+      // This must be a fully qualified longname.  All fully qualified names begin
+      // with "/Names".  We have to split off the final segment which will become
+      // the shortname of the object.
+      //
+      std::string::size_type i = name.rfind ("/");
+      NS_ASSERT_MSG (i != std::string::npos, "NamesPriv::Add(): Internal error.  Can't find '/' in name");
+
+      //
+      // The slash we found cannot be the slash at the start of the namespaceName.
+      // This would indicate there is no shortname in the path at all.
+      //
+      NS_ASSERT_MSG (i != 0, "NamesPriv::Add(): Can't find a shortname in the name string");
+
+      //
+      // We now know where the context string starts and ends, and where the
+      // shortname starts and ends.  All we have to do is to call our available
+      // function for creating addubg a shortname under a context string.
+      //
+      return Add (name.substr (0, i), name.substr (i + 1), object);
+    }
+  else
+    {
+      //
+      // This must be a shortname.  Shortnames can't have ANY '/' characters in
+      // them since they are interpreted as a final segment of a fullname.  A 
+      // shortname in this context means creating a name in the root namespace.
+      // We indicate this by passing a zero context to the "real" add.
+      //
+      NS_ASSERT_MSG (offset == std::string::npos, "NamesPriv::Add(): Unexpected '/' in shortname");
+      return Add (Ptr<Object> (0, false), name, object);
+    }
 }
 
 bool
@@ -204,7 +252,7 @@
 {
   if (context == "/Names")
     {
-      return Add (name, object);
+      return Add (Ptr<Object> (0, false), name, object);
     }
   return Add (FindObjectFromFullName (context), name, object);
 }
@@ -589,11 +637,11 @@
   NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
 
   //
-  // We also have some syntactical sugary methods, so make sure they do what
+  // We also have some syntactically sugary methods, so make sure they do what
   // they should as well.
   //
   Ptr<TestObject> bridge = CreateObject<TestObject> ();
-  result = Names::Add ("/Names", "Bridge", client);
+  result = Names::Add ("/Names", "Bridge", bridge);
   NS_TEST_ASSERT_EQUAL (result, true);
 
   Ptr<TestObject> bridgeEth0 = CreateObject<TestObject> ();
@@ -606,6 +654,20 @@
   foundObject = Names::Find<TestObject> ("/Names/Bridge/eth0");
   NS_TEST_ASSERT_EQUAL (foundObject, bridgeEth0);
 
+  Ptr<TestObject> wireless = CreateObject<TestObject> ();
+  result = Names::Add ("/Names/Wireless", wireless);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  Ptr<TestObject> wirelessAth0 = CreateObject<TestObject> ();
+  result = Names::Add ("/Names/Wireless/ath0", wirelessAth0);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  foundObject = Names::Find<TestObject> ("/Names/Wireless");
+  NS_TEST_ASSERT_EQUAL (foundObject, wireless);
+
+  foundObject = Names::Find<TestObject> ("/Names/Wireless/ath0");
+  NS_TEST_ASSERT_EQUAL (foundObject, wirelessAth0);
+
   //
   // Run the simulator and destroy it to get the Destroy method called on the
   // private implementation object.  We depend on seeing a valgrind-clean run of