rename object-names.{cc,h} to names.{cc,h} per convention
authorCraig Dowell <craigdo@ee.washington.edu>
Thu, 22 Jan 2009 23:07:34 -0800
changeset 4147 5d8530130930
parent 4146 805af0f9ddd9
child 4148 7f1a5bd869e5
rename object-names.{cc,h} to names.{cc,h} per convention
src/core/config.cc
src/core/names.cc
src/core/names.h
src/core/object-names.cc
src/core/object-names.h
src/core/wscript
src/helper/application-container.cc
src/helper/bridge-helper.cc
src/helper/csma-helper.cc
src/helper/emu-helper.cc
src/helper/internet-stack-helper.cc
src/helper/ipv4-interface-container.cc
src/helper/mobility-helper.cc
src/helper/net-device-container.cc
src/helper/node-container.cc
src/helper/olsr-helper.cc
src/helper/on-off-helper.cc
src/helper/packet-sink-helper.cc
src/helper/packet-socket-helper.cc
src/helper/point-to-point-helper.cc
src/helper/static-multicast-route-helper.cc
src/helper/udp-echo-helper.cc
src/helper/v4ping-helper.cc
src/helper/wifi-helper.cc
src/helper/yans-wifi-helper.cc
--- a/src/core/config.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/core/config.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -22,7 +22,7 @@
 #include "object.h"
 #include "global-value.h"
 #include "object-vector.h"
-#include "object-names.h"
+#include "names.h"
 #include "pointer.h"
 #include "log.h"
 #include <sstream>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/names.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -0,0 +1,695 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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
