1.1 --- a/src/core/config.cc Wed Jan 21 00:28:47 2009 -0800
1.2 +++ b/src/core/config.cc Thu Jan 22 23:07:34 2009 -0800
1.3 @@ -22,7 +22,7 @@
1.4 #include "object.h"
1.5 #include "global-value.h"
1.6 #include "object-vector.h"
1.7 -#include "object-names.h"
1.8 +#include "names.h"
1.9 #include "pointer.h"
1.10 #include "log.h"
1.11 #include <sstream>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/src/core/names.cc Thu Jan 22 23:07:34 2009 -0800
2.3 @@ -0,0 +1,695 @@
2.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2.5 +/*
2.6 + * Copyright (c) 2009 University of Washington
2.7 + *
2.8 + * This program is free software; you can redistribute it and/or modify
2.9 + * it under the terms of the GNU General Public License version 2 as
2.10 + * published by the Free Software Foundation;
2.11 + *
2.12 + * This program is distributed in the hope that it will be useful,
2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.15 + * GNU General Public License for more details.
2.16 + *
2.17 + * You should have received a copy of the GNU General Public License
2.18 + * along with this program; if not, write to the Free Software
2.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.20 + */
2.21 +
2.22 +#include <map>
2.23 +#include "object.h"
2.24 +#include "log.h"
2.25 +#include "assert.h"
2.26 +#include "abort.h"
2.27 +#include "names.h"
2.28 +#include "ns3/simulator.h"
2.29 +
2.30 +namespace ns3 {
2.31 +
2.32 +NS_LOG_COMPONENT_DEFINE ("Names");
2.33 +
2.34 +class NameNode
2.35 +{
2.36 +public:
2.37 + NameNode ();
2.38 + NameNode (const NameNode &nameNode);
2.39 + NameNode (NameNode *parent, std::string name, Ptr<Object> object);
2.40 + NameNode &operator = (const NameNode &rhs);
2.41 +
2.42 + ~NameNode ();
2.43 +
2.44 + NameNode *m_parent;
2.45 + std::string m_name;
2.46 + Ptr<Object> m_object;
2.47 +
2.48 + std::map<std::string, NameNode *> m_nameMap;
2.49 +};
2.50 +
2.51 +NameNode::NameNode ()
2.52 + : m_parent (0), m_name (""), m_object (0)
2.53 +{
2.54 +}
2.55 +
2.56 +NameNode::NameNode (const NameNode &nameNode)
2.57 +{
2.58 + m_parent = nameNode.m_parent;
2.59 + m_name = nameNode.m_name;
2.60 + m_object = nameNode.m_object;
2.61 + m_nameMap = nameNode.m_nameMap;
2.62 +}
2.63 +
2.64 +NameNode &
2.65 +NameNode::operator = (const NameNode &rhs)
2.66 +{
2.67 + m_parent = rhs.m_parent;
2.68 + m_name = rhs.m_name;
2.69 + m_object = rhs.m_object;
2.70 + m_nameMap = rhs.m_nameMap;
2.71 + return *this;
2.72 +}
2.73 +
2.74 +NameNode::NameNode (NameNode *parent, std::string name, Ptr<Object> object)
2.75 + : m_parent (parent), m_name (name), m_object (object)
2.76 +{
2.77 +}
2.78 +
2.79 +NameNode::~NameNode ()
2.80 +{
2.81 +}
2.82 +
2.83 +class NamesPriv
2.84 +{
2.85 +public:
2.86 + NamesPriv ();
2.87 + ~NamesPriv ();
2.88 +
2.89 + bool Add (std::string name, Ptr<Object> obj);
2.90 + bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
2.91 + bool Add (std::string context, std::string name, Ptr<Object> object);
2.92 + std::string FindShortName (Ptr<Object> object);
2.93 + std::string FindFullName (Ptr<Object> object);
2.94 + Ptr<Object> FindObjectFromFullName (std::string name);
2.95 + Ptr<Object> FindObjectFromShortName (Ptr<Object> context, std::string name);
2.96 +
2.97 + static NamesPriv *Get (void);
2.98 + static void Delete (void);
2.99 +private:
2.100 + static NamesPriv **DoGet (void);
2.101 +
2.102 + NameNode *IsNamed (Ptr<Object>);
2.103 + bool IsDuplicateName (NameNode *node, std::string name);
2.104 +
2.105 + NameNode m_root;
2.106 + std::map<Ptr<Object>, NameNode *> m_objectMap;
2.107 +};
2.108 +
2.109 +NamesPriv *
2.110 +NamesPriv::Get (void)
2.111 +{
2.112 + return *(DoGet ());
2.113 +}
2.114 +
2.115 +NamesPriv **
2.116 +NamesPriv::DoGet (void)
2.117 +{
2.118 + static NamesPriv *ptr = 0;
2.119 +
2.120 + if (ptr == 0)
2.121 + {
2.122 + ptr = new NamesPriv;
2.123 + Simulator::ScheduleDestroy (&NamesPriv::Delete);
2.124 + }
2.125 +
2.126 + return &ptr;
2.127 +}
2.128 +
2.129 +void
2.130 +NamesPriv::Delete (void)
2.131 +{
2.132 + NS_LOG_FUNCTION_NOARGS ();
2.133 +
2.134 + NamesPriv **ptr = DoGet ();
2.135 + delete *ptr;
2.136 + *ptr = 0;
2.137 +}
2.138 +
2.139 +NamesPriv::NamesPriv ()
2.140 +{
2.141 + NS_LOG_FUNCTION_NOARGS ();
2.142 +
2.143 + m_root.m_parent = 0;
2.144 + m_root.m_name = "Names";
2.145 + m_root.m_object = 0;
2.146 +}
2.147 +
2.148 +NamesPriv::~NamesPriv ()
2.149 +{
2.150 + NS_LOG_FUNCTION_NOARGS ();
2.151 +
2.152 + //
2.153 + // Every name is associated with an object in the object map, so freeing the
2.154 + // NameNodes in this map will free all of the memory allocated for the NameNodes
2.155 + //
2.156 + for (std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.begin (); i != m_objectMap.end (); ++i)
2.157 + {
2.158 + delete i->second;
2.159 + i->second = 0;
2.160 + }
2.161 +
2.162 + m_root.m_parent = 0;
2.163 + m_root.m_name = "";
2.164 + m_root.m_object = 0;
2.165 +}
2.166 +
2.167 +bool
2.168 +NamesPriv::Add (std::string name, Ptr<Object> object)
2.169 +{
2.170 + NS_LOG_FUNCTION (name << object);
2.171 + //
2.172 + // This is the simple, easy to use version of Add, so we want it to be flexible.
2.173 + //
2.174 + // If we are provided a name that doesn't begin with "/Names", we assume
2.175 + // that the caller has given us a shortname that she wants added to the root
2.176 + // namespace. This results in a call to the "real" Add with context set to
2.177 + // zero, indicating what we want to do.
2.178 + //
2.179 + // If we are given a name that begins with "/Names/" we assume that this is a
2.180 + // fullname to the object we want to create. We split the fullname into a
2.181 + // context string and and a final segment and then call the "Real" Add.
2.182 + //
2.183 + std::string namespaceName = "/Names";
2.184 + std::string::size_type offset = name.find (namespaceName);
2.185 + if (offset == 0)
2.186 + {
2.187 + //
2.188 + // This must be a fully qualified longname. All fully qualified names begin
2.189 + // with "/Names". We have to split off the final segment which will become
2.190 + // the shortname of the object.
2.191 + //
2.192 + std::string::size_type i = name.rfind ("/");
2.193 + NS_ASSERT_MSG (i != std::string::npos, "NamesPriv::Add(): Internal error. Can't find '/' in name");
2.194 +
2.195 + //
2.196 + // The slash we found cannot be the slash at the start of the namespaceName.
2.197 + // This would indicate there is no shortname in the path at all.
2.198 + //
2.199 + NS_ASSERT_MSG (i != 0, "NamesPriv::Add(): Can't find a shortname in the name string");
2.200 +
2.201 + //
2.202 + // We now know where the context string starts and ends, and where the
2.203 + // shortname starts and ends. All we have to do is to call our available
2.204 + // function for creating addubg a shortname under a context string.
2.205 + //
2.206 + return Add (name.substr (0, i), name.substr (i + 1), object);
2.207 + }
2.208 + else
2.209 + {
2.210 + //
2.211 + // This must be a shortname. Shortnames can't have ANY '/' characters in
2.212 + // them since they are interpreted as a final segment of a fullname. A
2.213 + // shortname in this context means creating a name in the root namespace.
2.214 + // We indicate this by passing a zero context to the "real" add.
2.215 + //
2.216 + NS_ASSERT_MSG (offset == std::string::npos, "NamesPriv::Add(): Unexpected '/' in shortname");
2.217 + return Add (Ptr<Object> (0, false), name, object);
2.218 + }
2.219 +}
2.220 +
2.221 +bool
2.222 +NamesPriv::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
2.223 +{
2.224 + NS_LOG_FUNCTION (context << name << object);
2.225 +
2.226 + if (IsNamed (object))
2.227 + {
2.228 + NS_LOG_LOGIC ("Object is already named");
2.229 + return false;
2.230 + }
2.231 +
2.232 + NameNode *node = 0;
2.233 + if (context)
2.234 + {
2.235 + node = IsNamed (context);
2.236 + NS_ASSERT_MSG (node, "NamesPriv::Name(): context must point to a previously named node");
2.237 + }
2.238 + else
2.239 + {
2.240 + node = &m_root;
2.241 + }
2.242 +
2.243 + if (IsDuplicateName (node, name))
2.244 + {
2.245 + NS_LOG_LOGIC ("Name is already taken");
2.246 + return false;
2.247 + }
2.248 +
2.249 + NameNode *newNode = new NameNode(node, name, object);
2.250 + node->m_nameMap[name] = newNode;
2.251 + m_objectMap[object] = newNode;
2.252 +
2.253 + return true;
2.254 +}
2.255 +
2.256 +bool
2.257 +NamesPriv::Add (std::string context, std::string name, Ptr<Object> object)
2.258 +{
2.259 + if (context == "/Names")
2.260 + {
2.261 + return Add (Ptr<Object> (0, false), name, object);
2.262 + }
2.263 + return Add (FindObjectFromFullName (context), name, object);
2.264 +}
2.265 +
2.266 +std::string
2.267 +NamesPriv::FindShortName (Ptr<Object> object)
2.268 +{
2.269 + NS_LOG_FUNCTION (object);
2.270 +
2.271 + std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
2.272 + if (i == m_objectMap.end ())
2.273 + {
2.274 + NS_LOG_LOGIC ("Object does not exist in object map");
2.275 + return "";
2.276 + }
2.277 + else
2.278 + {
2.279 + NS_LOG_LOGIC ("Object exists in object map");
2.280 + return i->second->m_name;
2.281 + }
2.282 +}
2.283 +
2.284 +std::string
2.285 +NamesPriv::FindFullName (Ptr<Object> object)
2.286 +{
2.287 + NS_LOG_FUNCTION (object);
2.288 +
2.289 + std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
2.290 + if (i == m_objectMap.end ())
2.291 + {
2.292 + NS_LOG_LOGIC ("Object does not exist in object map");
2.293 + return "";
2.294 + }
2.295 +
2.296 + NameNode *p = i->second;
2.297 + NS_ASSERT_MSG (p, "NamesPriv::FindFullName(): Internal error: Invalid NameNode pointer from map");
2.298 +
2.299 + std::string fullname;
2.300 +
2.301 + do
2.302 + {
2.303 + fullname = "/" + p->m_name + fullname;
2.304 + NS_LOG_LOGIC ("fullname is " << fullname);
2.305 + }
2.306 + while ((p = p->m_parent) != 0);
2.307 +
2.308 + return fullname;
2.309 +}
2.310 +
2.311 +
2.312 +Ptr<Object>
2.313 +NamesPriv::FindObjectFromFullName (std::string name)
2.314 +{
2.315 + std::string namespaceName = "/Names/";
2.316 + std::string::size_type offset = name.find (namespaceName);
2.317 + if (offset == std::string::npos)
2.318 + {
2.319 + NS_LOG_LOGIC (name << " is not in the " << namespaceName << " name space");
2.320 + return 0;
2.321 + }
2.322 +
2.323 + std::string remaining = name.substr (namespaceName.size ());
2.324 + NameNode *node = &m_root;
2.325 +
2.326 + //
2.327 + // remaining is now composed entirely of path segments in the /Names name space.
2.328 + // and we have eaten the leading slash. e.g., remaining = "ClientNode/eth0"
2.329 + // The start of the search is at the root of the name space.
2.330 + //
2.331 + for (;;)
2.332 + {
2.333 + NS_LOG_LOGIC ("Looking for the object of name " << remaining);
2.334 + offset = remaining.find ("/");
2.335 + if (offset == std::string::npos)
2.336 + {
2.337 + //
2.338 + // There are no remaining slashes so this is the last segment of the
2.339 + // specified name. We're done when we find it
2.340 + //
2.341 + std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (remaining);
2.342 + if (i == node->m_nameMap.end ())
2.343 + {
2.344 + NS_LOG_LOGIC ("Name does not exist in name map");
2.345 + return 0;
2.346 + }
2.347 + else
2.348 + {
2.349 + NS_LOG_LOGIC ("Name parsed, found object");
2.350 + return i->second->m_object;
2.351 + }
2.352 + }
2.353 + else
2.354 + {
2.355 + //
2.356 + // There are more slashes so this is an intermediate segment of the
2.357 + // specified name. We need to "recurse" when we find this segment.
2.358 + //
2.359 + offset = remaining.find ("/");
2.360 + std::string segment = remaining.substr(0, offset);
2.361 +
2.362 + std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (segment);
2.363 + if (i == node->m_nameMap.end ())
2.364 + {
2.365 + NS_LOG_LOGIC ("Name does not exist in name map");
2.366 + return 0;
2.367 + }
2.368 + else
2.369 + {
2.370 + node = i->second;
2.371 + remaining = remaining.substr (offset + 1);
2.372 + NS_LOG_LOGIC ("Intermediate segment parsed");
2.373 + continue;
2.374 + }
2.375 + }
2.376 + }
2.377 +
2.378 + NS_ASSERT_MSG (node, "NamesPriv::FindObjectFromFullName(): Internal error: this can't happen");
2.379 + return 0;
2.380 +}
2.381 +
2.382 +Ptr<Object>
2.383 +NamesPriv::FindObjectFromShortName (Ptr<Object> context, std::string name)
2.384 +{
2.385 + NS_LOG_FUNCTION (context << name);
2.386 +
2.387 + NameNode *node = 0;
2.388 +
2.389 + if (context == 0)
2.390 + {
2.391 + NS_LOG_LOGIC ("Zero context implies root NameNode");
2.392 + node = &m_root;
2.393 + }
2.394 + else
2.395 + {
2.396 + node = IsNamed (context);
2.397 + if (node == 0)
2.398 + {
2.399 + NS_LOG_LOGIC ("Context does not point to a previously named node");
2.400 + return 0;
2.401 + }
2.402 + }
2.403 +
2.404 + std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
2.405 + if (i == node->m_nameMap.end ())
2.406 + {
2.407 + NS_LOG_LOGIC ("Name does not exist in name map");
2.408 + return 0;
2.409 + }
2.410 + else
2.411 + {
2.412 + NS_LOG_LOGIC ("Name exists in name map");
2.413 + return i->second->m_object;
2.414 + }
2.415 +}
2.416 +
2.417 +NameNode *
2.418 +NamesPriv::IsNamed (Ptr<Object> object)
2.419 +{
2.420 + NS_LOG_FUNCTION (object);
2.421 +
2.422 + std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
2.423 + if (i == m_objectMap.end ())
2.424 + {
2.425 + NS_LOG_LOGIC ("Object does not exist in object map, returning NameNode 0");
2.426 + return 0;
2.427 + }
2.428 + else
2.429 + {
2.430 + NS_LOG_LOGIC ("Object exists in object map, returning NameNode " << &i->second);
2.431 + return i->second;
2.432 + }
2.433 +}
2.434 +
2.435 +bool
2.436 +NamesPriv::IsDuplicateName (NameNode *node, std::string name)
2.437 +{
2.438 + NS_LOG_FUNCTION (node << name);
2.439 +
2.440 + std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
2.441 + if (i == node->m_nameMap.end ())
2.442 + {
2.443 + NS_LOG_LOGIC ("Name does not exist in name map");
2.444 + return false;
2.445 + }
2.446 + else
2.447 + {
2.448 + NS_LOG_LOGIC ("Name exists in name map");
2.449 + return true;
2.450 + }
2.451 +}
2.452 +
2.453 +void
2.454 +Names::Delete (void)
2.455 +{
2.456 + NamesPriv::Delete ();
2.457 +}
2.458 +
2.459 +bool
2.460 +Names::Add (std::string name, Ptr<Object> object)
2.461 +{
2.462 + return NamesPriv::Get ()->Add (name, object);
2.463 +}
2.464 +
2.465 +bool
2.466 +Names::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
2.467 +{
2.468 + return NamesPriv::Get ()->Add (context, name, object);
2.469 +}
2.470 +
2.471 +bool
2.472 +Names::Add (std::string context, std::string name, Ptr<Object> object)
2.473 +{
2.474 + return NamesPriv::Get ()->Add (context, name, object);
2.475 +}
2.476 +
2.477 +std::string
2.478 +Names::FindShortName (Ptr<Object> object)
2.479 +{
2.480 + return NamesPriv::Get ()->FindShortName (object);
2.481 +}
2.482 +
2.483 +std::string
2.484 +Names::FindFullName (Ptr<Object> object)
2.485 +{
2.486 + return NamesPriv::Get ()->FindFullName (object);
2.487 +}
2.488 +
2.489 +Ptr<Object>
2.490 +Names::FindObjectFromFullNameInternal (std::string name)
2.491 +{
2.492 + return NamesPriv::Get ()->FindObjectFromFullName (name);
2.493 +}
2.494 +
2.495 +Ptr<Object>
2.496 +Names::FindObjectFromShortNameInternal (Ptr<Object> context, std::string name)
2.497 +{
2.498 + return NamesPriv::Get ()->FindObjectFromShortName (context, name);
2.499 +}
2.500 +
2.501 +} //namespace ns3
2.502 +
2.503 +#ifdef RUN_SELF_TESTS
2.504 +
2.505 +#include "test.h"
2.506 +#include "object-factory.h"
2.507 +
2.508 +namespace ns3 {
2.509 +
2.510 +class TestObject : public Object
2.511 +{
2.512 +public:
2.513 + static TypeId GetTypeId (void)
2.514 + {
2.515 + static TypeId tid = TypeId ("TestObject")
2.516 + .SetParent (Object::GetTypeId ())
2.517 + .HideFromDocumentation ()
2.518 + .AddConstructor<TestObject> ();
2.519 + return tid;
2.520 + }
2.521 + TestObject () {}
2.522 + virtual void Dispose (void) {}
2.523 +};
2.524 +
2.525 +class NamesTest : public Test
2.526 +{
2.527 +public:
2.528 + NamesTest ();
2.529 + virtual bool RunTests (void);
2.530 +};
2.531 +
2.532 +NamesTest::NamesTest ()
2.533 + : Test ("Names")
2.534 +{
2.535 +}
2.536 +
2.537 +bool
2.538 +NamesTest::RunTests (void)
2.539 +{
2.540 + bool result = true;
2.541 +
2.542 + //
2.543 + // Name a couple of objects at the root level
2.544 + //
2.545 + Ptr<TestObject> client = CreateObject<TestObject> ();
2.546 + result = Names::Add ("Client", client);
2.547 + NS_TEST_ASSERT_EQUAL (result, true);
2.548 +
2.549 + Ptr<TestObject> server = CreateObject<TestObject> ();
2.550 + result = Names::Add ("Server", server);
2.551 + NS_TEST_ASSERT_EQUAL (result, true);
2.552 +
2.553 + //
2.554 + // We shouldn't be able to add another name to a previously named object
2.555 + //
2.556 + result = Names::Add ("Not Client", client);
2.557 + NS_TEST_ASSERT_EQUAL (result, false);
2.558 +
2.559 + //
2.560 + // We shouldn't be able to duplicate a name at the root level.
2.561 + //
2.562 + Ptr<TestObject> secondClient = CreateObject<TestObject> ();
2.563 + result = Names::Add ("Client", secondClient);
2.564 + NS_TEST_ASSERT_EQUAL (result, false);
2.565 +
2.566 + //
2.567 + // We should be able to add a new name in the first object's context
2.568 + //
2.569 + Ptr<TestObject> clientEth0 = CreateObject<TestObject> ();
2.570 + result = Names::Add (client, "eth0", clientEth0);
2.571 + NS_TEST_ASSERT_EQUAL (result, true);
2.572 +
2.573 + //
2.574 + // We shouldn't be able to duplicate a name in that context.
2.575 + //
2.576 + Ptr<TestObject> secondClientEth0 = CreateObject<TestObject> ();
2.577 + result = Names::Add (client, "eth0", secondClientEth0);
2.578 + NS_TEST_ASSERT_EQUAL (result, false);
2.579 +
2.580 + //
2.581 + // We should be able to add the same name in the second object's context
2.582 + //
2.583 + Ptr<TestObject> serverEth0 = CreateObject<TestObject> ();
2.584 + result = Names::Add (server, "eth0", serverEth0);
2.585 + NS_TEST_ASSERT_EQUAL (result, true);
2.586 +
2.587 + //
2.588 + // We should be able to find the short names for the objects we created
2.589 + //
2.590 + std::string found;
2.591 +
2.592 + found = Names::FindShortName (client);
2.593 + NS_TEST_ASSERT_EQUAL (found, "Client");
2.594 +
2.595 + found = Names::FindShortName (server);
2.596 + NS_TEST_ASSERT_EQUAL (found, "Server");
2.597 +
2.598 + found = Names::FindShortName (clientEth0);
2.599 + NS_TEST_ASSERT_EQUAL (found, "eth0");
2.600 +
2.601 + found = Names::FindShortName (serverEth0);
2.602 + NS_TEST_ASSERT_EQUAL (found, "eth0");
2.603 +
2.604 + //
2.605 + // We should be able to find the full names for the objects we created
2.606 + //
2.607 + found = Names::FindFullName (client);
2.608 + NS_TEST_ASSERT_EQUAL (found, "/Names/Client");
2.609 +
2.610 + found = Names::FindFullName (server);
2.611 + NS_TEST_ASSERT_EQUAL (found, "/Names/Server");
2.612 +
2.613 + found = Names::FindFullName (clientEth0);
2.614 + NS_TEST_ASSERT_EQUAL (found, "/Names/Client/eth0");
2.615 +
2.616 + found = Names::FindFullName (serverEth0);
2.617 + NS_TEST_ASSERT_EQUAL (found, "/Names/Server/eth0");
2.618 +
2.619 + //
2.620 + // We should be able to find the objects from the short names
2.621 + //
2.622 + Ptr<TestObject> foundObject;
2.623 +
2.624 + foundObject = Names::FindObjectFromShortName<TestObject> (0, "Client");
2.625 + NS_TEST_ASSERT_EQUAL (foundObject, client);
2.626 +
2.627 + foundObject = Names::FindObjectFromShortName<TestObject> (0, "Server");
2.628 + NS_TEST_ASSERT_EQUAL (foundObject, server);
2.629 +
2.630 + foundObject = Names::FindObjectFromShortName<TestObject> (client, "eth0");
2.631 + NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
2.632 +
2.633 + foundObject = Names::FindObjectFromShortName<TestObject> (server, "eth0");
2.634 + NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
2.635 +
2.636 + //
2.637 + // We should be able to find the objects from their full names
2.638 + //
2.639 + foundObject = Names::Find<TestObject> ("/Names/Client");
2.640 + NS_TEST_ASSERT_EQUAL (foundObject, client);
2.641 +
2.642 + foundObject = Names::Find<TestObject> ("/Names/Server");
2.643 + NS_TEST_ASSERT_EQUAL (foundObject, server);
2.644 +
2.645 + foundObject = Names::Find<TestObject> ("/Names/Client/eth0");
2.646 + NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
2.647 +
2.648 + foundObject = Names::Find<TestObject> ("/Names/Server/eth0");
2.649 + NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
2.650 +
2.651 + //
2.652 + // We also have some syntactically sugary methods, so make sure they do what
2.653 + // they should as well.
2.654 + //
2.655 + Ptr<TestObject> bridge = CreateObject<TestObject> ();
2.656 + result = Names::Add ("/Names", "Bridge", bridge);
2.657 + NS_TEST_ASSERT_EQUAL (result, true);
2.658 +
2.659 + Ptr<TestObject> bridgeEth0 = CreateObject<TestObject> ();
2.660 + result = Names::Add ("/Names/Bridge", "eth0", bridgeEth0);
2.661 + NS_TEST_ASSERT_EQUAL (result, true);
2.662 +
2.663 + foundObject = Names::Find<TestObject> ("/Names/Bridge");
2.664 + NS_TEST_ASSERT_EQUAL (foundObject, bridge);
2.665 +
2.666 + foundObject = Names::Find<TestObject> ("/Names/Bridge/eth0");
2.667 + NS_TEST_ASSERT_EQUAL (foundObject, bridgeEth0);
2.668 +
2.669 + Ptr<TestObject> wireless = CreateObject<TestObject> ();
2.670 + result = Names::Add ("/Names/Wireless", wireless);
2.671 + NS_TEST_ASSERT_EQUAL (result, true);
2.672 +
2.673 + Ptr<TestObject> wirelessAth0 = CreateObject<TestObject> ();
2.674 + result = Names::Add ("/Names/Wireless/ath0", wirelessAth0);
2.675 + NS_TEST_ASSERT_EQUAL (result, true);
2.676 +
2.677 + foundObject = Names::Find<TestObject> ("/Names/Wireless");
2.678 + NS_TEST_ASSERT_EQUAL (foundObject, wireless);
2.679 +
2.680 + foundObject = Names::Find<TestObject> ("/Names/Wireless/ath0");
2.681 + NS_TEST_ASSERT_EQUAL (foundObject, wirelessAth0);
2.682 +
2.683 + //
2.684 + // Run the simulator and destroy it to get the Destroy method called on the
2.685 + // private implementation object. We depend on seeing a valgrind-clean run of
2.686 + // the unit tests to really determine if the clean up was really successful.
2.687 + //
2.688 + Simulator::Run ();
2.689 + Simulator::Destroy ();
2.690 +
2.691 + return true;
2.692 +}
2.693 +
2.694 +static NamesTest g_namesTests;
2.695 +
2.696 +} // namespace ns3
2.697 +
2.698 +#endif /* RUN_SELF_TESTS */
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/core/names.h Thu Jan 22 23:07:34 2009 -0800
3.3 @@ -0,0 +1,273 @@
3.4 +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
3.5 +/*
3.6 + * Copyright (c) 2009 University of Washington
3.7 + *
3.8 + * This program is free software; you can redistribute it and/or modify
3.9 + * it under the terms of the GNU General Public License version 2 as
3.10 + * published by the Free Software Foundation;
3.11 + *
3.12 + * This program is distributed in the hope that it will be useful,
3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 + * GNU General Public License for more details.
3.16 + *
3.17 + * You should have received a copy of the GNU General Public License
3.18 + * along with this program; if not, write to the Free Software
3.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3.20 + */
3.21 +
3.22 +#ifndef OBJECT_NAMES_H
3.23 +#define OBJECT_NAMES_H
3.24 +
3.25 +#include "ns3/ptr.h"
3.26 +#include "ns3/object.h"
3.27 +
3.28 +namespace ns3 {
3.29 +
3.30 +/**
3.31 + * \brief A directory of name and Ptr<Object> associations that allows us to
3.32 + * give any ns3 Object a name.
3.33 + */
3.34 +class Names
3.35 +{
3.36 +public:
3.37 +
3.38 + /**
3.39 + * Add the association between the string "name" and the Ptr<Object> obj
3.40 + * at the root of the "/Names" name space. This can be seen as equivalent
3.41 + * to adding a Pointer Attribute called "name" to the to the root name
3.42 + * space object and then assigning the value obj to that attribute. The
3.43 + * config facility will see it that way.
3.44 + *
3.45 + * \param name The name of the object you want to associate.
3.46 + * \param obj A smart pointer to the object itself.
3.47 + */
3.48 + static bool Add (std::string name, Ptr<Object> obj);
3.49 +
3.50 + /**
3.51 + * Add the association between the string "name" and the Ptr<Object> obj
3.52 + * in the object context given by the Ptr<Object> context. This can be
3.53 + * seen as equivalent to adding a Pointer Attribute called "name" to the
3.54 + * object given by "context" and then assigning the value obj to that
3.55 + * attribute. The config facility will see it that way.
3.56 + *
3.57 + * \param context A spart pointer to an object under which you want this
3.58 + * name to be defined.
3.59 + * \param name The name of the object you want to associate.
3.60 + * \param obj A smart pointer to the object itself.
3.61 + *
3.62 + * \returns true if the association was successfully completed, false otherwise
3.63 + */
3.64 + static bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
3.65 +
3.66 + /**
3.67 + * Syntactic sugar around the Object context Name method. Allows you to
3.68 + * specify the context with a string instead of the pointer. If the first
3.69 + * parameter (context) is "/Names" this turns into a call into Name at the
3.70 + * root of the name space. Otherwise it does a FindObjectFromFullNameInternal
3.71 + * on the context and adds the name to a subspace.
3.72 + *
3.73 + * \param context A fully qualified name describing a previously named object.
3.74 + * under which you want this name to be defined.
3.75 + * \param name The name of the object you want to associate.
3.76 + * \param obj A smart pointer to the object itself.
3.77 + *
3.78 + * \returns true if the association was successfully completed, false otherwise
3.79 + */
3.80 + static bool Add (std::string context, std::string name, Ptr<Object> object);
3.81 +
3.82 + /**
3.83 + * Given a pointer to an object, look to see if that object has a name
3.84 + * associated with it and return the shortname for the object.
3.85 + *
3.86 + * The fullname of an object is a fully qualified namespace name, for example
3.87 + * if you have a device that you have previously named "eth0" under a node
3.88 + * you have named "client", the fullname of the device will then be
3.89 + * "/Names/client/eth0".
3.90 + *
3.91 + * The shortname of an object is the name of the object in its parent name
3.92 + * space. Using the example above, asking for the shortname of the device
3.93 + * will result in "eth0" being returned.
3.94 + *
3.95 + * \param object A spart pointer to an object for which you want to find
3.96 + * its shortname.
3.97 + *
3.98 + * \returns a string containing the shortname of the object.
3.99 + */
3.100 + static std::string FindShortName (Ptr<Object> object);
3.101 +
3.102 + /**
3.103 + * Given a pointer to an object, look to see if that object has a name
3.104 + * associated with it and return the fully qualified namespace name
3.105 + * for the object.
3.106 + *
3.107 + * The fullname of an object is a fully qualified namespace name, for example
3.108 + * if you have a device that you have previously named "eth0" under a node
3.109 + * you have named "client", the fullname of the device will then be
3.110 + * "/Names/client/eth0".
3.111 + *
3.112 + * The shortname of an object is the name of the object in its parent name
3.113 + * space. Using the example above, asking for the shortname of the device
3.114 + * will result in "eth0" being returned.
3.115 + *
3.116 + * \param object A spart pointer to an object for which you want to find
3.117 + * its fullname.
3.118 + *
3.119 + * \returns a string containing the fullname of the object.
3.120 + */
3.121 + static std::string FindFullName (Ptr<Object> object);
3.122 +
3.123 + /**
3.124 + * Given a fullname string, look to see if there's an object in the system
3.125 + * with a that associated with it. If there is, do a QueryObject on the
3.126 + * resulting object to convert it to the requested typename.
3.127 + *
3.128 + * The fullname of an object is a fully qualified namespace name, for example
3.129 + * if you have a device that you have previously named "eth0" under a node
3.130 + * you have named "client", the fullname of the device will then be
3.131 + * "/Names/client/eth0".
3.132 + *
3.133 + * \param name A string containing a fully qualified name space name
3.134 + * used to locate the object.
3.135 + *
3.136 + * \returns a smart pointer to the named object converted to the requested
3.137 + * type.
3.138 + */
3.139 + template <typename T>
3.140 + static Ptr<T> FindObjectFromFullName (std::string name);
3.141 +
3.142 + /**
3.143 + * Given a fullname string, look to see if there's an object in the system
3.144 + * with a that associated with it. If there is, do a QueryObject on the
3.145 + * resulting object to convert it to the requested typename.
3.146 + *
3.147 + * The fullname of an object is a fully qualified namespace name, for example
3.148 + * if you have a device that you have previously named "eth0" under a node
3.149 + * you have named "client", the fullname of the device will then be
3.150 + * "/Names/client/eth0".
3.151 + *
3.152 + * \param name A string containing a fully qualified name space name
3.153 + * used to locate the object.
3.154 + *
3.155 + *
3.156 + * \returns a smart pointer to the named object converted to the requested
3.157 + * type.
3.158 + *
3.159 + * @comment This method is identical to FindObjectFromFullName, but has a
3.160 + * short signature since it is a common use and we want it to be easy to
3.161 + * type.
3.162 + */
3.163 + template <typename T>
3.164 + static Ptr<T> Find (std::string name);
3.165 +
3.166 + /**
3.167 + * Given an object context and a shortname string, look through the names
3.168 + * associated with the namespace defined by the context object to see if
3.169 + * there's an object there with the given shortname.
3.170 + *
3.171 + * The fullname of an object is a fully qualified namespace name, for example
3.172 + * if you have a device that you have previously named "eth0" under a node
3.173 + * you have named "client", the fullname of the device will then be
3.174 + * "/Names/client/eth0".
3.175 + *
3.176 + * The shortname of an object is the name of the object in its parent name
3.177 + * space. Using the example above, asking for the shortname of the device
3.178 + * will result in "eth0" being returned.
3.179 + *
3.180 + * The context object provides a namespace context, in the case of the example
3.181 + * it would be the "client" object under which we look for the short name.
3.182 + * In the example above, the context pointer would be the Ptr<Object> to the
3.183 + * client node, and the name would be the shortname "eth0"
3.184 + *
3.185 + * \param context A spart pointer to an object under which you want to look
3.186 + * for the provided name.
3.187 + * \param name A string containing a shortname to look for.
3.188 + *
3.189 + * \returns a smart pointer to the named object converted to the requested
3.190 + * type.
3.191 + */
3.192 + template <typename T>
3.193 + static Ptr<T> FindObjectFromShortName (Ptr<Object> context, std::string name);
3.194 +
3.195 + /**
3.196 + * Clean up all of the data structures of the implementation and delete the
3.197 + * underlying singleton. Used to get valgrind-clean runs if the simulator
3.198 + * is not run. Normally singleton cleanup is scheduled on Simulator::Destroy.
3.199 + */
3.200 + static void Delete (void);
3.201 +
3.202 +private:
3.203 + /**
3.204 + * \internal
3.205 + *
3.206 + * \brief Non-templated internal version of FindObjectFromLongName
3.207 + *
3.208 + * \param name A string containing a longname to look for.
3.209 + *
3.210 + * \returns a smart pointer to the named object.
3.211 + */
3.212 + static Ptr<Object> FindObjectFromFullNameInternal (std::string name);
3.213 +
3.214 + /**
3.215 + * \internal
3.216 + *
3.217 + * \brief Non-templated internal version of FindObjectFromShortName
3.218 + *
3.219 + * \param context A spart pointer to an object under which you want to look
3.220 + * for the provided name.
3.221 + * \param name A string containing a shortname to look for.
3.222 + *
3.223 + * \returns a smart pointer to the named object.
3.224 + */
3.225 + static Ptr<Object> FindObjectFromShortNameInternal (Ptr<Object> context, std::string name);
3.226 +};
3.227 +
3.228 +/**
3.229 + * \brief Template definition of corresponding template declaration found in class Names.
3.230 + */
3.231 +template <typename T>
3.232 +Ptr<T>
3.233 +Names::Find (std::string name)
3.234 +{
3.235 + return FindObjectFromFullName<T> (name);
3.236 +}
3.237 +
3.238 +/**
3.239 + * \brief Template definition of corresponding template declaration found in class Names.
3.240 + */
3.241 +template <typename T>
3.242 +Ptr<T>
3.243 +Names::FindObjectFromFullName (std::string name)
3.244 +{
3.245 + Ptr<Object> obj = FindObjectFromFullNameInternal (name);
3.246 + if (obj)
3.247 + {
3.248 + return obj->GetObject<T> ();
3.249 + }
3.250 + else
3.251 + {
3.252 + return 0;
3.253 + }
3.254 +}
3.255 +
3.256 +/**
3.257 + * \brief Template definition of corresponding template declaration found in class Names.
3.258 + */
3.259 +template <typename T>
3.260 +Ptr<T>
3.261 +Names::FindObjectFromShortName (Ptr<Object> context, std::string name)
3.262 +{
3.263 + Ptr<Object> obj = FindObjectFromShortNameInternal (context, name);
3.264 + if (obj)
3.265 + {
3.266 + return obj->GetObject<T> ();
3.267 + }
3.268 + else
3.269 + {
3.270 + return 0;
3.271 + }
3.272 +}
3.273 +
3.274 +}//namespace ns3
3.275 +
3.276 +#endif /* OBJECT_NAMES_H */
4.1 --- a/src/core/object-names.cc Wed Jan 21 00:28:47 2009 -0800
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,695 +0,0 @@
4.4 -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
4.5 -/*
4.6 - * Copyright (c) 2009 University of Washington
4.7 - *
4.8 - * This program is free software; you can redistribute it and/or modify
4.9 - * it under the terms of the GNU General Public License version 2 as
4.10 - * published by the Free Software Foundation;
4.11 - *
4.12 - * This program is distributed in the hope that it will be useful,
4.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 - * GNU General Public License for more details.
4.16 - *
4.17 - * You should have received a copy of the GNU General Public License
4.18 - * along with this program; if not, write to the Free Software
4.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4.20 - */
4.21 -
4.22 -#include <map>
4.23 -#include "object.h"
4.24 -#include "log.h"
4.25 -#include "assert.h"
4.26 -#include "abort.h"
4.27 -#include "object-names.h"
4.28 -#include "ns3/simulator.h"
4.29 -
4.30 -namespace ns3 {
4.31 -
4.32 -NS_LOG_COMPONENT_DEFINE ("Names");
4.33 -
4.34 -class NameNode
4.35 -{
4.36 -public:
4.37 - NameNode ();
4.38 - NameNode (const NameNode &nameNode);
4.39 - NameNode (NameNode *parent, std::string name, Ptr<Object> object);
4.40 - NameNode &operator = (const NameNode &rhs);
4.41 -
4.42 - ~NameNode ();
4.43 -
4.44 - NameNode *m_parent;
4.45 - std::string m_name;
4.46 - Ptr<Object> m_object;
4.47 -
4.48 - std::map<std::string, NameNode *> m_nameMap;
4.49 -};
4.50 -
4.51 -NameNode::NameNode ()
4.52 - : m_parent (0), m_name (""), m_object (0)
4.53 -{
4.54 -}
4.55 -
4.56 -NameNode::NameNode (const NameNode &nameNode)
4.57 -{
4.58 - m_parent = nameNode.m_parent;
4.59 - m_name = nameNode.m_name;
4.60 - m_object = nameNode.m_object;
4.61 - m_nameMap = nameNode.m_nameMap;
4.62 -}
4.63 -
4.64 -NameNode &
4.65 -NameNode::operator = (const NameNode &rhs)
4.66 -{
4.67 - m_parent = rhs.m_parent;
4.68 - m_name = rhs.m_name;
4.69 - m_object = rhs.m_object;
4.70 - m_nameMap = rhs.m_nameMap;
4.71 - return *this;
4.72 -}
4.73 -
4.74 -NameNode::NameNode (NameNode *parent, std::string name, Ptr<Object> object)
4.75 - : m_parent (parent), m_name (name), m_object (object)
4.76 -{
4.77 -}
4.78 -
4.79 -NameNode::~NameNode ()
4.80 -{
4.81 -}
4.82 -
4.83 -class NamesPriv
4.84 -{
4.85 -public:
4.86 - NamesPriv ();
4.87 - ~NamesPriv ();
4.88 -
4.89 - bool Add (std::string name, Ptr<Object> obj);
4.90 - bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
4.91 - bool Add (std::string context, std::string name, Ptr<Object> object);
4.92 - std::string FindShortName (Ptr<Object> object);
4.93 - std::string FindFullName (Ptr<Object> object);
4.94 - Ptr<Object> FindObjectFromFullName (std::string name);
4.95 - Ptr<Object> FindObjectFromShortName (Ptr<Object> context, std::string name);
4.96 -
4.97 - static NamesPriv *Get (void);
4.98 - static void Delete (void);
4.99 -private:
4.100 - static NamesPriv **DoGet (void);
4.101 -
4.102 - NameNode *IsNamed (Ptr<Object>);
4.103 - bool IsDuplicateName (NameNode *node, std::string name);
4.104 -
4.105 - NameNode m_root;
4.106 - std::map<Ptr<Object>, NameNode *> m_objectMap;
4.107 -};
4.108 -
4.109 -NamesPriv *
4.110 -NamesPriv::Get (void)
4.111 -{
4.112 - return *(DoGet ());
4.113 -}
4.114 -
4.115 -NamesPriv **
4.116 -NamesPriv::DoGet (void)
4.117 -{
4.118 - static NamesPriv *ptr = 0;
4.119 -
4.120 - if (ptr == 0)
4.121 - {
4.122 - ptr = new NamesPriv;
4.123 - Simulator::ScheduleDestroy (&NamesPriv::Delete);
4.124 - }
4.125 -
4.126 - return &ptr;
4.127 -}
4.128 -
4.129 -void
4.130 -NamesPriv::Delete (void)
4.131 -{
4.132 - NS_LOG_FUNCTION_NOARGS ();
4.133 -
4.134 - NamesPriv **ptr = DoGet ();
4.135 - delete *ptr;
4.136 - *ptr = 0;
4.137 -}
4.138 -
4.139 -NamesPriv::NamesPriv ()
4.140 -{
4.141 - NS_LOG_FUNCTION_NOARGS ();
4.142 -
4.143 - m_root.m_parent = 0;
4.144 - m_root.m_name = "Names";
4.145 - m_root.m_object = 0;
4.146 -}
4.147 -
4.148 -NamesPriv::~NamesPriv ()
4.149 -{
4.150 - NS_LOG_FUNCTION_NOARGS ();
4.151 -
4.152 - //
4.153 - // Every name is associated with an object in the object map, so freeing the
4.154 - // NameNodes in this map will free all of the memory allocated for the NameNodes
4.155 - //
4.156 - for (std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.begin (); i != m_objectMap.end (); ++i)
4.157 - {
4.158 - delete i->second;
4.159 - i->second = 0;
4.160 - }
4.161 -
4.162 - m_root.m_parent = 0;
4.163 - m_root.m_name = "";
4.164 - m_root.m_object = 0;
4.165 -}
4.166 -
4.167 -bool
4.168 -NamesPriv::Add (std::string name, Ptr<Object> object)
4.169 -{
4.170 - NS_LOG_FUNCTION (name << object);
4.171 - //
4.172 - // This is the simple, easy to use version of Add, so we want it to be flexible.
4.173 - //
4.174 - // If we are provided a name that doesn't begin with "/Names", we assume
4.175 - // that the caller has given us a shortname that she wants added to the root
4.176 - // namespace. This results in a call to the "real" Add with context set to
4.177 - // zero, indicating what we want to do.
4.178 - //
4.179 - // If we are given a name that begins with "/Names/" we assume that this is a
4.180 - // fullname to the object we want to create. We split the fullname into a
4.181 - // context string and and a final segment and then call the "Real" Add.
4.182 - //
4.183 - std::string namespaceName = "/Names";
4.184 - std::string::size_type offset = name.find (namespaceName);
4.185 - if (offset == 0)
4.186 - {
4.187 - //
4.188 - // This must be a fully qualified longname. All fully qualified names begin
4.189 - // with "/Names". We have to split off the final segment which will become
4.190 - // the shortname of the object.
4.191 - //
4.192 - std::string::size_type i = name.rfind ("/");
4.193 - NS_ASSERT_MSG (i != std::string::npos, "NamesPriv::Add(): Internal error. Can't find '/' in name");
4.194 -
4.195 - //
4.196 - // The slash we found cannot be the slash at the start of the namespaceName.
4.197 - // This would indicate there is no shortname in the path at all.
4.198 - //
4.199 - NS_ASSERT_MSG (i != 0, "NamesPriv::Add(): Can't find a shortname in the name string");
4.200 -
4.201 - //
4.202 - // We now know where the context string starts and ends, and where the
4.203 - // shortname starts and ends. All we have to do is to call our available
4.204 - // function for creating addubg a shortname under a context string.
4.205 - //
4.206 - return Add (name.substr (0, i), name.substr (i + 1), object);
4.207 - }
4.208 - else
4.209 - {
4.210 - //
4.211 - // This must be a shortname. Shortnames can't have ANY '/' characters in
4.212 - // them since they are interpreted as a final segment of a fullname. A
4.213 - // shortname in this context means creating a name in the root namespace.
4.214 - // We indicate this by passing a zero context to the "real" add.
4.215 - //
4.216 - NS_ASSERT_MSG (offset == std::string::npos, "NamesPriv::Add(): Unexpected '/' in shortname");
4.217 - return Add (Ptr<Object> (0, false), name, object);
4.218 - }
4.219 -}
4.220 -
4.221 -bool
4.222 -NamesPriv::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
4.223 -{
4.224 - NS_LOG_FUNCTION (context << name << object);
4.225 -
4.226 - if (IsNamed (object))
4.227 - {
4.228 - NS_LOG_LOGIC ("Object is already named");
4.229 - return false;
4.230 - }
4.231 -
4.232 - NameNode *node = 0;
4.233 - if (context)
4.234 - {
4.235 - node = IsNamed (context);
4.236 - NS_ASSERT_MSG (node, "NamesPriv::Name(): context must point to a previously named node");
4.237 - }
4.238 - else
4.239 - {
4.240 - node = &m_root;
4.241 - }
4.242 -
4.243 - if (IsDuplicateName (node, name))
4.244 - {
4.245 - NS_LOG_LOGIC ("Name is already taken");
4.246 - return false;
4.247 - }
4.248 -
4.249 - NameNode *newNode = new NameNode(node, name, object);
4.250 - node->m_nameMap[name] = newNode;
4.251 - m_objectMap[object] = newNode;
4.252 -
4.253 - return true;
4.254 -}
4.255 -
4.256 -bool
4.257 -NamesPriv::Add (std::string context, std::string name, Ptr<Object> object)
4.258 -{
4.259 - if (context == "/Names")
4.260 - {
4.261 - return Add (Ptr<Object> (0, false), name, object);
4.262 - }
4.263 - return Add (FindObjectFromFullName (context), name, object);
4.264 -}
4.265 -
4.266 -std::string
4.267 -NamesPriv::FindShortName (Ptr<Object> object)
4.268 -{
4.269 - NS_LOG_FUNCTION (object);
4.270 -
4.271 - std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
4.272 - if (i == m_objectMap.end ())
4.273 - {
4.274 - NS_LOG_LOGIC ("Object does not exist in object map");
4.275 - return "";
4.276 - }
4.277 - else
4.278 - {
4.279 - NS_LOG_LOGIC ("Object exists in object map");
4.280 - return i->second->m_name;
4.281 - }
4.282 -}
4.283 -
4.284 -std::string
4.285 -NamesPriv::FindFullName (Ptr<Object> object)
4.286 -{
4.287 - NS_LOG_FUNCTION (object);
4.288 -
4.289 - std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
4.290 - if (i == m_objectMap.end ())
4.291 - {
4.292 - NS_LOG_LOGIC ("Object does not exist in object map");
4.293 - return "";
4.294 - }
4.295 -
4.296 - NameNode *p = i->second;
4.297 - NS_ASSERT_MSG (p, "NamesPriv::FindFullName(): Internal error: Invalid NameNode pointer from map");
4.298 -
4.299 - std::string fullname;
4.300 -
4.301 - do
4.302 - {
4.303 - fullname = "/" + p->m_name + fullname;
4.304 - NS_LOG_LOGIC ("fullname is " << fullname);
4.305 - }
4.306 - while ((p = p->m_parent) != 0);
4.307 -
4.308 - return fullname;
4.309 -}
4.310 -
4.311 -
4.312 -Ptr<Object>
4.313 -NamesPriv::FindObjectFromFullName (std::string name)
4.314 -{
4.315 - std::string namespaceName = "/Names/";
4.316 - std::string::size_type offset = name.find (namespaceName);
4.317 - if (offset == std::string::npos)
4.318 - {
4.319 - NS_LOG_LOGIC (name << " is not in the " << namespaceName << " name space");
4.320 - return 0;
4.321 - }
4.322 -
4.323 - std::string remaining = name.substr (namespaceName.size ());
4.324 - NameNode *node = &m_root;
4.325 -
4.326 - //
4.327 - // remaining is now composed entirely of path segments in the /Names name space.
4.328 - // and we have eaten the leading slash. e.g., remaining = "ClientNode/eth0"
4.329 - // The start of the search is at the root of the name space.
4.330 - //
4.331 - for (;;)
4.332 - {
4.333 - NS_LOG_LOGIC ("Looking for the object of name " << remaining);
4.334 - offset = remaining.find ("/");
4.335 - if (offset == std::string::npos)
4.336 - {
4.337 - //
4.338 - // There are no remaining slashes so this is the last segment of the
4.339 - // specified name. We're done when we find it
4.340 - //
4.341 - std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (remaining);
4.342 - if (i == node->m_nameMap.end ())
4.343 - {
4.344 - NS_LOG_LOGIC ("Name does not exist in name map");
4.345 - return 0;
4.346 - }
4.347 - else
4.348 - {
4.349 - NS_LOG_LOGIC ("Name parsed, found object");
4.350 - return i->second->m_object;
4.351 - }
4.352 - }
4.353 - else
4.354 - {
4.355 - //
4.356 - // There are more slashes so this is an intermediate segment of the
4.357 - // specified name. We need to "recurse" when we find this segment.
4.358 - //
4.359 - offset = remaining.find ("/");
4.360 - std::string segment = remaining.substr(0, offset);
4.361 -
4.362 - std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (segment);
4.363 - if (i == node->m_nameMap.end ())
4.364 - {
4.365 - NS_LOG_LOGIC ("Name does not exist in name map");
4.366 - return 0;
4.367 - }
4.368 - else
4.369 - {
4.370 - node = i->second;
4.371 - remaining = remaining.substr (offset + 1);
4.372 - NS_LOG_LOGIC ("Intermediate segment parsed");
4.373 - continue;
4.374 - }
4.375 - }
4.376 - }
4.377 -
4.378 - NS_ASSERT_MSG (node, "NamesPriv::FindObjectFromFullName(): Internal error: this can't happen");
4.379 - return 0;
4.380 -}
4.381 -
4.382 -Ptr<Object>
4.383 -NamesPriv::FindObjectFromShortName (Ptr<Object> context, std::string name)
4.384 -{
4.385 - NS_LOG_FUNCTION (context << name);
4.386 -
4.387 - NameNode *node = 0;
4.388 -
4.389 - if (context == 0)
4.390 - {
4.391 - NS_LOG_LOGIC ("Zero context implies root NameNode");
4.392 - node = &m_root;
4.393 - }
4.394 - else
4.395 - {
4.396 - node = IsNamed (context);
4.397 - if (node == 0)
4.398 - {
4.399 - NS_LOG_LOGIC ("Context does not point to a previously named node");
4.400 - return 0;
4.401 - }
4.402 - }
4.403 -
4.404 - std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
4.405 - if (i == node->m_nameMap.end ())
4.406 - {
4.407 - NS_LOG_LOGIC ("Name does not exist in name map");
4.408 - return 0;
4.409 - }
4.410 - else
4.411 - {
4.412 - NS_LOG_LOGIC ("Name exists in name map");
4.413 - return i->second->m_object;
4.414 - }
4.415 -}
4.416 -
4.417 -NameNode *
4.418 -NamesPriv::IsNamed (Ptr<Object> object)
4.419 -{
4.420 - NS_LOG_FUNCTION (object);
4.421 -
4.422 - std::map<Ptr<Object>, NameNode *>::iterator i = m_objectMap.find (object);
4.423 - if (i == m_objectMap.end ())
4.424 - {
4.425 - NS_LOG_LOGIC ("Object does not exist in object map, returning NameNode 0");
4.426 - return 0;
4.427 - }
4.428 - else
4.429 - {
4.430 - NS_LOG_LOGIC ("Object exists in object map, returning NameNode " << &i->second);
4.431 - return i->second;
4.432 - }
4.433 -}
4.434 -
4.435 -bool
4.436 -NamesPriv::IsDuplicateName (NameNode *node, std::string name)
4.437 -{
4.438 - NS_LOG_FUNCTION (node << name);
4.439 -
4.440 - std::map<std::string, NameNode *>::iterator i = node->m_nameMap.find (name);
4.441 - if (i == node->m_nameMap.end ())
4.442 - {
4.443 - NS_LOG_LOGIC ("Name does not exist in name map");
4.444 - return false;
4.445 - }
4.446 - else
4.447 - {
4.448 - NS_LOG_LOGIC ("Name exists in name map");
4.449 - return true;
4.450 - }
4.451 -}
4.452 -
4.453 -void
4.454 -Names::Delete (void)
4.455 -{
4.456 - NamesPriv::Delete ();
4.457 -}
4.458 -
4.459 -bool
4.460 -Names::Add (std::string name, Ptr<Object> object)
4.461 -{
4.462 - return NamesPriv::Get ()->Add (name, object);
4.463 -}
4.464 -
4.465 -bool
4.466 -Names::Add (Ptr<Object> context, std::string name, Ptr<Object> object)
4.467 -{
4.468 - return NamesPriv::Get ()->Add (context, name, object);
4.469 -}
4.470 -
4.471 -bool
4.472 -Names::Add (std::string context, std::string name, Ptr<Object> object)
4.473 -{
4.474 - return NamesPriv::Get ()->Add (context, name, object);
4.475 -}
4.476 -
4.477 -std::string
4.478 -Names::FindShortName (Ptr<Object> object)
4.479 -{
4.480 - return NamesPriv::Get ()->FindShortName (object);
4.481 -}
4.482 -
4.483 -std::string
4.484 -Names::FindFullName (Ptr<Object> object)
4.485 -{
4.486 - return NamesPriv::Get ()->FindFullName (object);
4.487 -}
4.488 -
4.489 -Ptr<Object>
4.490 -Names::FindObjectFromFullNameInternal (std::string name)
4.491 -{
4.492 - return NamesPriv::Get ()->FindObjectFromFullName (name);
4.493 -}
4.494 -
4.495 -Ptr<Object>
4.496 -Names::FindObjectFromShortNameInternal (Ptr<Object> context, std::string name)
4.497 -{
4.498 - return NamesPriv::Get ()->FindObjectFromShortName (context, name);
4.499 -}
4.500 -
4.501 -} //namespace ns3
4.502 -
4.503 -#ifdef RUN_SELF_TESTS
4.504 -
4.505 -#include "test.h"
4.506 -#include "object-factory.h"
4.507 -
4.508 -namespace ns3 {
4.509 -
4.510 -class TestObject : public Object
4.511 -{
4.512 -public:
4.513 - static TypeId GetTypeId (void)
4.514 - {
4.515 - static TypeId tid = TypeId ("TestObject")
4.516 - .SetParent (Object::GetTypeId ())
4.517 - .HideFromDocumentation ()
4.518 - .AddConstructor<TestObject> ();
4.519 - return tid;
4.520 - }
4.521 - TestObject () {}
4.522 - virtual void Dispose (void) {}
4.523 -};
4.524 -
4.525 -class NamesTest : public Test
4.526 -{
4.527 -public:
4.528 - NamesTest ();
4.529 - virtual bool RunTests (void);
4.530 -};
4.531 -
4.532 -NamesTest::NamesTest ()
4.533 - : Test ("Names")
4.534 -{
4.535 -}
4.536 -
4.537 -bool
4.538 -NamesTest::RunTests (void)
4.539 -{
4.540 - bool result = true;
4.541 -
4.542 - //
4.543 - // Name a couple of objects at the root level
4.544 - //
4.545 - Ptr<TestObject> client = CreateObject<TestObject> ();
4.546 - result = Names::Add ("Client", client);
4.547 - NS_TEST_ASSERT_EQUAL (result, true);
4.548 -
4.549 - Ptr<TestObject> server = CreateObject<TestObject> ();
4.550 - result = Names::Add ("Server", server);
4.551 - NS_TEST_ASSERT_EQUAL (result, true);
4.552 -
4.553 - //
4.554 - // We shouldn't be able to add another name to a previously named object
4.555 - //
4.556 - result = Names::Add ("Not Client", client);
4.557 - NS_TEST_ASSERT_EQUAL (result, false);
4.558 -
4.559 - //
4.560 - // We shouldn't be able to duplicate a name at the root level.
4.561 - //
4.562 - Ptr<TestObject> secondClient = CreateObject<TestObject> ();
4.563 - result = Names::Add ("Client", secondClient);
4.564 - NS_TEST_ASSERT_EQUAL (result, false);
4.565 -
4.566 - //
4.567 - // We should be able to add a new name in the first object's context
4.568 - //
4.569 - Ptr<TestObject> clientEth0 = CreateObject<TestObject> ();
4.570 - result = Names::Add (client, "eth0", clientEth0);
4.571 - NS_TEST_ASSERT_EQUAL (result, true);
4.572 -
4.573 - //
4.574 - // We shouldn't be able to duplicate a name in that context.
4.575 - //
4.576 - Ptr<TestObject> secondClientEth0 = CreateObject<TestObject> ();
4.577 - result = Names::Add (client, "eth0", secondClientEth0);
4.578 - NS_TEST_ASSERT_EQUAL (result, false);
4.579 -
4.580 - //
4.581 - // We should be able to add the same name in the second object's context
4.582 - //
4.583 - Ptr<TestObject> serverEth0 = CreateObject<TestObject> ();
4.584 - result = Names::Add (server, "eth0", serverEth0);
4.585 - NS_TEST_ASSERT_EQUAL (result, true);
4.586 -
4.587 - //
4.588 - // We should be able to find the short names for the objects we created
4.589 - //
4.590 - std::string found;
4.591 -
4.592 - found = Names::FindShortName (client);
4.593 - NS_TEST_ASSERT_EQUAL (found, "Client");
4.594 -
4.595 - found = Names::FindShortName (server);
4.596 - NS_TEST_ASSERT_EQUAL (found, "Server");
4.597 -
4.598 - found = Names::FindShortName (clientEth0);
4.599 - NS_TEST_ASSERT_EQUAL (found, "eth0");
4.600 -
4.601 - found = Names::FindShortName (serverEth0);
4.602 - NS_TEST_ASSERT_EQUAL (found, "eth0");
4.603 -
4.604 - //
4.605 - // We should be able to find the full names for the objects we created
4.606 - //
4.607 - found = Names::FindFullName (client);
4.608 - NS_TEST_ASSERT_EQUAL (found, "/Names/Client");
4.609 -
4.610 - found = Names::FindFullName (server);
4.611 - NS_TEST_ASSERT_EQUAL (found, "/Names/Server");
4.612 -
4.613 - found = Names::FindFullName (clientEth0);
4.614 - NS_TEST_ASSERT_EQUAL (found, "/Names/Client/eth0");
4.615 -
4.616 - found = Names::FindFullName (serverEth0);
4.617 - NS_TEST_ASSERT_EQUAL (found, "/Names/Server/eth0");
4.618 -
4.619 - //
4.620 - // We should be able to find the objects from the short names
4.621 - //
4.622 - Ptr<TestObject> foundObject;
4.623 -
4.624 - foundObject = Names::FindObjectFromShortName<TestObject> (0, "Client");
4.625 - NS_TEST_ASSERT_EQUAL (foundObject, client);
4.626 -
4.627 - foundObject = Names::FindObjectFromShortName<TestObject> (0, "Server");
4.628 - NS_TEST_ASSERT_EQUAL (foundObject, server);
4.629 -
4.630 - foundObject = Names::FindObjectFromShortName<TestObject> (client, "eth0");
4.631 - NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
4.632 -
4.633 - foundObject = Names::FindObjectFromShortName<TestObject> (server, "eth0");
4.634 - NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
4.635 -
4.636 - //
4.637 - // We should be able to find the objects from their full names
4.638 - //
4.639 - foundObject = Names::Find<TestObject> ("/Names/Client");
4.640 - NS_TEST_ASSERT_EQUAL (foundObject, client);
4.641 -
4.642 - foundObject = Names::Find<TestObject> ("/Names/Server");
4.643 - NS_TEST_ASSERT_EQUAL (foundObject, server);
4.644 -
4.645 - foundObject = Names::Find<TestObject> ("/Names/Client/eth0");
4.646 - NS_TEST_ASSERT_EQUAL (foundObject, clientEth0);
4.647 -
4.648 - foundObject = Names::Find<TestObject> ("/Names/Server/eth0");
4.649 - NS_TEST_ASSERT_EQUAL (foundObject, serverEth0);
4.650 -
4.651 - //
4.652 - // We also have some syntactically sugary methods, so make sure they do what
4.653 - // they should as well.
4.654 - //
4.655 - Ptr<TestObject> bridge = CreateObject<TestObject> ();
4.656 - result = Names::Add ("/Names", "Bridge", bridge);
4.657 - NS_TEST_ASSERT_EQUAL (result, true);
4.658 -
4.659 - Ptr<TestObject> bridgeEth0 = CreateObject<TestObject> ();
4.660 - result = Names::Add ("/Names/Bridge", "eth0", bridgeEth0);
4.661 - NS_TEST_ASSERT_EQUAL (result, true);
4.662 -
4.663 - foundObject = Names::Find<TestObject> ("/Names/Bridge");
4.664 - NS_TEST_ASSERT_EQUAL (foundObject, bridge);
4.665 -
4.666 - foundObject = Names::Find<TestObject> ("/Names/Bridge/eth0");
4.667 - NS_TEST_ASSERT_EQUAL (foundObject, bridgeEth0);
4.668 -
4.669 - Ptr<TestObject> wireless = CreateObject<TestObject> ();
4.670 - result = Names::Add ("/Names/Wireless", wireless);
4.671 - NS_TEST_ASSERT_EQUAL (result, true);
4.672 -
4.673 - Ptr<TestObject> wirelessAth0 = CreateObject<TestObject> ();
4.674 - result = Names::Add ("/Names/Wireless/ath0", wirelessAth0);
4.675 - NS_TEST_ASSERT_EQUAL (result, true);
4.676 -
4.677 - foundObject = Names::Find<TestObject> ("/Names/Wireless");
4.678 - NS_TEST_ASSERT_EQUAL (foundObject, wireless);
4.679 -
4.680 - foundObject = Names::Find<TestObject> ("/Names/Wireless/ath0");
4.681 - NS_TEST_ASSERT_EQUAL (foundObject, wirelessAth0);
4.682 -
4.683 - //
4.684 - // Run the simulator and destroy it to get the Destroy method called on the
4.685 - // private implementation object. We depend on seeing a valgrind-clean run of
4.686 - // the unit tests to really determine if the clean up was really successful.
4.687 - //
4.688 - Simulator::Run ();
4.689 - Simulator::Destroy ();
4.690 -
4.691 - return true;
4.692 -}
4.693 -
4.694 -static NamesTest g_namesTests;
4.695 -
4.696 -} // namespace ns3
4.697 -
4.698 -#endif /* RUN_SELF_TESTS */
5.1 --- a/src/core/object-names.h Wed Jan 21 00:28:47 2009 -0800
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,273 +0,0 @@
5.4 -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
5.5 -/*
5.6 - * Copyright (c) 2009 University of Washington
5.7 - *
5.8 - * This program is free software; you can redistribute it and/or modify
5.9 - * it under the terms of the GNU General Public License version 2 as
5.10 - * published by the Free Software Foundation;
5.11 - *
5.12 - * This program is distributed in the hope that it will be useful,
5.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 - * GNU General Public License for more details.
5.16 - *
5.17 - * You should have received a copy of the GNU General Public License
5.18 - * along with this program; if not, write to the Free Software
5.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5.20 - */
5.21 -
5.22 -#ifndef OBJECT_NAMES_H
5.23 -#define OBJECT_NAMES_H
5.24 -
5.25 -#include "ns3/ptr.h"
5.26 -#include "ns3/object.h"
5.27 -
5.28 -namespace ns3 {
5.29 -
5.30 -/**
5.31 - * \brief A directory of name and Ptr<Object> associations that allows us to
5.32 - * give any ns3 Object a name.
5.33 - */
5.34 -class Names
5.35 -{
5.36 -public:
5.37 -
5.38 - /**
5.39 - * Add the association between the string "name" and the Ptr<Object> obj
5.40 - * at the root of the "/Names" name space. This can be seen as equivalent
5.41 - * to adding a Pointer Attribute called "name" to the to the root name
5.42 - * space object and then assigning the value obj to that attribute. The
5.43 - * config facility will see it that way.
5.44 - *
5.45 - * \param name The name of the object you want to associate.
5.46 - * \param obj A smart pointer to the object itself.
5.47 - */
5.48 - static bool Add (std::string name, Ptr<Object> obj);
5.49 -
5.50 - /**
5.51 - * Add the association between the string "name" and the Ptr<Object> obj
5.52 - * in the object context given by the Ptr<Object> context. This can be
5.53 - * seen as equivalent to adding a Pointer Attribute called "name" to the
5.54 - * object given by "context" and then assigning the value obj to that
5.55 - * attribute. The config facility will see it that way.
5.56 - *
5.57 - * \param context A spart pointer to an object under which you want this
5.58 - * name to be defined.
5.59 - * \param name The name of the object you want to associate.
5.60 - * \param obj A smart pointer to the object itself.
5.61 - *
5.62 - * \returns true if the association was successfully completed, false otherwise
5.63 - */
5.64 - static bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
5.65 -
5.66 - /**
5.67 - * Syntactic sugar around the Object context Name method. Allows you to
5.68 - * specify the context with a string instead of the pointer. If the first
5.69 - * parameter (context) is "/Names" this turns into a call into Name at the
5.70 - * root of the name space. Otherwise it does a FindObjectFromFullNameInternal
5.71 - * on the context and adds the name to a subspace.
5.72 - *
5.73 - * \param context A fully qualified name describing a previously named object.
5.74 - * under which you want this name to be defined.
5.75 - * \param name The name of the object you want to associate.
5.76 - * \param obj A smart pointer to the object itself.
5.77 - *
5.78 - * \returns true if the association was successfully completed, false otherwise
5.79 - */
5.80 - static bool Add (std::string context, std::string name, Ptr<Object> object);
5.81 -
5.82 - /**
5.83 - * Given a pointer to an object, look to see if that object has a name
5.84 - * associated with it and return the shortname for the object.
5.85 - *
5.86 - * The fullname of an object is a fully qualified namespace name, for example
5.87 - * if you have a device that you have previously named "eth0" under a node
5.88 - * you have named "client", the fullname of the device will then be
5.89 - * "/Names/client/eth0".
5.90 - *
5.91 - * The shortname of an object is the name of the object in its parent name
5.92 - * space. Using the example above, asking for the shortname of the device
5.93 - * will result in "eth0" being returned.
5.94 - *
5.95 - * \param object A spart pointer to an object for which you want to find
5.96 - * its shortname.
5.97 - *
5.98 - * \returns a string containing the shortname of the object.
5.99 - */
5.100 - static std::string FindShortName (Ptr<Object> object);
5.101 -
5.102 - /**
5.103 - * Given a pointer to an object, look to see if that object has a name
5.104 - * associated with it and return the fully qualified namespace name
5.105 - * for the object.
5.106 - *
5.107 - * The fullname of an object is a fully qualified namespace name, for example
5.108 - * if you have a device that you have previously named "eth0" under a node
5.109 - * you have named "client", the fullname of the device will then be
5.110 - * "/Names/client/eth0".
5.111 - *
5.112 - * The shortname of an object is the name of the object in its parent name
5.113 - * space. Using the example above, asking for the shortname of the device
5.114 - * will result in "eth0" being returned.
5.115 - *
5.116 - * \param object A spart pointer to an object for which you want to find
5.117 - * its fullname.
5.118 - *
5.119 - * \returns a string containing the fullname of the object.
5.120 - */
5.121 - static std::string FindFullName (Ptr<Object> object);
5.122 -
5.123 - /**
5.124 - * Given a fullname string, look to see if there's an object in the system
5.125 - * with a that associated with it. If there is, do a QueryObject on the
5.126 - * resulting object to convert it to the requested typename.
5.127 - *
5.128 - * The fullname of an object is a fully qualified namespace name, for example
5.129 - * if you have a device that you have previously named "eth0" under a node
5.130 - * you have named "client", the fullname of the device will then be
5.131 - * "/Names/client/eth0".
5.132 - *
5.133 - * \param name A string containing a fully qualified name space name
5.134 - * used to locate the object.
5.135 - *
5.136 - * \returns a smart pointer to the named object converted to the requested
5.137 - * type.
5.138 - */
5.139 - template <typename T>
5.140 - static Ptr<T> FindObjectFromFullName (std::string name);
5.141 -
5.142 - /**
5.143 - * Given a fullname string, look to see if there's an object in the system
5.144 - * with a that associated with it. If there is, do a QueryObject on the
5.145 - * resulting object to convert it to the requested typename.
5.146 - *
5.147 - * The fullname of an object is a fully qualified namespace name, for example
5.148 - * if you have a device that you have previously named "eth0" under a node
5.149 - * you have named "client", the fullname of the device will then be
5.150 - * "/Names/client/eth0".
5.151 - *
5.152 - * \param name A string containing a fully qualified name space name
5.153 - * used to locate the object.
5.154 - *
5.155 - *
5.156 - * \returns a smart pointer to the named object converted to the requested
5.157 - * type.
5.158 - *
5.159 - * @comment This method is identical to FindObjectFromFullName, but has a
5.160 - * short signature since it is a common use and we want it to be easy to
5.161 - * type.
5.162 - */
5.163 - template <typename T>
5.164 - static Ptr<T> Find (std::string name);
5.165 -
5.166 - /**
5.167 - * Given an object context and a shortname string, look through the names
5.168 - * associated with the namespace defined by the context object to see if
5.169 - * there's an object there with the given shortname.
5.170 - *
5.171 - * The fullname of an object is a fully qualified namespace name, for example
5.172 - * if you have a device that you have previously named "eth0" under a node
5.173 - * you have named "client", the fullname of the device will then be
5.174 - * "/Names/client/eth0".
5.175 - *
5.176 - * The shortname of an object is the name of the object in its parent name
5.177 - * space. Using the example above, asking for the shortname of the device
5.178 - * will result in "eth0" being returned.
5.179 - *
5.180 - * The context object provides a namespace context, in the case of the example
5.181 - * it would be the "client" object under which we look for the short name.
5.182 - * In the example above, the context pointer would be the Ptr<Object> to the
5.183 - * client node, and the name would be the shortname "eth0"
5.184 - *
5.185 - * \param context A spart pointer to an object under which you want to look
5.186 - * for the provided name.
5.187 - * \param name A string containing a shortname to look for.
5.188 - *
5.189 - * \returns a smart pointer to the named object converted to the requested
5.190 - * type.
5.191 - */
5.192 - template <typename T>
5.193 - static Ptr<T> FindObjectFromShortName (Ptr<Object> context, std::string name);
5.194 -
5.195 - /**
5.196 - * Clean up all of the data structures of the implementation and delete the
5.197 - * underlying singleton. Used to get valgrind-clean runs if the simulator
5.198 - * is not run. Normally singleton cleanup is scheduled on Simulator::Destroy.
5.199 - */
5.200 - static void Delete (void);
5.201 -
5.202 -private:
5.203 - /**
5.204 - * \internal
5.205 - *
5.206 - * \brief Non-templated internal version of FindObjectFromLongName
5.207 - *
5.208 - * \param name A string containing a longname to look for.
5.209 - *
5.210 - * \returns a smart pointer to the named object.
5.211 - */
5.212 - static Ptr<Object> FindObjectFromFullNameInternal (std::string name);
5.213 -
5.214 - /**
5.215 - * \internal
5.216 - *
5.217 - * \brief Non-templated internal version of FindObjectFromShortName
5.218 - *
5.219 - * \param context A spart pointer to an object under which you want to look
5.220 - * for the provided name.
5.221 - * \param name A string containing a shortname to look for.
5.222 - *
5.223 - * \returns a smart pointer to the named object.
5.224 - */
5.225 - static Ptr<Object> FindObjectFromShortNameInternal (Ptr<Object> context, std::string name);
5.226 -};
5.227 -
5.228 -/**
5.229 - * \brief Template definition of corresponding template declaration found in class Names.
5.230 - */
5.231 -template <typename T>
5.232 -Ptr<T>
5.233 -Names::Find (std::string name)
5.234 -{
5.235 - return FindObjectFromFullName<T> (name);
5.236 -}
5.237 -
5.238 -/**
5.239 - * \brief Template definition of corresponding template declaration found in class Names.
5.240 - */
5.241 -template <typename T>
5.242 -Ptr<T>
5.243 -Names::FindObjectFromFullName (std::string name)
5.244 -{
5.245 - Ptr<Object> obj = FindObjectFromFullNameInternal (name);
5.246 - if (obj)
5.247 - {
5.248 - return obj->GetObject<T> ();
5.249 - }
5.250 - else
5.251 - {
5.252 - return 0;
5.253 - }
5.254 -}
5.255 -
5.256 -/**
5.257 - * \brief Template definition of corresponding template declaration found in class Names.
5.258 - */
5.259 -template <typename T>
5.260 -Ptr<T>
5.261 -Names::FindObjectFromShortName (Ptr<Object> context, std::string name)
5.262 -{
5.263 - Ptr<Object> obj = FindObjectFromShortNameInternal (context, name);
5.264 - if (obj)
5.265 - {
5.266 - return obj->GetObject<T> ();
5.267 - }
5.268 - else
5.269 - {
5.270 - return 0;
5.271 - }
5.272 -}
5.273 -
5.274 -}//namespace ns3
5.275 -
5.276 -#endif /* OBJECT_NAMES_H */
6.1 --- a/src/core/wscript Wed Jan 21 00:28:47 2009 -0800
6.2 +++ b/src/core/wscript Thu Jan 22 23:07:34 2009 -0800
6.3 @@ -53,7 +53,7 @@
6.4 'trace-source-accessor.cc',
6.5 'config.cc',
6.6 'callback.cc',
6.7 - 'object-names.cc',
6.8 + 'names.cc',
6.9 ]
6.10 core.uselib = 'RT'
6.11
6.12 @@ -99,7 +99,7 @@
6.13 'object-vector.h',
6.14 'deprecated.h',
6.15 'abort.h',
6.16 - 'object-names.h',
6.17 + 'names.h',
6.18 ]
6.19
6.20 if sys.platform == 'win32':
7.1 --- a/src/helper/application-container.cc Wed Jan 21 00:28:47 2009 -0800
7.2 +++ b/src/helper/application-container.cc Thu Jan 22 23:07:34 2009 -0800
7.3 @@ -18,7 +18,7 @@
7.4 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7.5 */
7.6
7.7 -#include "ns3/object-names.h"
7.8 +#include "ns3/names.h"
7.9 #include "application-container.h"
7.10
7.11 namespace ns3 {
8.1 --- a/src/helper/bridge-helper.cc Wed Jan 21 00:28:47 2009 -0800
8.2 +++ b/src/helper/bridge-helper.cc Thu Jan 22 23:07:34 2009 -0800
8.3 @@ -20,7 +20,7 @@
8.4 #include "ns3/log.h"
8.5 #include "ns3/bridge-net-device.h"
8.6 #include "ns3/node.h"
8.7 -#include "ns3/object-names.h"
8.8 +#include "ns3/names.h"
8.9
8.10 NS_LOG_COMPONENT_DEFINE ("BridgeHelper");
8.11
9.1 --- a/src/helper/csma-helper.cc Wed Jan 21 00:28:47 2009 -0800
9.2 +++ b/src/helper/csma-helper.cc Thu Jan 22 23:07:34 2009 -0800
9.3 @@ -26,7 +26,7 @@
9.4 #include "ns3/pcap-writer.h"
9.5 #include "ns3/config.h"
9.6 #include "ns3/packet.h"
9.7 -#include "ns3/object-names.h"
9.8 +#include "ns3/names.h"
9.9 #include <string>
9.10
9.11 namespace ns3 {
10.1 --- a/src/helper/emu-helper.cc Wed Jan 21 00:28:47 2009 -0800
10.2 +++ b/src/helper/emu-helper.cc Thu Jan 22 23:07:34 2009 -0800
10.3 @@ -21,7 +21,7 @@
10.4 #include "ns3/log.h"
10.5 #include "ns3/simulator.h"
10.6 #include "ns3/object-factory.h"
10.7 -#include "ns3/object-names.h"
10.8 +#include "ns3/names.h"
10.9 #include "ns3/queue.h"
10.10 #include "ns3/emu-net-device.h"
10.11 #include "ns3/pcap-writer.h"
11.1 --- a/src/helper/internet-stack-helper.cc Wed Jan 21 00:28:47 2009 -0800
11.2 +++ b/src/helper/internet-stack-helper.cc Thu Jan 22 23:07:34 2009 -0800
11.3 @@ -21,7 +21,7 @@
11.4 #include "ns3/assert.h"
11.5 #include "ns3/log.h"
11.6 #include "ns3/object.h"
11.7 -#include "ns3/object-names.h"
11.8 +#include "ns3/names.h"
11.9 #include "ns3/ipv4.h"
11.10 #include "internet-stack-helper.h"
11.11 #include "ns3/internet-stack.h"
12.1 --- a/src/helper/ipv4-interface-container.cc Wed Jan 21 00:28:47 2009 -0800
12.2 +++ b/src/helper/ipv4-interface-container.cc Thu Jan 22 23:07:34 2009 -0800
12.3 @@ -1,6 +1,6 @@
12.4 #include "ipv4-interface-container.h"
12.5 #include "ns3/node-list.h"
12.6 -#include "ns3/object-names.h"
12.7 +#include "ns3/names.h"
12.8
12.9 namespace ns3 {
12.10
13.1 --- a/src/helper/mobility-helper.cc Wed Jan 21 00:28:47 2009 -0800
13.2 +++ b/src/helper/mobility-helper.cc Thu Jan 22 23:07:34 2009 -0800
13.3 @@ -25,7 +25,7 @@
13.4 #include "ns3/pointer.h"
13.5 #include "ns3/config.h"
13.6 #include "ns3/simulator.h"
13.7 -#include "ns3/object-names.h"
13.8 +#include "ns3/names.h"
13.9 #include <iostream>
13.10
13.11 namespace ns3 {
14.1 --- a/src/helper/net-device-container.cc Wed Jan 21 00:28:47 2009 -0800
14.2 +++ b/src/helper/net-device-container.cc Thu Jan 22 23:07:34 2009 -0800
14.3 @@ -19,7 +19,7 @@
14.4 */
14.5
14.6 #include "net-device-container.h"
14.7 -#include "ns3/object-names.h"
14.8 +#include "ns3/names.h"
14.9
14.10 namespace ns3 {
14.11
15.1 --- a/src/helper/node-container.cc Wed Jan 21 00:28:47 2009 -0800
15.2 +++ b/src/helper/node-container.cc Thu Jan 22 23:07:34 2009 -0800
15.3 @@ -19,7 +19,7 @@
15.4 */
15.5 #include "node-container.h"
15.6 #include "ns3/node-list.h"
15.7 -#include "ns3/object-names.h"
15.8 +#include "ns3/names.h"
15.9
15.10 namespace ns3 {
15.11
16.1 --- a/src/helper/olsr-helper.cc Wed Jan 21 00:28:47 2009 -0800
16.2 +++ b/src/helper/olsr-helper.cc Thu Jan 22 23:07:34 2009 -0800
16.3 @@ -20,7 +20,7 @@
16.4 #include "olsr-helper.h"
16.5 #include "ns3/olsr-agent.h"
16.6 #include "ns3/node-list.h"
16.7 -#include "ns3/object-names.h"
16.8 +#include "ns3/names.h"
16.9
16.10 namespace ns3 {
16.11
17.1 --- a/src/helper/on-off-helper.cc Wed Jan 21 00:28:47 2009 -0800
17.2 +++ b/src/helper/on-off-helper.cc Thu Jan 22 23:07:34 2009 -0800
17.3 @@ -21,7 +21,7 @@
17.4 #include "ns3/inet-socket-address.h"
17.5 #include "ns3/packet-socket-address.h"
17.6 #include "ns3/string.h"
17.7 -#include "ns3/object-names.h"
17.8 +#include "ns3/names.h"
17.9
17.10 namespace ns3 {
17.11
18.1 --- a/src/helper/packet-sink-helper.cc Wed Jan 21 00:28:47 2009 -0800
18.2 +++ b/src/helper/packet-sink-helper.cc Thu Jan 22 23:07:34 2009 -0800
18.3 @@ -21,7 +21,7 @@
18.4 #include "packet-sink-helper.h"
18.5 #include "ns3/string.h"
18.6 #include "ns3/inet-socket-address.h"
18.7 -#include "ns3/object-names.h"
18.8 +#include "ns3/names.h"
18.9
18.10 namespace ns3 {
18.11
19.1 --- a/src/helper/packet-socket-helper.cc Wed Jan 21 00:28:47 2009 -0800
19.2 +++ b/src/helper/packet-socket-helper.cc Thu Jan 22 23:07:34 2009 -0800
19.3 @@ -20,7 +20,7 @@
19.4
19.5 #include "packet-socket-helper.h"
19.6 #include "ns3/packet-socket-factory.h"
19.7 -#include "ns3/object-names.h"
19.8 +#include "ns3/names.h"
19.9
19.10 namespace ns3 {
19.11
20.1 --- a/src/helper/point-to-point-helper.cc Wed Jan 21 00:28:47 2009 -0800
20.2 +++ b/src/helper/point-to-point-helper.cc Thu Jan 22 23:07:34 2009 -0800
20.3 @@ -25,7 +25,7 @@
20.4 #include "ns3/pcap-writer.h"
20.5 #include "ns3/config.h"
20.6 #include "ns3/packet.h"
20.7 -#include "ns3/object-names.h"
20.8 +#include "ns3/names.h"
20.9
20.10 namespace ns3 {
20.11
21.1 --- a/src/helper/static-multicast-route-helper.cc Wed Jan 21 00:28:47 2009 -0800
21.2 +++ b/src/helper/static-multicast-route-helper.cc Thu Jan 22 23:07:34 2009 -0800
21.3 @@ -23,7 +23,7 @@
21.4 #include "ns3/assert.h"
21.5 #include "ns3/ipv4-address.h"
21.6 #include "ns3/ipv4.h"
21.7 -#include "ns3/object-names.h"
21.8 +#include "ns3/names.h"
21.9 #include "static-multicast-route-helper.h"
21.10
21.11 namespace ns3 {
22.1 --- a/src/helper/udp-echo-helper.cc Wed Jan 21 00:28:47 2009 -0800
22.2 +++ b/src/helper/udp-echo-helper.cc Thu Jan 22 23:07:34 2009 -0800
22.3 @@ -21,7 +21,7 @@
22.4 #include "ns3/udp-echo-server.h"
22.5 #include "ns3/udp-echo-client.h"
22.6 #include "ns3/uinteger.h"
22.7 -#include "ns3/object-names.h"
22.8 +#include "ns3/names.h"
22.9
22.10 namespace ns3 {
22.11
23.1 --- a/src/helper/v4ping-helper.cc Wed Jan 21 00:28:47 2009 -0800
23.2 +++ b/src/helper/v4ping-helper.cc Thu Jan 22 23:07:34 2009 -0800
23.3 @@ -20,7 +20,7 @@
23.4
23.5 #include "v4ping-helper.h"
23.6 #include "ns3/v4ping.h"
23.7 -#include "ns3/object-names.h"
23.8 +#include "ns3/names.h"
23.9
23.10 namespace ns3 {
23.11
24.1 --- a/src/helper/wifi-helper.cc Wed Jan 21 00:28:47 2009 -0800
24.2 +++ b/src/helper/wifi-helper.cc Thu Jan 22 23:07:34 2009 -0800
24.3 @@ -31,7 +31,7 @@
24.4 #include "ns3/pcap-writer.h"
24.5 #include "ns3/config.h"
24.6 #include "ns3/simulator.h"
24.7 -#include "ns3/object-names.h"
24.8 +#include "ns3/names.h"
24.9
24.10 NS_LOG_COMPONENT_DEFINE ("WifiHelper");
24.11
25.1 --- a/src/helper/yans-wifi-helper.cc Wed Jan 21 00:28:47 2009 -0800
25.2 +++ b/src/helper/yans-wifi-helper.cc Thu Jan 22 23:07:34 2009 -0800
25.3 @@ -27,7 +27,7 @@
25.4 #include "ns3/pcap-writer.h"
25.5 #include "ns3/simulator.h"
25.6 #include "ns3/config.h"
25.7 -#include "ns3/object-names.h"
25.8 +#include "ns3/names.h"
25.9
25.10 namespace ns3 {
25.11