make simple version of Names:Add even simpler. Use that in examples/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