+ */
+
+#include <map>
+#include "object.h"
+#include "log.h"
+#include "assert.h"
+#include "abort.h"
+#include "names.h"
+#include "ns3/simulator.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("Names");
+
+class NameNode
+{
+public:
+  NameNode ();
+  NameNode (const NameNode &nameNode);
+  NameNode (NameNode *parent, std::string name, Ptr<Object> object);
+  NameNode &operator = (const NameNode &rhs);
+
+ ~NameNode ();
+
+  NameNode *m_parent;
+  std::string m_name;
+  Ptr<Object> m_object;
+
+  std::map<std::string, NameNode *> m_nameMap;
+};
+
+NameNode::NameNode ()
+  : m_parent (0), m_name (""), m_object (0)
+{
+}
+
+NameNode::NameNode (const NameNode &nameNode)
+{
+  m_parent = nameNode.m_parent;
+  m_name = nameNode.m_name;
+  m_object = nameNode.m_object;
+  m_nameMap = nameNode.m_nameMap;
+}
+
+NameNode &
+NameNode::operator = (const NameNode &rhs)
+{
+  m_parent = rhs.m_parent;
+  m_name = rhs.m_name;
+  m_object = rhs.m_object;
+  m_nameMap = rhs.m_nameMap;
+  return *this;
+}
+
+NameNode::NameNode (NameNode *parent, std::string name, Ptr<Object> object)
+  : m_parent (parent), m_name (name), m_object (object)
+{
+}
+
+NameNode::~NameNode ()
+{
+}
+
+class NamesPriv 
+{
+public:
+  NamesPriv ();
+  ~NamesPriv ();
+
+  bool Add (std::string name, Ptr<Object> obj);
+  bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
+  bool Add (std::string context, std::string name, Ptr<Object> object);
+  std::string FindShortName (Ptr<Object> object);
+  std::string FindFullName (Ptr<Object> object);
+  Ptr<Object> FindObjectFromFullName (std::string name);
+  Ptr<Object> FindObjectFromShortName (Ptr<Object> context, std::string name);
+
+  static NamesPriv *Get (void);
+  static void Delete (void);
+private:
+  static NamesPriv **DoGet (void);
+
+  NameNode *IsNamed (Ptr<Object>);
+  bool IsDuplicateName (NameNode *node, std::string name);
+
+  NameNode m_root;
+  std::map<Ptr<Object>, NameNode *> m_objectMap;
+};
+
+NamesPriv *
+NamesPriv::Get (void)
+{
+  return *(DoGet ());
+}
+
+NamesPriv **
+NamesPriv::DoGet (void)
+{
+  static NamesPriv *ptr = 0;
+
+  if (ptr == 0)
+    {
+      ptr = new NamesPriv;
+      Simulator::ScheduleDestroy (&NamesPriv::Delete);
+    }
+
+  return &ptr;
+}
+
+void 
+NamesPriv::Delete (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  NamesPriv **ptr = DoGet ();
+  delete *ptr;
+  *ptr = 0;
+}
+
+NamesPriv::NamesPriv ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_root.m_parent = 0;
+  m_root.m_name = "Names";
+  m_root.m_object = 0;
+}
+
+NamesPriv::~NamesPriv ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  //
+  // Every name is associated with an object in the object map, so freeing the
+  // NameNodes in this map will free all of the memory allocated for the NameNodes
+  //
+  for (std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.begin (); i != m_objectMap.end (); ++i)
+    {
+      delete i->second;
+      i->second = 0;
+    }
+
+  m_root.m_parent = 0;
+  m_root.m_name = "";
+  m_root.m_object = 0;
+}
+
+bool
+NamesPriv::Add (std::string name, Ptr<Object> 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
+NamesPriv::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
+{
+  NS_LOG_FUNCTION (context << name << object);
+
+  if (IsNamed (object))
+    {
+      NS_LOG_LOGIC ("Object is already named");
+      return false;
+    }
+
+  NameNode *node = 0;
+  if (context)
+    {
+      node = IsNamed (context);
+      NS_ASSERT_MSG (node, "NamesPriv::Name(): context must point to a previously named node");
+    }
+  else
+    {
+      node = &m_root;
+    }
+
+  if (IsDuplicateName (node, name))
+    {
+      NS_LOG_LOGIC ("Name is already taken");
+      return false;
+    }
+
+  NameNode *newNode = new NameNode(node, name, object);
+  node->m_nameMap[name] = newNode;
+  m_objectMap[object] = newNode;
+
+  return true;
+}
+
+bool
+NamesPriv::Add (std::string context, std::string name, Ptr<Object> object)
+{
+  if (context == "/Names")
+    {
+      return Add (Ptr<Object> (0, false), name, object);
+    }
+  return Add (FindObjectFromFullName (context), name, object);
+}
+
+std::string
+NamesPriv::FindShortName (Ptr<Object> object)
+{
+  NS_LOG_FUNCTION (object);
+
+  std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
+  if (i == m_objectMap.end ())
+    {
+      NS_LOG_LOGIC ("Object does not exist in object map");
+      return "";
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Object exists in object map");
+      return i->second->m_name;
+    }
+}
+
+std::string
+NamesPriv::FindFullName (Ptr<Object> object)
+{
+  NS_LOG_FUNCTION (object);
+
+  std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
+  if (i == m_objectMap.end ())
+    {
+      NS_LOG_LOGIC ("Object does not exist in object map");
+      return "";
+    }
+
+  NameNode *p = i->second;
+  NS_ASSERT_MSG (p, "NamesPriv::FindFullName(): Internal error: Invalid NameNode pointer from map");
+
+  std::string fullname;
+
+  do
+    {
+      fullname = "/" + p->m_name + fullname;
+      NS_LOG_LOGIC ("fullname is " << fullname);
+    }
+  while ((p = p->m_parent) != 0);
+
+  return fullname;
+}
+
+
+Ptr<Object>
+NamesPriv::FindObjectFromFullName (std::string name)
+{
+  std::string namespaceName = "/Names/";
+  std::string::size_type offset = name.find (namespaceName);
+  if (offset == std::string::npos)
+    {
+      NS_LOG_LOGIC (name << " is not in the " << namespaceName << " name space");
+      return 0;
+    }
+
+  std::string remaining = name.substr (namespaceName.size ());
+  NameNode *node = &m_root;
+
+  //
+  // remaining is now composed entirely of path segments in the /Names name space.
+  // and we have eaten the leading slash. e.g., remaining = "ClientNode/eth0"
+  // The start of the search is at the root of the name space.
+  //
+  for (;;)
+    {
+      NS_LOG_LOGIC ("Looking for the object of name " << remaining);
+      offset = remaining.find ("/");
+      if (offset == std::string::npos)
+        {
+          //
+          // There are no remaining slashes so this is the last segment of the 
+          // specified name.  We're done when we find it
+          //
+          std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (remaining);
+          if (i == node->m_nameMap.end ())
+            {
+              NS_LOG_LOGIC ("Name does not exist in name map");
+              return 0;
+            }
+          else
+            {
+              NS_LOG_LOGIC ("Name parsed, found object");
+              return i->second->m_object;
+            }
+        }
+      else
+        {
+          //
+          // There are more slashes so this is an intermediate segment of the 
+          // specified name.  We need to "recurse" when we find this segment.
+          //
+          offset = remaining.find ("/");
+          std::string segment = remaining.substr(0, offset);
+
+          std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (segment);
+          if (i == node->m_nameMap.end ())
+            {
+              NS_LOG_LOGIC ("Name does not exist in name map");
+              return 0;
+            }
+          else
+            {
+              node = i->second;
+              remaining = remaining.substr (offset + 1);
+              NS_LOG_LOGIC ("Intermediate segment parsed");
+              continue;
+            }
+        }
+    }
+
+  NS_ASSERT_MSG (node, "NamesPriv::FindObjectFromFullName(): Internal error:  this can't happen");
+  return 0;
+}
+
+Ptr<Object>
+NamesPriv::FindObjectFromShortName (Ptr<Object> context, std::string name)
+{
+  NS_LOG_FUNCTION (context << name);
+
+  NameNode *node = 0;
+
+  if (context == 0)
+    {
+      NS_LOG_LOGIC ("Zero context implies root NameNode");
+      node = &m_root;
+    }
+  else
+    {
+      node = IsNamed (context);
+      if (node == 0)
+        {
+          NS_LOG_LOGIC ("Context does not point to a previously named node");
+          return 0;
+        }
+    }
+
+  std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
+  if (i == node->m_nameMap.end ())
+    {
+      NS_LOG_LOGIC ("Name does not exist in name map");
+      return 0;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Name exists in name map");
+      return i->second->m_object;
+    }
+}
+
+NameNode *
+NamesPriv::IsNamed (Ptr<Object> object)
+{
+  NS_LOG_FUNCTION (object);
+
+  std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
+  if (i == m_objectMap.end ())
+    {
+      NS_LOG_LOGIC ("Object does not exist in object map, returning NameNode 0");
+      return 0;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Object exists in object map, returning NameNode " << &i->second);
+      return i->second;
+    }
+}
+
+bool
+NamesPriv::IsDuplicateName (NameNode *node, std::string name)
+{
+  NS_LOG_FUNCTION (node << name);
+
+  std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
+  if (i == node->m_nameMap.end ())
+    {
+      NS_LOG_LOGIC ("Name does not exist in name map");
+      return false;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Name exists in name map");
+      return true;
+    }
+}
+
+void
+Names::Delete (void)
+{
+  NamesPriv::Delete ();
+}
+
+bool
+Names::Add (std::string name, Ptr<Object> object)
+{
+  return NamesPriv::Get ()->Add (name, object);
+}
+
+bool
+Names::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
+{
+  return NamesPriv::Get ()->Add (context, name, object);
+}
+
+bool
+Names::Add (std::string context, std::string name, Ptr<Object> object)
+{
+  return NamesPriv::Get ()->Add (context, name, object);
+}
+
+std::string
+Names::FindShortName (Ptr<Object> object)
+{
+  return NamesPriv::Get ()->FindShortName (object);
+}
+
+std::string
+Names::FindFullName (Ptr<Object> object)
+{
+  return NamesPriv::Get ()->FindFullName (object);
+}
+
+Ptr<Object>
+Names::FindObjectFromFullNameInternal (std::string name)
+{
+  return NamesPriv::Get ()->FindObjectFromFullName (name);
+}
+
+Ptr<Object>
+Names::FindObjectFromShortNameInternal (Ptr<Object> context, std::string name)
+{
+  return NamesPriv::Get ()->FindObjectFromShortName (context, name);
+}
+
+} //namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+#include "object-factory.h"
+
+namespace ns3 {
+
+class TestObject : public Object
+{
+public:
+  static TypeId GetTypeId (void) 
+  {
+    static TypeId tid = TypeId ("TestObject")
+      .SetParent (Object::GetTypeId ())
+      .HideFromDocumentation ()
+      .AddConstructor<TestObject> ();
+    return tid;
+  }
+  TestObject () {}
+  virtual void Dispose (void) {}
+};
+
+class NamesTest : public Test
+{
+public:
+  NamesTest ();
+  virtual bool RunTests (void);
+};
+
+NamesTest::NamesTest ()
+  : Test ("Names")
+{
+}
+
+bool 
+NamesTest::RunTests (void)
+{
+  bool result = true;
+
+  // 
+  // Name a couple of objects at the root level
+  //
+  Ptr<TestObject> client = CreateObject<TestObject> ();
+  result = Names::Add ("Client", client);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  Ptr<TestObject> server = CreateObject<TestObject> ();
+  result = Names::Add ("Server", server);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  //
+  // We shouldn't be able to add another name to a previously named object
+  //
+  result = Names::Add ("Not Client", client);
+  NS_TEST_ASSERT_EQUAL (result, false);
+
+  //
+  // We shouldn't be able to duplicate a name at the root level.
+  //
+  Ptr<TestObject> secondClient = CreateObject<TestObject> ();
+  result = Names::Add ("Client", secondClient);
+  NS_TEST_ASSERT_EQUAL (result, false);
+
+  //
+  // We should be able to add a new name in the first object's context
+  //
+  Ptr<TestObject> clientEth0 = CreateObject<TestObject> ();
+  result = Names::Add (client, "eth0", clientEth0);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  //
+  // We shouldn't be able to duplicate a name in that context.
+  //
+  Ptr<TestObject> secondClientEth0 = CreateObject<TestObject> ();
+  result = Names::Add (client, "eth0", secondClientEth0);
+  NS_TEST_ASSERT_EQUAL (result, false);
+
+  //
+  // We should be able to add the same name in the second object's context
+  //
+  Ptr<TestObject> serverEth0 = CreateObject<TestObject> ();
+  result = Names::Add (server, "eth0", serverEth0);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  //
+  // We should be able to find the short names for the objects we created
+  //
+  std::string found;
+
+  found = Names::FindShortName (client);
+  NS_TEST_ASSERT_EQUAL (found, "Client");
+
+  found = Names::FindShortName (server);
+  NS_TEST_ASSERT_EQUAL (found, "Server");
+
+  found = Names::FindShortName (clientEth0);
+  NS_TEST_ASSERT_EQUAL (found, "eth0");
+
+  found = Names::FindShortName (serverEth0);
+  NS_TEST_ASSERT_EQUAL (found, "eth0");
+
+  //
+  // We should be able to find the full names for the objects we created
+  //
+  found = Names::FindFullName (client);
+  NS_TEST_ASSERT_EQUAL (found, "/Names/Client");
+
+  found = Names::FindFullName (server);
+  NS_TEST_ASSERT_EQUAL (found, "/Names/Server");
+
+  found = Names::FindFullName (clientEth0);
+  NS_TEST_ASSERT_EQUAL (found, "/Names/Client/eth0");
+
+  found = Names::FindFullName (serverEth0);
+  NS_TEST_ASSERT_EQUAL (found, "/Names/Server/eth0");
+
+  // 
+  // We should be able to find the objects from the short names
+  //
+  Ptr<TestObject> foundObject;
+
+  foundObject = Names::FindObjectFromShortName<TestObject> (0, "Client");
+  NS_TEST_ASSERT_EQUAL (foundObject, client);
+
+  foundObject = Names::FindObjectFromShortName<TestObject> (0, "Server");
+  NS_TEST_ASSERT_EQUAL (foundObject, server);
+
+  foundObject = Names::FindObjectFromShortName<TestObject> (client, "eth0");
+  NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
+
+  foundObject = Names::FindObjectFromShortName<TestObject> (server, "eth0");
+  NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
+
+  // 
+  // We should be able to find the objects from their full names
+  //
+  foundObject = Names::Find<TestObject> ("/Names/Client");
+  NS_TEST_ASSERT_EQUAL (foundObject, client);
+
+  foundObject = Names::Find<TestObject> ("/Names/Server");
+  NS_TEST_ASSERT_EQUAL (foundObject, server);
+
+  foundObject = Names::Find<TestObject> ("/Names/Client/eth0");
+  NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
+
+  foundObject = Names::Find<TestObject> ("/Names/Server/eth0");
+  NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
+
+  //
+  // 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", bridge);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  Ptr<TestObject> bridgeEth0 = CreateObject<TestObject> ();
+  result = Names::Add ("/Names/Bridge", "eth0", bridgeEth0);
+  NS_TEST_ASSERT_EQUAL (result, true);
+
+  foundObject = Names::Find<TestObject> ("/Names/Bridge");
+  NS_TEST_ASSERT_EQUAL (foundObject, bridge);
+
+  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
+  // the unit tests to really determine if the clean up was really successful.
+  //
+  Simulator::Run ();
+  Simulator::Destroy ();
+  
+  return true;
+}
+
+static NamesTest g_namesTests;
+
+} // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/names.h	Thu Jan 22 23:07:34 2009 -0800
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * 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
+ */
+
+#ifndef OBJECT_NAMES_H
+#define OBJECT_NAMES_H
+
+#include "ns3/ptr.h"
+#include "ns3/object.h"
+
+namespace ns3 {
+
+/**
+ * \brief A directory of name and Ptr<Object> associations that allows us to
+ * give any ns3 Object a name.
+ */
+class Names
+{
+public:
+
+  /**
+   * Add the association between the string "name" and the Ptr<Object> obj
+   * at the root of the "/Names" name space.  This can be seen as equivalent
+   * to adding a Pointer Attribute called "name" to the to the root name 
+   * space object and then assigning the value obj to that attribute.  The 
+   * config facility will see it that way.
+   *
+   * \param name The name of the object you want to associate.
+   * \param obj A smart pointer to the object itself.
+   */
+  static bool Add (std::string name, Ptr<Object> obj);
+
+  /**
+   * Add the association between the string "name" and the Ptr<Object> obj
+   * in the object context given by the Ptr<Object> context.  This can be
+   * seen as equivalent to adding a Pointer Attribute called "name" to the 
+   * object given by "context" and then assigning the value obj to that
+   * attribute.  The config facility will see it that way.
+   *
+   * \param context A spart pointer to an object under which you want this
+   *                name to be defined.
+   * \param name The name of the object you want to associate.
+   * \param obj A smart pointer to the object itself.
+   *
+   * \returns true if the association was successfully completed, false otherwise
+   */
+  static bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
+
+  /**
+   * Syntactic sugar around the Object context Name method.  Allows you to 
+   * specify the context with a string instead of the pointer.  If the first
+   * parameter (context) is "/Names" this turns into a call into Name at the
+   * root of the name space.  Otherwise it does a FindObjectFromFullNameInternal
+   * on the context and adds the name to a subspace.
+   *
+   * \param context A fully qualified name describing a previously named object.
+   *                under which you want this name to be defined.
+   * \param name The name of the object you want to associate.
+   * \param obj A smart pointer to the object itself.
+   *
+   * \returns true if the association was successfully completed, false otherwise
+   */
+  static bool Add (std::string context, std::string name, Ptr<Object> object);
+
+  /**
+   * Given a pointer to an object, look to see if that object has a name
+   * associated with it and return the shortname for the object.
+   *
+   * The fullname of an object is a fully qualified namespace name, for example
+   * if you have a device that you have previously named "eth0" under a node
+   * you have named "client", the fullname of the device will then be
+   * "/Names/client/eth0".
+   *
+   * The shortname of an object is the name of the object in its parent name
+   * space.  Using the example above, asking for the shortname of the device
+   * will result in "eth0" being returned.
+   *
+   * \param object A spart pointer to an object for which you want to find
+   *               its shortname.
+   *
+   * \returns a string containing the shortname of the object.
+   */
+  static std::string FindShortName (Ptr<Object> object);
+
+  /**
+   * Given a pointer to an object, look to see if that object has a name
+   * associated with it and return the fully qualified namespace name
+   * for the object.
+   *
+   * The fullname of an object is a fully qualified namespace name, for example
+   * if you have a device that you have previously named "eth0" under a node
+   * you have named "client", the fullname of the device will then be
+   * "/Names/client/eth0".
+   *
+   * The shortname of an object is the name of the object in its parent name
+   * space.  Using the example above, asking for the shortname of the device
+   * will result in "eth0" being returned.
+   *
+   * \param object A spart pointer to an object for which you want to find
+   *               its fullname.
+   *
+   * \returns a string containing the fullname of the object.
+   */
+  static std::string FindFullName (Ptr<Object> object);
+
+  /**
+   * Given a fullname string, look to see if there's an object in the system
+   * with a that associated with it.  If there is, do a QueryObject on the 
+   * resulting object to convert it to the requested typename.  
+   * 
+   * The fullname of an object is a fully qualified namespace name, for example
+   * if you have a device that you have previously named "eth0" under a node
+   * you have named "client", the fullname of the device will then be
+   * "/Names/client/eth0".
+   *
+   * \param name A string containing a fully qualified name space name 
+   *             used to locate the object.
+   *
+   * \returns a smart pointer to the named object converted to the requested
+   *          type.
+   */
+  template <typename T>
+  static Ptr<T> FindObjectFromFullName (std::string name);
+
+  /**
+   * Given a fullname string, look to see if there's an object in the system
+   * with a that associated with it.  If there is, do a QueryObject on the 
+   * resulting object to convert it to the requested typename.  
+   * 
+   * The fullname of an object is a fully qualified namespace name, for example
+   * if you have a device that you have previously named "eth0" under a node
+   * you have named "client", the fullname of the device will then be
+   * "/Names/client/eth0".
+   *
+   * \param name A string containing a fully qualified name space name 
+   *             used to locate the object.
+   *
+   *
+   * \returns a smart pointer to the named object converted to the requested
+   *          type.
+   *
+   * @comment This method is identical to FindObjectFromFullName, but has a
+   * short signature since it is a common use and we want it to be easy to 
+   * type.
+   */
+  template <typename T>
+  static Ptr<T> Find (std::string name);
+
+  /**
+   * Given an object context and a shortname string, look through the names 
+   * associated with the namespace defined by the context object to see if 
+   * there's an object there with the given shortname.
+   *
+   * The fullname of an object is a fully qualified namespace name, for example
+   * if you have a device that you have previously named "eth0" under a node
+   * you have named "client", the fullname of the device will then be
+   * "/Names/client/eth0".
+   *
+   * The shortname of an object is the name of the object in its parent name
+   * space.  Using the example above, asking for the shortname of the device
+   * will result in "eth0" being returned.
+   *
+   * The context object provides a namespace context, in the case of the example
+   * it would be the "client" object under which we look for the short name.
+   * In the example above, the context pointer would be the Ptr<Object> to the 
+   * client node, and the name would be the shortname "eth0"  
+   *
+   * \param context A spart pointer to an object under which you want to look 
+   *                for the provided name.
+   * \param name A string containing a shortname to look for.
+   *
+   * \returns a smart pointer to the named object converted to the requested
+   *          type.
+   */
+  template <typename T>
+  static Ptr<T> FindObjectFromShortName (Ptr<Object> context, std::string name);
+
+  /**
+   * Clean up all of the data structures of the implementation and delete the
+   * underlying singleton.  Used to get valgrind-clean runs if the simulator
+   * is not run.  Normally singleton cleanup is scheduled on Simulator::Destroy.
+   */
+  static void Delete (void);
+
+private:
+  /**
+   * \internal
+   *
+   * \brief Non-templated internal version of FindObjectFromLongName
+   *
+   * \param name A string containing a longname to look for.
+   *
+   * \returns a smart pointer to the named object.
+   */
+  static Ptr<Object> FindObjectFromFullNameInternal (std::string name);
+
+  /**
+   * \internal
+   *
+   * \brief Non-templated internal version of FindObjectFromShortName
+   *
+   * \param context A spart pointer to an object under which you want to look 
+   *                for the provided name.
+   * \param name A string containing a shortname to look for.
+   *
+   * \returns a smart pointer to the named object.
+   */
+  static Ptr<Object> FindObjectFromShortNameInternal (Ptr<Object> context, std::string name);
+};
+
+/**
+ * \brief Template definition of corresponding template declaration found in class Names.
+ */
+template <typename T>
+Ptr<T> 
+Names::Find (std::string name)
+{
+  return FindObjectFromFullName<T> (name);
+}
+
+/**
+ * \brief Template definition of corresponding template declaration found in class Names.
+ */
+template <typename T>
+Ptr<T> 
+Names::FindObjectFromFullName (std::string name)
+{
+  Ptr<Object> obj = FindObjectFromFullNameInternal (name);
+  if (obj)
+    {
+      return obj->GetObject<T> ();
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/**
+ * \brief Template definition of corresponding template declaration found in class Names.
+ */
+template <typename T>
+Ptr<T> 
+Names::FindObjectFromShortName (Ptr<Object> context, std::string name)
+{
+  Ptr<Object> obj = FindObjectFromShortNameInternal (context, name);
+  if (obj)
+    {
+      return obj->GetObject<T> ();
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+}//namespace ns3
+
+#endif /* OBJECT_NAMES_H */
--- a/src/core/object-names.cc	Wed Jan 21 00:28:47 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,695 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * 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
- */
-
-#include <map>
-#include "object.h"
-#include "log.h"
-#include "assert.h"
-#include "abort.h"
-#include "object-names.h"
-#include "ns3/simulator.h"
-
-namespace ns3 {
-
-NS_LOG_COMPONENT_DEFINE ("Names");
-
-class NameNode
-{
-public:
-  NameNode ();
-  NameNode (const NameNode &nameNode);
-  NameNode (NameNode *parent, std::string name, Ptr<Object> object);
-  NameNode &operator = (const NameNode &rhs);
-
- ~NameNode ();
-
-  NameNode *m_parent;
-  std::string m_name;
-  Ptr<Object> m_object;
-
-  std::map<std::string, NameNode *> m_nameMap;
-};
-
-NameNode::NameNode ()
-  : m_parent (0), m_name (""), m_object (0)
-{
-}
-
-NameNode::NameNode (const NameNode &nameNode)
-{
-  m_parent = nameNode.m_parent;
-  m_name = nameNode.m_name;
-  m_object = nameNode.m_object;
-  m_nameMap = nameNode.m_nameMap;
-}
-
-NameNode &
-NameNode::operator = (const NameNode &rhs)
-{
-  m_parent = rhs.m_parent;
-  m_name = rhs.m_name;
-  m_object = rhs.m_object;
-  m_nameMap = rhs.m_nameMap;
-  return *this;
-}
-
-NameNode::NameNode (NameNode *parent, std::string name, Ptr<Object> object)
-  : m_parent (parent), m_name (name), m_object (object)
-{
-}
-
-NameNode::~NameNode ()
-{
-}
-
-class NamesPriv 
-{
-public:
-  NamesPriv ();
-  ~NamesPriv ();
-
-  bool Add (std::string name, Ptr<Object> obj);
-  bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
-  bool Add (std::string context, std::string name, Ptr<Object> object);
-  std::string FindShortName (Ptr<Object> object);
-  std::string FindFullName (Ptr<Object> object);
-  Ptr<Object> FindObjectFromFullName (std::string name);
-  Ptr<Object> FindObjectFromShortName (Ptr<Object> context, std::string name);
-
-  static NamesPriv *Get (void);
-  static void Delete (void);
-private:
-  static NamesPriv **DoGet (void);
-
-  NameNode *IsNamed (Ptr<Object>);
-  bool IsDuplicateName (NameNode *node, std::string name);
-
-  NameNode m_root;
-  std::map<Ptr<Object>, NameNode *> m_objectMap;
-};
-
-NamesPriv *
-NamesPriv::Get (void)
-{
-  return *(DoGet ());
-}
-
-NamesPriv **
-NamesPriv::DoGet (void)
-{
-  static NamesPriv *ptr = 0;
-
-  if (ptr == 0)
-    {
-      ptr = new NamesPriv;
-      Simulator::ScheduleDestroy (&NamesPriv::Delete);
-    }
-
-  return &ptr;
-}
-
-void 
-NamesPriv::Delete (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  NamesPriv **ptr = DoGet ();
-  delete *ptr;
-  *ptr = 0;
-}
-
-NamesPriv::NamesPriv ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  m_root.m_parent = 0;
-  m_root.m_name = "Names";
-  m_root.m_object = 0;
-}
-
-NamesPriv::~NamesPriv ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  //
-  // Every name is associated with an object in the object map, so freeing the
-  // NameNodes in this map will free all of the memory allocated for the NameNodes
-  //
-  for (std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.begin (); i != m_objectMap.end (); ++i)
-    {
-      delete i->second;
-      i->second = 0;
-    }
-
-  m_root.m_parent = 0;
-  m_root.m_name = "";
-  m_root.m_object = 0;
-}
-
-bool
-NamesPriv::Add (std::string name, Ptr<Object> 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
-NamesPriv::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
-{
-  NS_LOG_FUNCTION (context << name << object);
-
-  if (IsNamed (object))
-    {
-      NS_LOG_LOGIC ("Object is already named");
-      return false;
-    }
-
-  NameNode *node = 0;
-  if (context)
-    {
-      node = IsNamed (context);
-      NS_ASSERT_MSG (node, "NamesPriv::Name(): context must point to a previously named node");
-    }
-  else
-    {
-      node = &m_root;
-    }
-
-  if (IsDuplicateName (node, name))
-    {
-      NS_LOG_LOGIC ("Name is already taken");
-      return false;
-    }
-
-  NameNode *newNode = new NameNode(node, name, object);
-  node->m_nameMap[name] = newNode;
-  m_objectMap[object] = newNode;
-
-  return true;
-}
-
-bool
-NamesPriv::Add (std::string context, std::string name, Ptr<Object> object)
-{
-  if (context == "/Names")
-    {
-      return Add (Ptr<Object> (0, false), name, object);
-    }
-  return Add (FindObjectFromFullName (context), name, object);
-}
-
-std::string
-NamesPriv::FindShortName (Ptr<Object> object)
-{
-  NS_LOG_FUNCTION (object);
-
-  std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
-  if (i == m_objectMap.end ())
-    {
-      NS_LOG_LOGIC ("Object does not exist in object map");
-      return "";
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Object exists in object map");
-      return i->second->m_name;
-    }
-}
-
-std::string
-NamesPriv::FindFullName (Ptr<Object> object)
-{
-  NS_LOG_FUNCTION (object);
-
-  std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
-  if (i == m_objectMap.end ())
-    {
-      NS_LOG_LOGIC ("Object does not exist in object map");
-      return "";
-    }
-
-  NameNode *p = i->second;
-  NS_ASSERT_MSG (p, "NamesPriv::FindFullName(): Internal error: Invalid NameNode pointer from map");
-
-  std::string fullname;
-
-  do
-    {
-      fullname = "/" + p->m_name + fullname;
-      NS_LOG_LOGIC ("fullname is " << fullname);
-    }
-  while ((p = p->m_parent) != 0);
-
-  return fullname;
-}
-
-
-Ptr<Object>
-NamesPriv::FindObjectFromFullName (std::string name)
-{
-  std::string namespaceName = "/Names/";
-  std::string::size_type offset = name.find (namespaceName);
-  if (offset == std::string::npos)
-    {
-      NS_LOG_LOGIC (name << " is not in the " << namespaceName << " name space");
-      return 0;
-    }
-
-  std::string remaining = name.substr (namespaceName.size ());
-  NameNode *node = &m_root;
-
-  //
-  // remaining is now composed entirely of path segments in the /Names name space.
-  // and we have eaten the leading slash. e.g., remaining = "ClientNode/eth0"
-  // The start of the search is at the root of the name space.
-  //
-  for (;;)
-    {
-      NS_LOG_LOGIC ("Looking for the object of name " << remaining);
-      offset = remaining.find ("/");
-      if (offset == std::string::npos)
-        {
-          //
-          // There are no remaining slashes so this is the last segment of the 
-          // specified name.  We're done when we find it
-          //
-          std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (remaining);
-          if (i == node->m_nameMap.end ())
-            {
-              NS_LOG_LOGIC ("Name does not exist in name map");
-              return 0;
-            }
-          else
-            {
-              NS_LOG_LOGIC ("Name parsed, found object");
-              return i->second->m_object;
-            }
-        }
-      else
-        {
-          //
-          // There are more slashes so this is an intermediate segment of the 
-          // specified name.  We need to "recurse" when we find this segment.
-          //
-          offset = remaining.find ("/");
-          std::string segment = remaining.substr(0, offset);
-
-          std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (segment);
-          if (i == node->m_nameMap.end ())
-            {
-              NS_LOG_LOGIC ("Name does not exist in name map");
-              return 0;
-            }
-          else
-            {
-              node = i->second;
-              remaining = remaining.substr (offset + 1);
-              NS_LOG_LOGIC ("Intermediate segment parsed");
-              continue;
-            }
-        }
-    }
-
-  NS_ASSERT_MSG (node, "NamesPriv::FindObjectFromFullName(): Internal error:  this can't happen");
-  return 0;
-}
-
-Ptr<Object>
-NamesPriv::FindObjectFromShortName (Ptr<Object> context, std::string name)
-{
-  NS_LOG_FUNCTION (context << name);
-
-  NameNode *node = 0;
-
-  if (context == 0)
-    {
-      NS_LOG_LOGIC ("Zero context implies root NameNode");
-      node = &m_root;
-    }
-  else
-    {
-      node = IsNamed (context);
-      if (node == 0)
-        {
-          NS_LOG_LOGIC ("Context does not point to a previously named node");
-          return 0;
-        }
-    }
-
-  std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
-  if (i == node->m_nameMap.end ())
-    {
-      NS_LOG_LOGIC ("Name does not exist in name map");
-      return 0;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Name exists in name map");
-      return i->second->m_object;
-    }
-}
-
-NameNode *
-NamesPriv::IsNamed (Ptr<Object> object)
-{
-  NS_LOG_FUNCTION (object);
-
-  std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
-  if (i == m_objectMap.end ())
-    {
-      NS_LOG_LOGIC ("Object does not exist in object map, returning NameNode 0");
-      return 0;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Object exists in object map, returning NameNode " << &i->second);
-      return i->second;
-    }
-}
-
-bool
-NamesPriv::IsDuplicateName (NameNode *node, std::string name)
-{
-  NS_LOG_FUNCTION (node << name);
-
-  std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
-  if (i == node->m_nameMap.end ())
-    {
-      NS_LOG_LOGIC ("Name does not exist in name map");
-      return false;
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Name exists in name map");
-      return true;
-    }
-}
-
-void
-Names::Delete (void)
-{
-  NamesPriv::Delete ();
-}
-
-bool
-Names::Add (std::string name, Ptr<Object> object)
-{
-  return NamesPriv::Get ()->Add (name, object);
-}
-
-bool
-Names::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
-{
-  return NamesPriv::Get ()->Add (context, name, object);
-}
-
-bool
-Names::Add (std::string context, std::string name, Ptr<Object> object)
-{
-  return NamesPriv::Get ()->Add (context, name, object);
-}
-
-std::string
-Names::FindShortName (Ptr<Object> object)
-{
-  return NamesPriv::Get ()->FindShortName (object);
-}
-
-std::string
-Names::FindFullName (Ptr<Object> object)
-{
-  return NamesPriv::Get ()->FindFullName (object);
-}
-
-Ptr<Object>
-Names::FindObjectFromFullNameInternal (std::string name)
-{
-  return NamesPriv::Get ()->FindObjectFromFullName (name);
-}
-
-Ptr<Object>
-Names::FindObjectFromShortNameInternal (Ptr<Object> context, std::string name)
-{
-  return NamesPriv::Get ()->FindObjectFromShortName (context, name);
-}
-
-} //namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "test.h"
-#include "object-factory.h"
-
-namespace ns3 {
-
-class TestObject : public Object
-{
-public:
-  static TypeId GetTypeId (void) 
-  {
-    static TypeId tid = TypeId ("TestObject")
-      .SetParent (Object::GetTypeId ())
-      .HideFromDocumentation ()
-      .AddConstructor<TestObject> ();
-    return tid;
-  }
-  TestObject () {}
-  virtual void Dispose (void) {}
-};
-
-class NamesTest : public Test
-{
-public:
-  NamesTest ();
-  virtual bool RunTests (void);
-};
-
-NamesTest::NamesTest ()
-  : Test ("Names")
-{
-}
-
-bool 
-NamesTest::RunTests (void)
-{
-  bool result = true;
-
-  // 
-  // Name a couple of objects at the root level
-  //
-  Ptr<TestObject> client = CreateObject<TestObject> ();
-  result = Names::Add ("Client", client);
-  NS_TEST_ASSERT_EQUAL (result, true);
-
-  Ptr<TestObject> server = CreateObject<TestObject> ();
-  result = Names::Add ("Server", server);
-  NS_TEST_ASSERT_EQUAL (result, true);
-
-  //
-  // We shouldn't be able to add another name to a previously named object
-  //
-  result = Names::Add ("Not Client", client);
-  NS_TEST_ASSERT_EQUAL (result, false);
-
-  //
-  // We shouldn't be able to duplicate a name at the root level.
-  //
-  Ptr<TestObject> secondClient = CreateObject<TestObject> ();
-  result = Names::Add ("Client", secondClient);
-  NS_TEST_ASSERT_EQUAL (result, false);
-
-  //
-  // We should be able to add a new name in the first object's context
-  //
-  Ptr<TestObject> clientEth0 = CreateObject<TestObject> ();
-  result = Names::Add (client, "eth0", clientEth0);
-  NS_TEST_ASSERT_EQUAL (result, true);
-
-  //
-  // We shouldn't be able to duplicate a name in that context.
-  //
-  Ptr<TestObject> secondClientEth0 = CreateObject<TestObject> ();
-  result = Names::Add (client, "eth0", secondClientEth0);
-  NS_TEST_ASSERT_EQUAL (result, false);
-
-  //
-  // We should be able to add the same name in the second object's context
-  //
-  Ptr<TestObject> serverEth0 = CreateObject<TestObject> ();
-  result = Names::Add (server, "eth0", serverEth0);
-  NS_TEST_ASSERT_EQUAL (result, true);
-
-  //
-  // We should be able to find the short names for the objects we created
-  //
-  std::string found;
-
-  found = Names::FindShortName (client);
-  NS_TEST_ASSERT_EQUAL (found, "Client");
-
-  found = Names::FindShortName (server);
-  NS_TEST_ASSERT_EQUAL (found, "Server");
-
-  found = Names::FindShortName (clientEth0);
-  NS_TEST_ASSERT_EQUAL (found, "eth0");
-
-  found = Names::FindShortName (serverEth0);
-  NS_TEST_ASSERT_EQUAL (found, "eth0");
-
-  //
-  // We should be able to find the full names for the objects we created
-  //
-  found = Names::FindFullName (client);
-  NS_TEST_ASSERT_EQUAL (found, "/Names/Client");
-
-  found = Names::FindFullName (server);
-  NS_TEST_ASSERT_EQUAL (found, "/Names/Server");
-
-  found = Names::FindFullName (clientEth0);
-  NS_TEST_ASSERT_EQUAL (found, "/Names/Client/eth0");
-
-  found = Names::FindFullName (serverEth0);
-  NS_TEST_ASSERT_EQUAL (found, "/Names/Server/eth0");
-
-  // 
-  // We should be able to find the objects from the short names
-  //
-  Ptr<TestObject> foundObject;
-
-  foundObject = Names::FindObjectFromShortName<TestObject> (0, "Client");
-  NS_TEST_ASSERT_EQUAL (foundObject, client);
-
-  foundObject = Names::FindObjectFromShortName<TestObject> (0, "Server");
-  NS_TEST_ASSERT_EQUAL (foundObject, server);
-
-  foundObject = Names::FindObjectFromShortName<TestObject> (client, "eth0");
-  NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
-
-  foundObject = Names::FindObjectFromShortName<TestObject> (server, "eth0");
-  NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
-
-  // 
-  // We should be able to find the objects from their full names
-  //
-  foundObject = Names::Find<TestObject> ("/Names/Client");
-  NS_TEST_ASSERT_EQUAL (foundObject, client);
-
-  foundObject = Names::Find<TestObject> ("/Names/Server");
-  NS_TEST_ASSERT_EQUAL (foundObject, server);
-
-  foundObject = Names::Find<TestObject> ("/Names/Client/eth0");
-  NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
-
-  foundObject = Names::Find<TestObject> ("/Names/Server/eth0");
-  NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
-
-  //
-  // 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", bridge);
-  NS_TEST_ASSERT_EQUAL (result, true);
-
-  Ptr<TestObject> bridgeEth0 = CreateObject<TestObject> ();
-  result = Names::Add ("/Names/Bridge", "eth0", bridgeEth0);
-  NS_TEST_ASSERT_EQUAL (result, true);
-
-  foundObject = Names::Find<TestObject> ("/Names/Bridge");
-  NS_TEST_ASSERT_EQUAL (foundObject, bridge);
-
-  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
-  // the unit tests to really determine if the clean up was really successful.
-  //
-  Simulator::Run ();
-  Simulator::Destroy ();
-  
-  return true;
-}
-
-static NamesTest g_namesTests;
-
-} // namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/core/object-names.h	Wed Jan 21 00:28:47 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2009 University of Washington
- *
- * 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
- */
-
-#ifndef OBJECT_NAMES_H
-#define OBJECT_NAMES_H
-
-#include "ns3/ptr.h"
-#include "ns3/object.h"
-
-namespace ns3 {
-
-/**
- * \brief A directory of name and Ptr<Object> associations that allows us to
- * give any ns3 Object a name.
- */
-class Names
-{
-public:
-
-  /**
-   * Add the association between the string "name" and the Ptr<Object> obj
-   * at the root of the "/Names" name space.  This can be seen as equivalent
-   * to adding a Pointer Attribute called "name" to the to the root name 
-   * space object and then assigning the value obj to that attribute.  The 
-   * config facility will see it that way.
-   *
-   * \param name The name of the object you want to associate.
-   * \param obj A smart pointer to the object itself.
-   */
-  static bool Add (std::string name, Ptr<Object> obj);
-
-  /**
-   * Add the association between the string "name" and the Ptr<Object> obj
-   * in the object context given by the Ptr<Object> context.  This can be
-   * seen as equivalent to adding a Pointer Attribute called "name" to the 
-   * object given by "context" and then assigning the value obj to that
-   * attribute.  The config facility will see it that way.
-   *
-   * \param context A spart pointer to an object under which you want this
-   *                name to be defined.
-   * \param name The name of the object you want to associate.
-   * \param obj A smart pointer to the object itself.
-   *
-   * \returns true if the association was successfully completed, false otherwise
-   */
-  static bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
-
-  /**
-   * Syntactic sugar around the Object context Name method.  Allows you to 
-   * specify the context with a string instead of the pointer.  If the first
-   * parameter (context) is "/Names" this turns into a call into Name at the
-   * root of the name space.  Otherwise it does a FindObjectFromFullNameInternal
-   * on the context and adds the name to a subspace.
-   *
-   * \param context A fully qualified name describing a previously named object.
-   *                under which you want this name to be defined.
-   * \param name The name of the object you want to associate.
-   * \param obj A smart pointer to the object itself.
-   *
-   * \returns true if the association was successfully completed, false otherwise
-   */
-  static bool Add (std::string context, std::string name, Ptr<Object> object);
-
-  /**
-   * Given a pointer to an object, look to see if that object has a name
-   * associated with it and return the shortname for the object.
-   *
-   * The fullname of an object is a fully qualified namespace name, for example
-   * if you have a device that you have previously named "eth0" under a node
-   * you have named "client", the fullname of the device will then be
-   * "/Names/client/eth0".
-   *
-   * The shortname of an object is the name of the object in its parent name
-   * space.  Using the example above, asking for the shortname of the device
-   * will result in "eth0" being returned.
-   *
-   * \param object A spart pointer to an object for which you want to find
-   *               its shortname.
-   *
-   * \returns a string containing the shortname of the object.
-   */
-  static std::string FindShortName (Ptr<Object> object);
-
-  /**
-   * Given a pointer to an object, look to see if that object has a name
-   * associated with it and return the fully qualified namespace name
-   * for the object.
-   *
-   * The fullname of an object is a fully qualified namespace name, for example
-   * if you have a device that you have previously named "eth0" under a node
-   * you have named "client", the fullname of the device will then be
-   * "/Names/client/eth0".
-   *
-   * The shortname of an object is the name of the object in its parent name
-   * space.  Using the example above, asking for the shortname of the device
-   * will result in "eth0" being returned.
-   *
-   * \param object A spart pointer to an object for which you want to find
-   *               its fullname.
-   *
-   * \returns a string containing the fullname of the object.
-   */
-  static std::string FindFullName (Ptr<Object> object);
-
-  /**
-   * Given a fullname string, look to see if there's an object in the system
-   * with a that associated with it.  If there is, do a QueryObject on the 
-   * resulting object to convert it to the requested typename.  
-   * 
-   * The fullname of an object is a fully qualified namespace name, for example
-   * if you have a device that you have previously named "eth0" under a node
-   * you have named "client", the fullname of the device will then be
-   * "/Names/client/eth0".
-   *
-   * \param name A string containing a fully qualified name space name 
-   *             used to locate the object.
-   *
-   * \returns a smart pointer to the named object converted to the requested
-   *          type.
-   */
-  template <typename T>
-  static Ptr<T> FindObjectFromFullName (std::string name);
-
-  /**
-   * Given a fullname string, look to see if there's an object in the system
-   * with a that associated with it.  If there is, do a QueryObject on the 
-   * resulting object to convert it to the requested typename.  
-   * 
-   * The fullname of an object is a fully qualified namespace name, for example
-   * if you have a device that you have previously named "eth0" under a node
-   * you have named "client", the fullname of the device will then be
-   * "/Names/client/eth0".
-   *
-   * \param name A string containing a fully qualified name space name 
-   *             used to locate the object.
-   *
-   *
-   * \returns a smart pointer to the named object converted to the requested
-   *          type.
-   *
-   * @comment This method is identical to FindObjectFromFullName, but has a
-   * short signature since it is a common use and we want it to be easy to 
-   * type.
-   */
-  template <typename T>
-  static Ptr<T> Find (std::string name);
-
-  /**
-   * Given an object context and a shortname string, look through the names 
-   * associated with the namespace defined by the context object to see if 
-   * there's an object there with the given shortname.
-   *
-   * The fullname of an object is a fully qualified namespace name, for example
-   * if you have a device that you have previously named "eth0" under a node
-   * you have named "client", the fullname of the device will then be
-   * "/Names/client/eth0".
-   *
-   * The shortname of an object is the name of the object in its parent name
-   * space.  Using the example above, asking for the shortname of the device
-   * will result in "eth0" being returned.
-   *
-   * The context object provides a namespace context, in the case of the example
-   * it would be the "client" object under which we look for the short name.
-   * In the example above, the context pointer would be the Ptr<Object> to the 
-   * client node, and the name would be the shortname "eth0"  
-   *
-   * \param context A spart pointer to an object under which you want to look 
-   *                for the provided name.
-   * \param name A string containing a shortname to look for.
-   *
-   * \returns a smart pointer to the named object converted to the requested
-   *          type.
-   */
-  template <typename T>
-  static Ptr<T> FindObjectFromShortName (Ptr<Object> context, std::string name);
-
-  /**
-   * Clean up all of the data structures of the implementation and delete the
-   * underlying singleton.  Used to get valgrind-clean runs if the simulator
-   * is not run.  Normally singleton cleanup is scheduled on Simulator::Destroy.
-   */
-  static void Delete (void);
-
-private:
-  /**
-   * \internal
-   *
-   * \brief Non-templated internal version of FindObjectFromLongName
-   *
-   * \param name A string containing a longname to look for.
-   *
-   * \returns a smart pointer to the named object.
-   */
-  static Ptr<Object> FindObjectFromFullNameInternal (std::string name);
-
-  /**
-   * \internal
-   *
-   * \brief Non-templated internal version of FindObjectFromShortName
-   *
-   * \param context A spart pointer to an object under which you want to look 
-   *                for the provided name.
-   * \param name A string containing a shortname to look for.
-   *
-   * \returns a smart pointer to the named object.
-   */
-  static Ptr<Object> FindObjectFromShortNameInternal (Ptr<Object> context, std::string name);
-};
-
-/**
- * \brief Template definition of corresponding template declaration found in class Names.
- */
-template <typename T>
-Ptr<T> 
-Names::Find (std::string name)
-{
-  return FindObjectFromFullName<T> (name);
-}
-
-/**
- * \brief Template definition of corresponding template declaration found in class Names.
- */
-template <typename T>
-Ptr<T> 
-Names::FindObjectFromFullName (std::string name)
-{
-  Ptr<Object> obj = FindObjectFromFullNameInternal (name);
-  if (obj)
-    {
-      return obj->GetObject<T> ();
-    }
-  else
-    {
-      return 0;
-    }
-}
-
-/**
- * \brief Template definition of corresponding template declaration found in class Names.
- */
-template <typename T>
-Ptr<T> 
-Names::FindObjectFromShortName (Ptr<Object> context, std::string name)
-{
-  Ptr<Object> obj = FindObjectFromShortNameInternal (context, name);
-  if (obj)
-    {
-      return obj->GetObject<T> ();
-    }
-  else
-    {
-      return 0;
-    }
-}
-
-}//namespace ns3
-
-#endif /* OBJECT_NAMES_H */
--- a/src/core/wscript	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/core/wscript	Thu Jan 22 23:07:34 2009 -0800
@@ -53,7 +53,7 @@
         'trace-source-accessor.cc',
         'config.cc',
         'callback.cc',
-        'object-names.cc',
+        'names.cc',
         ]
     core.uselib = 'RT'
 
@@ -99,7 +99,7 @@
         'object-vector.h',
         'deprecated.h',
         'abort.h',
-        'object-names.h',
+        'names.h',
         ]
 
     if sys.platform == 'win32':
--- a/src/helper/application-container.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/application-container.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -18,7 +18,7 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 #include "application-container.h"
 
 namespace ns3 {
--- a/src/helper/bridge-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/bridge-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -20,7 +20,7 @@
 #include "ns3/log.h"
 #include "ns3/bridge-net-device.h"
 #include "ns3/node.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 NS_LOG_COMPONENT_DEFINE ("BridgeHelper");
 
--- a/src/helper/csma-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/csma-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -26,7 +26,7 @@
 #include "ns3/pcap-writer.h"
 #include "ns3/config.h"
 #include "ns3/packet.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 #include <string>
 
 namespace ns3 {
--- a/src/helper/emu-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/emu-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -21,7 +21,7 @@
 #include "ns3/log.h"
 #include "ns3/simulator.h"
 #include "ns3/object-factory.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 #include "ns3/queue.h"
 #include "ns3/emu-net-device.h"
 #include "ns3/pcap-writer.h"
--- a/src/helper/internet-stack-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/internet-stack-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -21,7 +21,7 @@
 #include "ns3/assert.h"
 #include "ns3/log.h"
 #include "ns3/object.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 #include "ns3/ipv4.h"
 #include "internet-stack-helper.h"
 #include "ns3/internet-stack.h"
--- a/src/helper/ipv4-interface-container.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/ipv4-interface-container.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -1,6 +1,6 @@
 #include "ipv4-interface-container.h"
 #include "ns3/node-list.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/mobility-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/mobility-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -25,7 +25,7 @@
 #include "ns3/pointer.h"
 #include "ns3/config.h"
 #include "ns3/simulator.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 #include <iostream>
 
 namespace ns3 {
--- a/src/helper/net-device-container.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/net-device-container.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -19,7 +19,7 @@
  */
 
 #include "net-device-container.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/node-container.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/node-container.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -19,7 +19,7 @@
  */
 #include "node-container.h"
 #include "ns3/node-list.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/olsr-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/olsr-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -20,7 +20,7 @@
 #include "olsr-helper.h"
 #include "ns3/olsr-agent.h"
 #include "ns3/node-list.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/on-off-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/on-off-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -21,7 +21,7 @@
 #include "ns3/inet-socket-address.h"
 #include "ns3/packet-socket-address.h"
 #include "ns3/string.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/packet-sink-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/packet-sink-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -21,7 +21,7 @@
 #include "packet-sink-helper.h"
 #include "ns3/string.h"
 #include "ns3/inet-socket-address.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/packet-socket-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/packet-socket-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -20,7 +20,7 @@
 
 #include "packet-socket-helper.h"
 #include "ns3/packet-socket-factory.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/point-to-point-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/point-to-point-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -25,7 +25,7 @@
 #include "ns3/pcap-writer.h"
 #include "ns3/config.h"
 #include "ns3/packet.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/static-multicast-route-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/static-multicast-route-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -23,7 +23,7 @@
 #include "ns3/assert.h"
 #include "ns3/ipv4-address.h"
 #include "ns3/ipv4.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 #include "static-multicast-route-helper.h"
 
 namespace ns3 {
--- a/src/helper/udp-echo-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/udp-echo-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -21,7 +21,7 @@
 #include "ns3/udp-echo-server.h"
 #include "ns3/udp-echo-client.h"
 #include "ns3/uinteger.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/v4ping-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/v4ping-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -20,7 +20,7 @@
 
 #include "v4ping-helper.h"
 #include "ns3/v4ping.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {
 
--- a/src/helper/wifi-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/wifi-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -31,7 +31,7 @@
 #include "ns3/pcap-writer.h"
 #include "ns3/config.h"
 #include "ns3/simulator.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 NS_LOG_COMPONENT_DEFINE ("WifiHelper");
 
--- a/src/helper/yans-wifi-helper.cc	Wed Jan 21 00:28:47 2009 -0800
+++ b/src/helper/yans-wifi-helper.cc	Thu Jan 22 23:07:34 2009 -0800
@@ -27,7 +27,7 @@
 #include "ns3/pcap-writer.h"
 #include "ns3/simulator.h"
 #include "ns3/config.h"
-#include "ns3/object-names.h"
+#include "ns3/names.h"
 
 namespace ns3 {