A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
names.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#include "names.h"
19
20#include "abort.h"
21#include "assert.h"
22#include "log.h"
23#include "object.h"
24#include "singleton.h"
25
26#include <map>
27
28/**
29 * \file
30 * \ingroup config
31 * ns3::Names, ns3::NamesNode and ns3::NamePriv implementations.
32 */
33
34namespace ns3
35{
36
38
39/**
40 * \ingroup config
41 * Node in the naming tree.
42 */
44{
45 public:
46 /** Default constructor. */
47 NameNode();
48 /**
49 * Copy constructor.
50 *
51 * \param [in] nameNode The NameNode to copy from.
52 */
53 NameNode(const NameNode& nameNode);
54 /**
55 * Constructor.
56 *
57 * \param [in] parent The parent NameNode.
58 * \param [in] name The name of this NameNode
59 * \param [in] object The object corresponding to this NameNode.
60 */
61 NameNode(NameNode* parent, std::string name, Ptr<Object> object);
62 /**
63 * Assignment operator.
64 *
65 * \param [in] rhs The NameNode to copy from.
66 * \returns The lhs NameNode.
67 */
68 NameNode& operator=(const NameNode& rhs);
69
70 /** Destructor. */
71 ~NameNode();
72
73 /** The parent NameNode. */
75 /** The name of this NameNode. */
76 std::string m_name;
77 /** The object corresponding to this NameNode. */
79
80 /** Children of this NameNode. */
81 std::map<std::string, NameNode*> m_nameMap;
82};
83
85 : m_parent(nullptr),
86 m_name(""),
87 m_object(nullptr)
88{
89}
90
92{
93 m_parent = nameNode.m_parent;
94 m_name = nameNode.m_name;
95 m_object = nameNode.m_object;
96 m_nameMap = nameNode.m_nameMap;
97}
98
101{
102 m_parent = rhs.m_parent;
103 m_name = rhs.m_name;
104 m_object = rhs.m_object;
105 m_nameMap = rhs.m_nameMap;
106 return *this;
107}
108
109NameNode::NameNode(NameNode* parent, std::string name, Ptr<Object> object)
110 : m_parent(parent),
111 m_name(name),
112 m_object(object)
113{
114 NS_LOG_FUNCTION(this << parent << name << object);
115}
116
118{
119 NS_LOG_FUNCTION(this);
120}
121
122/**
123 * \ingroup config
124 * The singleton root Names object.
125 */
126class NamesPriv : public Singleton<NamesPriv>
127{
128 public:
129 /** Constructor. */
130 NamesPriv();
131 /** Destructor. */
132 ~NamesPriv() override;
133
134 // Doxygen \copydoc bug: won't copy these docs, so we repeat them.
135
136 /**
137 * Internal implementation for Names::Add(std::string,Ptr<Object>)
138 *
139 * \param [in] name The name of the object you want to associate;
140 * which may be prepended with a path to that object.
141 * \param [in] object A smart pointer to the object itself.
142 * \return \c true if the object was named successfully.
143 */
144 bool Add(std::string name, Ptr<Object> object);
145 /**
146 * Internal implementation for Names::Add(std::string,std::string,Ptr<Object>)
147 *
148 * \param [in] path A path name describing a previously named object
149 * under which you want this new name to be defined.
150 * \param [in] name The name of the object you want to associate.
151 * \param [in] object A smart pointer to the object itself.
152 * \return \c true if the object was named successfully.
153 */
154 bool Add(std::string path, std::string name, Ptr<Object> object);
155 /**
156 * Internal implementation for Names::Add(Ptr<Object>,std::string,Ptr<Object>)
157 *
158 * \param [in] context A smart pointer to an object that is used
159 * in place of the path under which you want this new
160 * name to be defined.
161 * \param [in] name The name of the object you want to associate.
162 * \param [in] object A smart pointer to the object itself.
163 * \return \c true if the object was named successfully.
164 */
165 bool Add(Ptr<Object> context, std::string name, Ptr<Object> object);
166
167 /**
168 * Internal implementation for Names::Rename(std::string,std::string)
169 *
170 * \param [in] oldpath The current path name to the object you want
171 * to change.
172 * \param [in] newname The new name of the object you want to change.
173 * \return \c true if the object was renamed successfully.
174 */
175 bool Rename(std::string oldpath, std::string newname);
176 /**
177 * Internal implementation for
178 * Names::Rename(std::string,std::string,std::string)
179 *
180 * \param [in] path A path name describing a previously named object
181 * under which you want this name change to occur
182 * (cf. directory).
183 * \param [in] oldname The currently defined name of the object.
184 * \param [in] newname The new name you want the object to have.
185 * \return \c true if the object was renamed successfully.
186 */
187 bool Rename(std::string path, std::string oldname, std::string newname);
188 /**
189 * Internal implementation for
190 * Names::Rename(Ptr<Object>,std::string,std::string)
191 *
192 * \param [in] context A smart pointer to an object that is used
193 * in place of the path under which you want this
194 * new name to be defined.
195 * \param [in] oldname The current shortname of the object you want
196 * to change.
197 * \param [in] newname The new shortname of the object you want
198 * to change.
199 * \return \c true if the object was renamed successfully.
200 */
201 bool Rename(Ptr<Object> context, std::string oldname, std::string newname);
202
203 /**
204 * Internal implementation for Names::FindName()
205 *
206 * \param [in] object A smart pointer to an object for which you want
207 * to find its name.
208 * \returns A string containing the name of the object if found,
209 * otherwise the empty string.
210 */
211 std::string FindName(Ptr<Object> object);
212 /**
213 * Internal implementation of Names::FindPath()
214 *
215 * \param [in] object A smart pointer to an object for which you
216 * want to find its fullname.
217 * \returns A string containing the name path of the object,
218 * otherwise the empty string.
219 */
220 std::string FindPath(Ptr<Object> object);
221
222 /**
223 * Internal implementation for Names::Clear()
224 */
225 void Clear();
226
227 /**
228 * Internal implementation for ns3::Names::Find(std::string)
229 *
230 * \param [in] path A string containing a name space path used
231 * to locate the object.
232 * \returns A smart pointer to the named object converted to
233 * the requested type.
234 */
235 Ptr<Object> Find(std::string path);
236 /**
237 * Internal implementation for ns3::Names::Find(std::string,std::string)
238 *
239 * \param [in] path A path name describing a previously named object
240 * under which you want to look for the specified name.
241 * \param [in] name A string containing a name to search for.
242 * \returns A smart pointer to the named object converted to
243 * the requested type.
244 */
245 Ptr<Object> Find(std::string path, std::string name);
246 /**
247 * Internal implementation for ns3::Names::Find(Ptr<Object>,std::string)
248 *
249 * \param [in] context A smart pointer to an object that is used
250 * in place of the path under which you want this
251 * new name to be defined.
252 * \param [in] name A string containing a name to search for.
253 * \returns A smart pointer to the named object converted to
254 * the requested type.
255 */
256 Ptr<Object> Find(Ptr<Object> context, std::string name);
257
258 private:
259 /**
260 * Check if an object has a name.
261 *
262 * \param [in] object The object to check.
263 * \returns The corresponding NameNode, if it exists.
264 */
266 /**
267 * Check if a name already exists as a child of a NameNode.
268 *
269 * \param [in] node The node to search.
270 * \param [in] name The name to search for.
271 * \returns \c true if \c name already exists as a child of \c node.
272 */
273 bool IsDuplicateName(NameNode* node, std::string name);
274
275 /** The root NameNode. */
277
278 /** Map from object pointers to their NameNodes. */
279 std::map<Ptr<Object>, NameNode*> m_objectMap;
280};
281
283{
284 NS_LOG_FUNCTION(this);
285
286 m_root.m_parent = nullptr;
287 m_root.m_name = "Names";
288 m_root.m_object = nullptr;
289}
290
292{
293 NS_LOG_FUNCTION(this);
294 Clear();
295 m_root.m_name = "";
296}
297
298void
300{
301 NS_LOG_FUNCTION(this);
302 //
303 // Every name is associated with an object in the object map, so freeing the
304 // NameNodes in this map will free all of the memory allocated for the NameNodes
305 //
306 for (auto i = m_objectMap.begin(); i != m_objectMap.end(); ++i)
307 {
308 delete i->second;
309 i->second = nullptr;
310 }
311
312 m_objectMap.clear();
313
314 m_root.m_parent = nullptr;
315 m_root.m_name = "Names";
316 m_root.m_object = nullptr;
317 m_root.m_nameMap.clear();
318}
319
320bool
321NamesPriv::Add(std::string name, Ptr<Object> object)
322{
323 NS_LOG_FUNCTION(this << name << object);
324 //
325 // This is the simple, easy to use version of Add, so we want it to be flexible.
326 // We don't want to force a user to always type the fully qualified namespace
327 // name, so we allow the namespace name to be omitted. For example, calling
328 // Add ("Client/ath0", obj) should result in exactly the same behavior as
329 // Add ("/Names/Client/ath0", obj). Calling Add ("Client", obj) should have
330 // the same effect as Add ("Names/Client", obj)
331 //
332 // The first thing to do, then, is to "canonicalize" the input string to always
333 // be a fully qualified name.
334 //
335 // If we are given a name that begins with "/Names/" we assume that this is a
336 // fully qualified path name to the object we want to create. We split the name
337 // into a path string and a final segment (name) and then call the "Real" Add.
338 //
339 std::string namespaceName = "/Names";
340 std::string::size_type offset = name.find(namespaceName);
341 if (offset != 0)
342 {
343 //
344 // This must be a name that has the "/Names" namespace prefix omitted.
345 // Do some reasonableness checking on the rest of the name.
346 //
347 offset = name.find('/');
348 if (offset == 0)
349 {
350 NS_ASSERT_MSG(false, "NamesPriv::Add(): Name begins with '/' but not \"/Names\"");
351 return false;
352 }
353
354 name = "/Names/" + name;
355 }
356
357 //
358 // There must now be a fully qualified path in the string. All fully
359 // qualified names begin with "/Names". We have to split off the final
360 // segment which will become the name of the object. A '/' that
361 // separates the path from the final segment had better be there since
362 // we just made sure that at least the namespace name was there.
363 //
364 std::string::size_type i = name.rfind('/');
365 NS_ASSERT_MSG(i != std::string::npos,
366 "NamesPriv::Add(): Internal error. Can't find '/' in name");
367
368 //
369 // The slash we found cannot be the slash at the start of the namespaceName.
370 // This would indicate there is no name in the path at all. It can be
371 // any other index.
372 //
373 NS_ASSERT_MSG(i != 0, "NamesPriv::Add(): Can't find a name in the path string");
374
375 //
376 // We now know where the path string starts and ends, and where the
377 // name starts and ends. All we have to do is to call our available
378 // function for adding a name under a path string.
379 //
380 return Add(name.substr(0, i), name.substr(i + 1), object);
381}
382
383bool
384NamesPriv::Add(std::string path, std::string name, Ptr<Object> object)
385{
386 NS_LOG_FUNCTION(this << path << name << object);
387 if (path == "/Names")
388 {
389 return Add(Ptr<Object>(nullptr, false), name, object);
390 }
391 return Add(Find(path), name, object);
392}
393
394bool
395NamesPriv::Add(Ptr<Object> context, std::string name, Ptr<Object> object)
396{
397 NS_LOG_FUNCTION(this << context << name << object);
398
399 if (IsNamed(object))
400 {
401 NS_LOG_LOGIC("Object is already named");
402 return false;
403 }
404
405 NameNode* node = nullptr;
406 if (context)
407 {
408 node = IsNamed(context);
409 NS_ASSERT_MSG(node, "NamesPriv::Name(): context must point to a previously named node");
410 }
411 else
412 {
413 node = &m_root;
414 }
415
416 if (IsDuplicateName(node, name))
417 {
418 NS_LOG_LOGIC("Name is already taken");
419 return false;
420 }
421
422 auto newNode = new NameNode(node, name, object);
423 node->m_nameMap[name] = newNode;
424 m_objectMap[object] = newNode;
425
426 return true;
427}
428
429bool
430NamesPriv::Rename(std::string oldpath, std::string newname)
431{
432 NS_LOG_FUNCTION(this << oldpath << newname);
433 //
434 // This is the simple, easy to use version of Rename, so we want it to be
435 // flexible. We don't want to force a user to always type the fully
436 // qualified namespace name, so we allow the namespace name to be omitted.
437 // For example, calling Rename ("Client/ath0", "eth0") should result in
438 // exactly the same behavior as Rename ("/Names/Client/ath0", "eth0").
439 // Calling Rename ("Client", "Router") should have the same effect as
440 // Rename ("Names/Client", "Router")
441 //
442 // The first thing to do, then, is to "canonicalize" the input string to always
443 // be a fully qualified path.
444 //
445 // If we are given a name that begins with "/Names/" we assume that this is a
446 // fully qualified path to the object we want to change. We split the path into
447 // path string (cf directory) and a final segment (cf filename) and then call
448 // the "Real" Rename.
449 //
450 std::string namespaceName = "/Names";
451 std::string::size_type offset = oldpath.find(namespaceName);
452 if (offset != 0)
453 {
454 //
455 // This must be a name that has the "/Names" namespace prefix omitted.
456 // Do some reasonableness checking on the rest of the name.
457 //
458 offset = oldpath.find('/');
459 if (offset == 0)
460 {
461 NS_ASSERT_MSG(false, "NamesPriv::Add(): Name begins with '/' but not \"/Names\"");
462 return false;
463 }
464
465 oldpath = "/Names/" + oldpath;
466 }
467
468 //
469 // There must now be a fully qualified path in the oldpath string. All
470 // fully qualified names begin with "/Names". We have to split off the final
471 // segment which will become the name we want to rename. A '/' that
472 // separates the path from the final segment (name) had better be there since
473 // we just made sure that at least the namespace name was there.
474 //
475 std::string::size_type i = oldpath.rfind('/');
476 NS_ASSERT_MSG(i != std::string::npos,
477 "NamesPriv::Add(): Internal error. Can't find '/' in name");
478
479 //
480 // The slash we found cannot be the slash at the start of the namespaceName.
481 // This would indicate there is no name in the path at all. It can be
482 // any other index.
483 //
484 NS_ASSERT_MSG(i != 0, "NamesPriv::Add(): Can't find a name in the path string");
485
486 //
487 // We now know where the path part of the string starts and ends, and where the
488 // name part starts and ends. All we have to do is to call our available
489 // function for creating adding a name under a path string.
490 //
491 return Rename(oldpath.substr(0, i), oldpath.substr(i + 1), newname);
492}
493
494bool
495NamesPriv::Rename(std::string path, std::string oldname, std::string newname)
496{
497 NS_LOG_FUNCTION(this << path << oldname << newname);
498 if (path == "/Names")
499 {
500 return Rename(Ptr<Object>(nullptr, false), oldname, newname);
501 }
502 return Rename(Find(path), oldname, newname);
503}
504
505bool
506NamesPriv::Rename(Ptr<Object> context, std::string oldname, std::string newname)
507{
508 NS_LOG_FUNCTION(this << context << oldname << newname);
509
510 NameNode* node = nullptr;
511 if (context)
512 {
513 node = IsNamed(context);
514 NS_ASSERT_MSG(node, "NamesPriv::Name(): context must point to a previously named node");
515 }
516 else
517 {
518 node = &m_root;
519 }
520
521 if (IsDuplicateName(node, newname))
522 {
523 NS_LOG_LOGIC("New name is already taken");
524 return false;
525 }
526
527 auto i = node->m_nameMap.find(oldname);
528 if (i == node->m_nameMap.end())
529 {
530 NS_LOG_LOGIC("Old name does not exist in name map");
531 return false;
532 }
533 else
534 {
535 NS_LOG_LOGIC("Old name exists in name map");
536
537 //
538 // The rename process consists of:
539 // 1. Getting the pointer to the name node from the map and remembering it;
540 // 2. Removing the map entry corresponding to oldname from the map;
541 // 3. Changing the name string in the name node;
542 // 4. Adding the name node back in the map under the newname.
543 //
544 NameNode* changeNode = i->second;
545 node->m_nameMap.erase(i);
546 changeNode->m_name = newname;
547 node->m_nameMap[newname] = changeNode;
548 return true;
549 }
550}
551
552std::string
554{
555 NS_LOG_FUNCTION(this << object);
556
557 auto i = m_objectMap.find(object);
558 if (i == m_objectMap.end())
559 {
560 NS_LOG_LOGIC("Object does not exist in object map");
561 return "";
562 }
563 else
564 {
565 NS_LOG_LOGIC("Object exists in object map");
566 return i->second->m_name;
567 }
568}
569
570std::string
572{
573 NS_LOG_FUNCTION(this << object);
574
575 auto i = m_objectMap.find(object);
576 if (i == m_objectMap.end())
577 {
578 NS_LOG_LOGIC("Object does not exist in object map");
579 return "";
580 }
581
582 NameNode* p = i->second;
584 "NamesPriv::FindFullName(): Internal error: Invalid NameNode pointer from map");
585
586 std::string path;
587
588 do
589 {
590 path = "/" + p->m_name + path;
591 NS_LOG_LOGIC("path is " << path);
592 } while ((p = p->m_parent) != nullptr);
593
594 return path;
595}
596
598NamesPriv::Find(std::string path)
599{
600 //
601 // This is hooked in from simple, easy to use version of Find, so we want it
602 // to be flexible.
603 //
604 // If we are provided a path that doesn't begin with "/Names", we assume
605 // that the caller has simply given us a path starting with a name that
606 // is in the root namespace. This allows people to omit the "/Names" prefix.
607 // and simply do a Find ("Client/eth0") instead of having to always do a
608 // Find ("/Names/Client/eth0");
609 //
610 // So, if we are given a name that begins with "/Names/" the upshot is that we
611 // just remove that prefix and treat the rest of the string as starting with a
612 // name in the root namespace.
613 //
614
615 NS_LOG_FUNCTION(this << path);
616 std::string namespaceName = "/Names/";
617 std::string remaining;
618
619 std::string::size_type offset = path.find(namespaceName);
620 if (offset == 0)
621 {
622 NS_LOG_LOGIC(path << " is a fully qualified name");
623 remaining = path.substr(namespaceName.size());
624 }
625 else
626 {
627 NS_LOG_LOGIC(path << " begins with a relative name");
628 remaining = path;
629 }
630
631 NameNode* node = &m_root;
632
633 //
634 // The string <remaining> is now composed entirely of path segments in
635 // the /Names name space and we have eaten the leading slash. e.g.,
636 // remaining = "ClientNode/eth0"
637 //
638 // The start of the search is always at the root of the name space.
639 //
640 for (;;)
641 {
642 NS_LOG_LOGIC("Looking for the object of name " << remaining);
643 offset = remaining.find('/');
644 if (offset == std::string::npos)
645 {
646 //
647 // There are no remaining slashes so this is the last segment of the
648 // specified name. We're done when we find it
649 //
650 auto i = node->m_nameMap.find(remaining);
651 if (i == node->m_nameMap.end())
652 {
653 NS_LOG_LOGIC("Name does not exist in name map");
654 return nullptr;
655 }
656 else
657 {
658 NS_LOG_LOGIC("Name parsed, found object");
659 return i->second->m_object;
660 }
661 }
662 else
663 {
664 //
665 // There are more slashes so this is an intermediate segment of the
666 // specified name. We need to "recurse" when we find this segment.
667 //
668 offset = remaining.find('/');
669 std::string segment = remaining.substr(0, offset);
670
671 auto i = node->m_nameMap.find(segment);
672 if (i == node->m_nameMap.end())
673 {
674 NS_LOG_LOGIC("Name does not exist in name map");
675 return nullptr;
676 }
677 else
678 {
679 node = i->second;
680 remaining = remaining.substr(offset + 1);
681 NS_LOG_LOGIC("Intermediate segment parsed");
682 continue;
683 }
684 }
685 }
686
687 NS_ASSERT_MSG(node, "NamesPriv::Find(): Internal error: this can't happen");
688 return nullptr;
689}
690
692NamesPriv::Find(std::string path, std::string name)
693{
694 NS_LOG_FUNCTION(this << path << name);
695
696 if (path == "/Names")
697 {
698 return Find(Ptr<Object>(nullptr, false), name);
699 }
700 return Find(Find(path), name);
701}
702
704NamesPriv::Find(Ptr<Object> context, std::string name)
705{
706 NS_LOG_FUNCTION(this << context << name);
707
708 NameNode* node = nullptr;
709
710 if (!context)
711 {
712 NS_LOG_LOGIC("Zero context implies root NameNode");
713 node = &m_root;
714 }
715 else
716 {
717 node = IsNamed(context);
718 if (node == nullptr)
719 {
720 NS_LOG_LOGIC("Context does not point to a previously named node");
721 return nullptr;
722 }
723 }
724
725 auto i = node->m_nameMap.find(name);
726 if (i == node->m_nameMap.end())
727 {
728 NS_LOG_LOGIC("Name does not exist in name map");
729 return nullptr;
730 }
731 else
732 {
733 NS_LOG_LOGIC("Name exists in name map");
734 return i->second->m_object;
735 }
736}
737
740{
741 NS_LOG_FUNCTION(this << object);
742
743 auto i = m_objectMap.find(object);
744 if (i == m_objectMap.end())
745 {
746 NS_LOG_LOGIC("Object does not exist in object map, returning NameNode 0");
747 return nullptr;
748 }
749 else
750 {
751 NS_LOG_LOGIC("Object exists in object map, returning NameNode " << &i->second);
752 return i->second;
753 }
754}
755
756bool
757NamesPriv::IsDuplicateName(NameNode* node, std::string name)
758{
759 NS_LOG_FUNCTION(this << node << name);
760
761 auto i = node->m_nameMap.find(name);
762 if (i == node->m_nameMap.end())
763 {
764 NS_LOG_LOGIC("Name does not exist in name map");
765 return false;
766 }
767 else
768 {
769 NS_LOG_LOGIC("Name exists in name map");
770 return true;
771 }
772}
773
774void
775Names::Add(std::string name, Ptr<Object> object)
776{
777 NS_LOG_FUNCTION(name << object);
778 bool result = NamesPriv::Get()->Add(name, object);
779 NS_ABORT_MSG_UNLESS(result, "Names::Add(): Error adding name " << name);
780}
781
782void
783Names::Rename(std::string oldpath, std::string newname)
784{
785 NS_LOG_FUNCTION(oldpath << newname);
786 bool result = NamesPriv::Get()->Rename(oldpath, newname);
787 NS_ABORT_MSG_UNLESS(result, "Names::Rename(): Error renaming " << oldpath << " to " << newname);
788}
789
790void
791Names::Add(std::string path, std::string name, Ptr<Object> object)
792{
793 NS_LOG_FUNCTION(path << name << object);
794 bool result = NamesPriv::Get()->Add(path, name, object);
795 NS_ABORT_MSG_UNLESS(result, "Names::Add(): Error adding " << path << " " << name);
796}
797
798void
799Names::Rename(std::string path, std::string oldname, std::string newname)
800{
801 NS_LOG_FUNCTION(path << oldname << newname);
802 bool result = NamesPriv::Get()->Rename(path, oldname, newname);
803 NS_ABORT_MSG_UNLESS(result,
804 "Names::Rename (): Error renaming " << path << " " << oldname << " to "
805 << newname);
806}
807
808void
809Names::Add(Ptr<Object> context, std::string name, Ptr<Object> object)
810{
811 NS_LOG_FUNCTION(context << name << object);
812 bool result = NamesPriv::Get()->Add(context, name, object);
813 NS_ABORT_MSG_UNLESS(result,
814 "Names::Add(): Error adding name " << name << " under context "
815 << &context);
816}
817
818void
819Names::Rename(Ptr<Object> context, std::string oldname, std::string newname)
820{
821 NS_LOG_FUNCTION(context << oldname << newname);
822 bool result = NamesPriv::Get()->Rename(context, oldname, newname);
823 NS_ABORT_MSG_UNLESS(result,
824 "Names::Rename (): Error renaming " << oldname << " to " << newname
825 << " under context " << &context);
826}
827
828std::string
830{
831 NS_LOG_FUNCTION(object);
832 return NamesPriv::Get()->FindName(object);
833}
834
835std::string
837{
838 NS_LOG_FUNCTION(object);
839 return NamesPriv::Get()->FindPath(object);
840}
841
842void
844{
846 return NamesPriv::Get()->Clear();
847}
848
850Names::FindInternal(std::string name)
851{
852 NS_LOG_FUNCTION(name);
853 return NamesPriv::Get()->Find(name);
854}
855
857Names::FindInternal(std::string path, std::string name)
858{
859 NS_LOG_FUNCTION(path << name);
860 return NamesPriv::Get()->Find(path, name);
861}
862
864Names::FindInternal(Ptr<Object> context, std::string name)
865{
866 NS_LOG_FUNCTION(context << name);
867 return NamesPriv::Get()->Find(context, name);
868}
869
870} // namespace ns3
NS_ABORT_x macro definitions.
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
Node in the naming tree.
Definition: names.cc:44
NameNode * m_parent
The parent NameNode.
Definition: names.cc:74
~NameNode()
Destructor.
Definition: names.cc:117
NameNode()
Default constructor.
Definition: names.cc:84
Ptr< Object > m_object
The object corresponding to this NameNode.
Definition: names.cc:78
std::map< std::string, NameNode * > m_nameMap
Children of this NameNode.
Definition: names.cc:81
NameNode & operator=(const NameNode &rhs)
Assignment operator.
Definition: names.cc:100
std::string m_name
The name of this NameNode.
Definition: names.cc:76
static void Rename(std::string oldpath, std::string newname)
Rename a previously associated name.
Definition: names.cc:783
static Ptr< Object > FindInternal(std::string path)
Non-templated internal version of Names::Find.
Definition: names.cc:850
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition: names.cc:775
static void Clear()
Clear the list of objects associated with names.
Definition: names.cc:843
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition: names.cc:829
static std::string FindPath(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and return the...
Definition: names.cc:836
The singleton root Names object.
Definition: names.cc:127
bool Add(std::string name, Ptr< Object > object)
Internal implementation for Names::Add(std::string,Ptr<Object>)
Definition: names.cc:321
NameNode m_root
The root NameNode.
Definition: names.cc:276
bool IsDuplicateName(NameNode *node, std::string name)
Check if a name already exists as a child of a NameNode.
Definition: names.cc:757
std::string FindPath(Ptr< Object > object)
Internal implementation of Names::FindPath()
Definition: names.cc:571
bool Rename(std::string oldpath, std::string newname)
Internal implementation for Names::Rename(std::string,std::string)
Definition: names.cc:430
std::string FindName(Ptr< Object > object)
Internal implementation for Names::FindName()
Definition: names.cc:553
~NamesPriv() override
Destructor.
Definition: names.cc:291
NameNode * IsNamed(Ptr< Object > object)
Check if an object has a name.
Definition: names.cc:739
std::map< Ptr< Object >, NameNode * > m_objectMap
Map from object pointers to their NameNodes.
Definition: names.cc:279
NamesPriv()
Constructor.
Definition: names.cc:282
Ptr< Object > Find(std::string path)
Internal implementation for ns3::Names::Find(std::string)
Definition: names.cc:598
void Clear()
Internal implementation for Names::Clear()
Definition: names.cc:299
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
A template singleton.
Definition: singleton.h:68
static NamesPriv * Get()
Get a pointer to the singleton instance.
Definition: singleton.h:107
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Debug message logging.
Declaration of class ns3::Names.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::Object class declaration, which is the root of the Object hierarchy and Aggregation.
ns3::Singleton declaration and template implementation.