make simple version of Names:Add even simpler. Use that in examples/names.cc
authorCraig Dowell <craigdo@ee.washington.edu>
Tue Jan 20 18:29:06 2009 -0800 (12 months ago)
changeset 41413f7f08d9daad
parent 4140 6bbf05bf4826
child 4142 59f784af5db6
make simple version of Names:Add even simpler. Use that in examples/names.cc
examples/names.cc
src/core/object-names.cc
     1.1 --- a/examples/names.cc	Tue Jan 20 17:39:18 2009 -0800
     1.2 +++ b/examples/names.cc	Tue Jan 20 18:29:06 2009 -0800
     1.3 @@ -56,8 +56,8 @@
     1.4    // as the destination, so these will go into the name system as "/Names/client"
     1.5    // and "/Names/server".  
     1.6    //
     1.7 -  Names::Add ("/Names", "client", n.Get (0));
     1.8 -  Names::Add ("/Names", "server", n.Get (1));
     1.9 +  Names::Add ("/Names/client", n.Get (0));
    1.10 +  Names::Add ("/Names/server", n.Get (1));
    1.11  
    1.12    InternetStackHelper internet;
    1.13    internet.Install (n);
    1.14 @@ -72,12 +72,12 @@
    1.15    // Add some human readable names for the devices we'll be interested in.
    1.16    // We add the names to the name space "under" the nodes we created above.
    1.17    // This has the effect of making "/Names/client/eth0" and "/Names/server/eth0"
    1.18 -  // Note that the first parameter must reference a previously named object,
    1.19 +  // Note that the first part of the path must reference a previously named object,
    1.20    // and we have, in fact, already named objects "/Names/client" and
    1.21    // "/Names/server"
    1.22    //
    1.23 -  Names::Add ("/Names/client", "eth0", d.Get (0));
    1.24 -  Names::Add ("/Names/server", "eth0", d.Get (1));
    1.25 +  Names::Add ("/Names/client/eth0", d.Get (0));
    1.26 +  Names::Add ("/Names/server/eth0", d.Get (1));
    1.27  
    1.28    Ipv4AddressHelper ipv4;
    1.29    ipv4.SetBase ("10.1.1.0", "255.255.255.0");
     2.1 --- a/src/core/object-names.cc	Tue Jan 20 17:39:18 2009 -0800
     2.2 +++ b/src/core/object-names.cc	Tue Jan 20 18:29:06 2009 -0800
     2.3 @@ -161,7 +161,55 @@
     2.4  bool
     2.5  NamesPriv::Add (std::string name, Ptr<Object> object)
     2.6  {
     2.7 -  return Add (Ptr<Object> (0, false), name, object);
     2.8 +  NS_LOG_FUNCTION (name << object);
     2.9 +  //
    2.10 +  // This is the simple, easy to use version of Add, so we want it to be flexible.
    2.11 +  //
    2.12 +  // If we are provided a name that doesn't begin with "/Names", we assume 
    2.13 +  // that the caller has given us a shortname that she wants added to the root
    2.14 +  // namespace.  This results in a call to the "real" Add with context set to 
    2.15 +  // zero, indicating what we want to do.
    2.16 +  //
    2.17 +  // If we are given a name that begins with "/Names/" we assume that this is a
    2.18 +  // fullname to the object we want to create.  We split the fullname into a 
    2.19 +  // context string and and a final segment and then call the "Real" Add.
    2.20 +  //
    2.21 +  std::string namespaceName = "/Names";
    2.22 +  std::string::size_type offset = name.find (namespaceName);
    2.23 +  if (offset == 0)
    2.24 +    {
    2.25 +      //
    2.26 +      // This must be a fully qualified longname.  All fully qualified names begin
    2.27 +      // with "/Names".  We have to split off the final segment which will become
    2.28 +      // the shortname of the object.
    2.29 +      //
    2.30 +      std::string::size_type i = name.rfind ("/");
    2.31 +      NS_ASSERT_MSG (i != std::string::npos, "NamesPriv::Add(): Internal error.  Can't find '/' in name");
    2.32 +
    2.33 +      //
    2.34 +      // The slash we found cannot be the slash at the start of the namespaceName.
    2.35 +      // This would indicate there is no shortname in the path at all.
    2.36 +      //
    2.37 +      NS_ASSERT_MSG (i != 0, "NamesPriv::Add(): Can't find a shortname in the name string");
    2.38 +
    2.39 +      //
    2.40 +      // We now know where the context string starts and ends, and where the
    2.41 +      // shortname starts and ends.  All we have to do is to call our available
    2.42 +      // function for creating addubg a shortname under a context string.
    2.43 +      //
    2.44 +      return Add (name.substr (0, i), name.substr (i + 1), object);
    2.45 +    }
    2.46 +  else
    2.47 +    {
    2.48 +      //
    2.49 +      // This must be a shortname.  Shortnames can't have ANY '/' characters in
    2.50 +      // them since they are interpreted as a final segment of a fullname.  A 
    2.51 +      // shortname in this context means creating a name in the root namespace.
    2.52 +      // We indicate this by passing a zero context to the "real" add.
    2.53 +      //
    2.54 +      NS_ASSERT_MSG (offset == std::string::npos, "NamesPriv::Add(): Unexpected '/' in shortname");
    2.55 +      return Add (Ptr<Object> (0, false), name, object);
    2.56 +    }
    2.57  }
    2.58  
    2.59  bool
    2.60 @@ -204,7 +252,7 @@
    2.61  {
    2.62    if (context == "/Names")
    2.63      {
    2.64 -      return Add (name, object);
    2.65 +      return Add (Ptr<Object> (0, false), name, object);
    2.66      }
    2.67    return Add (FindObjectFromFullName (context), name, object);
    2.68  }
    2.69 @@ -589,11 +637,11 @@
    2.70    NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
    2.71  
    2.72    //
    2.73 -  // We also have some syntactical sugary methods, so make sure they do what
    2.74 +  // We also have some syntactically sugary methods, so make sure they do what
    2.75    // they should as well.
    2.76    //
    2.77    Ptr<TestObject> bridge = CreateObject<TestObject> ();
    2.78 -  result = Names::Add ("/Names", "Bridge", client);
    2.79 +  result = Names::Add ("/Names", "Bridge", bridge);
    2.80    NS_TEST_ASSERT_EQUAL (result, true);
    2.81  
    2.82    Ptr<TestObject> bridgeEth0 = CreateObject<TestObject> ();
    2.83 @@ -606,6 +654,20 @@
    2.84    foundObject = Names::Find<TestObject> ("/Names/Bridge/eth0");
    2.85    NS_TEST_ASSERT_EQUAL (foundObject, bridgeEth0);
    2.86  
    2.87 +  Ptr<TestObject> wireless = CreateObject<TestObject> ();
    2.88 +  result = Names::Add ("/Names/Wireless", wireless);
    2.89 +  NS_TEST_ASSERT_EQUAL (result, true);
    2.90 +
    2.91 +  Ptr<TestObject> wirelessAth0 = CreateObject<TestObject> ();
    2.92 +  result = Names::Add ("/Names/Wireless/ath0", wirelessAth0);
    2.93 +  NS_TEST_ASSERT_EQUAL (result, true);
    2.94 +
    2.95 +  foundObject = Names::Find<TestObject> ("/Names/Wireless");
    2.96 +  NS_TEST_ASSERT_EQUAL (foundObject, wireless);
    2.97 +
    2.98 +  foundObject = Names::Find<TestObject> ("/Names/Wireless/ath0");
    2.99 +  NS_TEST_ASSERT_EQUAL (foundObject, wirelessAth0);
   2.100 +
   2.101    //
   2.102    // Run the simulator and destroy it to get the Destroy method called on the
   2.103    // private implementation object.  We depend on seeing a valgrind-clean run of