A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
config.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8#include "config.h"
9
10#include "global-value.h"
11#include "log.h"
12#include "names.h"
14#include "object.h"
15#include "pointer.h"
16#include "singleton.h"
17
18#include <sstream>
19
20/**
21 * @file
22 * @ingroup config-impl
23 * ns3::Config implementations.
24 */
25
26/**
27 * @defgroup config-impl Config implementations
28 * @ingroup config
29 */
30namespace ns3
31{
32
34
35namespace Config
36{
37
42
43MatchContainer::MatchContainer(const std::vector<Ptr<Object>>& objects,
44 const std::vector<std::string>& contexts,
45 std::string path)
46 : m_objects(objects),
47 m_contexts(contexts),
48 m_path(path)
49{
50 NS_LOG_FUNCTION(this << &objects << &contexts << path);
51}
52
55{
56 NS_LOG_FUNCTION(this);
57 return m_objects.begin();
58}
59
62{
63 NS_LOG_FUNCTION(this);
64 return m_objects.end();
65}
66
67std::size_t
69{
70 NS_LOG_FUNCTION(this);
71 return m_objects.size();
72}
73
75MatchContainer::Get(std::size_t i) const
76{
77 NS_LOG_FUNCTION(this << i);
78 return m_objects[i];
79}
80
81std::string
83{
84 NS_LOG_FUNCTION(this << i);
85 return m_contexts[i];
86}
87
88std::string
90{
91 NS_LOG_FUNCTION(this);
92 return m_path;
93}
94
95void
96MatchContainer::Set(std::string name, const AttributeValue& value)
97{
98 NS_LOG_FUNCTION(this << name << &value);
99 for (auto tmp = Begin(); tmp != End(); ++tmp)
100 {
101 Ptr<Object> object = *tmp;
102 // Let ObjectBase::SetAttribute raise any errors
103 object->SetAttribute(name, value);
104 }
105}
106
107bool
108MatchContainer::SetFailSafe(std::string name, const AttributeValue& value)
109{
110 NS_LOG_FUNCTION(this << name << &value);
111 bool ok = false;
112 for (auto tmp = Begin(); tmp != End(); ++tmp)
113 {
114 Ptr<Object> object = *tmp;
115 ok |= object->SetAttributeFailSafe(name, value);
116 }
117 return ok;
118}
119
120void
121MatchContainer::Connect(std::string name, const CallbackBase& cb)
122{
123 if (!ConnectFailSafe(name, cb))
124 {
125 NS_FATAL_ERROR("Could not connect callback to " << name);
126 }
127}
128
129bool
131{
132 NS_LOG_FUNCTION(this << name << &cb);
133 NS_ASSERT(m_objects.size() == m_contexts.size());
134 bool ok = false;
135 for (uint32_t i = 0; i < m_objects.size(); ++i)
136 {
137 Ptr<Object> object = m_objects[i];
138 std::string ctx = m_contexts[i] + name;
139 ok |= object->TraceConnect(name, ctx, cb);
140 }
141 return ok;
142}
143
144void
146{
147 if (!ConnectWithoutContextFailSafe(name, cb))
148 {
149 NS_FATAL_ERROR("Could not connect callback to " << name);
150 }
151}
152
153bool
155{
156 NS_LOG_FUNCTION(this << name << &cb);
157 bool ok = false;
158 for (auto tmp = Begin(); tmp != End(); ++tmp)
159 {
160 Ptr<Object> object = *tmp;
161 ok |= object->TraceConnectWithoutContext(name, cb);
162 }
163 return ok;
164}
165
166void
167MatchContainer::Disconnect(std::string name, const CallbackBase& cb)
168{
169 NS_LOG_FUNCTION(this << name << &cb);
170 NS_ASSERT(m_objects.size() == m_contexts.size());
171 for (uint32_t i = 0; i < m_objects.size(); ++i)
172 {
173 Ptr<Object> object = m_objects[i];
174 std::string ctx = m_contexts[i] + name;
175 object->TraceDisconnect(name, ctx, cb);
176 }
177}
178
179void
181{
182 NS_LOG_FUNCTION(this << name << &cb);
183 for (auto tmp = Begin(); tmp != End(); ++tmp)
184 {
185 Ptr<Object> object = *tmp;
186 object->TraceDisconnectWithoutContext(name, cb);
187 }
188}
189
190/**
191 * @ingroup config-impl
192 * Helper to test if an array entry matches a config path specification.
193 */
195{
196 public:
197 /**
198 * Construct from a Config path specification.
199 *
200 * @param [in] element The Config path specification.
201 */
202 ArrayMatcher(std::string element);
203 /**
204 * Test if a specific index matches the Config Path.
205 *
206 * @param [in] i The index.
207 * @returns \c true if the index matches the Config Path.
208 */
209 bool Matches(std::size_t i) const;
210
211 private:
212 /**
213 * Convert a string to an \c uint32_t.
214 *
215 * @param [in] str The string.
216 * @param [in] value The location to store the \c uint32_t.
217 * @returns \c true if the string could be converted.
218 */
219 bool StringToUint32(std::string str, uint32_t* value) const;
220 /** The Config path element. */
221 std::string m_element;
222
223 // end of class ArrayMatcher
224};
225
226ArrayMatcher::ArrayMatcher(std::string element)
227 : m_element(element)
228{
229 NS_LOG_FUNCTION(this << element);
230}
231
232bool
233ArrayMatcher::Matches(std::size_t i) const
234{
235 NS_LOG_FUNCTION(this << i);
236 if (m_element == "*")
237 {
238 NS_LOG_DEBUG("Array " << i << " matches *");
239 return true;
240 }
241 std::string::size_type tmp;
242 tmp = m_element.find('|');
243 if (tmp != std::string::npos)
244 {
245 std::string left = m_element.substr(0, tmp - 0);
246 std::string right = m_element.substr(tmp + 1, m_element.size() - (tmp + 1));
247 ArrayMatcher matcher = ArrayMatcher(left);
248 if (matcher.Matches(i))
249 {
250 NS_LOG_DEBUG("Array " << i << " matches " << left);
251 return true;
252 }
253 matcher = ArrayMatcher(right);
254 if (matcher.Matches(i))
255 {
256 NS_LOG_DEBUG("Array " << i << " matches " << right);
257 return true;
258 }
259 NS_LOG_DEBUG("Array " << i << " does not match " << m_element);
260 return false;
261 }
262 std::string::size_type leftBracket = m_element.find('[');
263 std::string::size_type rightBracket = m_element.find(']');
264 std::string::size_type dash = m_element.find('-');
265 if (leftBracket == 0 && rightBracket == m_element.size() - 1 && dash > leftBracket &&
266 dash < rightBracket)
267 {
268 std::string lowerBound = m_element.substr(leftBracket + 1, dash - (leftBracket + 1));
269 std::string upperBound = m_element.substr(dash + 1, rightBracket - (dash + 1));
270 uint32_t min;
271 uint32_t max;
272 if (StringToUint32(lowerBound, &min) && StringToUint32(upperBound, &max) && i >= min &&
273 i <= max)
274 {
275 NS_LOG_DEBUG("Array " << i << " matches " << m_element);
276 return true;
277 }
278 else
279 {
280 NS_LOG_DEBUG("Array " << i << " does not " << m_element);
281 return false;
282 }
283 }
284 uint32_t value;
285 if (StringToUint32(m_element, &value) && i == value)
286 {
287 NS_LOG_DEBUG("Array " << i << " matches " << m_element);
288 return true;
289 }
290 NS_LOG_DEBUG("Array " << i << " does not match " << m_element);
291 return false;
292}
293
294bool
295ArrayMatcher::StringToUint32(std::string str, uint32_t* value) const
296{
297 NS_LOG_FUNCTION(this << str << value);
298 std::istringstream iss;
299 iss.str(str);
300 iss >> (*value);
301 return !iss.bad() && !iss.fail();
302}
303
304/**
305 * @ingroup config-impl
306 * Abstract class to parse Config paths into object references.
307 */
309{
310 public:
311 /**
312 * Construct from a base Config path.
313 *
314 * @param [in] path The Config path.
315 */
316 Resolver(std::string path);
317 /** Destructor. */
318 virtual ~Resolver();
319
320 /**
321 * Parse the stored Config path into an object reference,
322 * beginning at the indicated root object.
323 *
324 * @param [in] root The object corresponding to the current position in
325 * in the Config path.
326 */
327 void Resolve(Ptr<Object> root);
328
329 private:
330 /** Ensure the Config path starts and ends with a '/'. */
331 void Canonicalize();
332 /**
333 * Parse the next element in the Config path.
334 *
335 * @param [in] path The remaining portion of the Config path.
336 * @param [in] root The object corresponding to the current position
337 * in the Config path.
338 */
339 void DoResolve(std::string path, Ptr<Object> root);
340 /**
341 * Parse an index on the Config path.
342 *
343 * @param [in] path The remaining Config path.
344 * @param [in,out] vector The resulting list of matching objects.
345 */
346 void DoArrayResolve(std::string path, const ObjectPtrContainerValue& vector);
347 /**
348 * Handle one object found on the path.
349 *
350 * @param [in] object The current object on the Config path.
351 */
352 void DoResolveOne(Ptr<Object> object);
353 /**
354 * Get the current Config path.
355 *
356 * @returns The current Config path.
357 */
358 std::string GetResolvedPath() const;
359 /**
360 * Handle one found object.
361 *
362 * @param [in] object The found object.
363 * @param [in] path The matching Config path context.
364 */
365 virtual void DoOne(Ptr<Object> object, std::string path) = 0;
366
367 /** Current list of path tokens. */
368 std::vector<std::string> m_workStack;
369 /** The Config path. */
370 std::string m_path;
371
372 // end of class Resolver
373};
374
375Resolver::Resolver(std::string path)
376 : m_path(path)
377{
378 NS_LOG_FUNCTION(this << path);
379 Canonicalize();
380}
381
386
387void
389{
390 NS_LOG_FUNCTION(this);
391
392 // ensure that we start and end with a '/'
393 std::string::size_type tmp = m_path.find('/');
394 if (tmp != 0)
395 {
396 // no slash at start
397 m_path = "/" + m_path;
398 }
399 tmp = m_path.find_last_of('/');
400 if (tmp != (m_path.size() - 1))
401 {
402 // no slash at end
403 m_path = m_path + "/";
404 }
405}
406
407void
409{
410 NS_LOG_FUNCTION(this << root);
411
412 DoResolve(m_path, root);
413}
414
415std::string
417{
418 NS_LOG_FUNCTION(this);
419
420 std::string fullPath = "/";
421 for (auto i = m_workStack.begin(); i != m_workStack.end(); i++)
422 {
423 fullPath += *i + "/";
424 }
425 return fullPath;
426}
427
428void
430{
431 NS_LOG_FUNCTION(this << object);
432
433 NS_LOG_DEBUG("resolved=" << GetResolvedPath());
434 DoOne(object, GetResolvedPath());
435}
436
437void
438Resolver::DoResolve(std::string path, Ptr<Object> root)
439{
440 NS_LOG_FUNCTION(this << path << root);
441 NS_ASSERT((path.find('/')) == 0);
442 std::string::size_type next = path.find('/', 1);
443
444 if (next == std::string::npos)
445 {
446 //
447 // If root is zero, we're beginning to see if we can use the object name
448 // service to resolve this path. It is impossible to have a object name
449 // associated with the root of the object name service since that root
450 // is not an object. This path must be referring to something in another
451 // namespace and it will have been found already since the name service
452 // is always consulted last.
453 //
454 if (root)
455 {
456 DoResolveOne(root);
457 }
458 return;
459 }
460 std::string item = path.substr(1, next - 1);
461 std::string pathLeft = path.substr(next, path.size() - next);
462
463 //
464 // If root is zero, we're beginning to see if we can use the object name
465 // service to resolve this path. In this case, we must see the name space
466 // "/Names" on the front of this path. There is no object associated with
467 // the root of the "/Names" namespace, so we just ignore it and move on to
468 // the next segment.
469 //
470 if (!root)
471 {
472 std::string::size_type offset = path.find("/Names");
473 if (offset == 0)
474 {
475 m_workStack.push_back(item);
476 DoResolve(pathLeft, root);
477 m_workStack.pop_back();
478 return;
479 }
480 }
481
482 //
483 // We have an item (possibly a segment of a namespace path. Check to see if
484 // we can determine that this segment refers to a named object. If root is
485 // zero, this means to look in the root of the "/Names" name space, otherwise
486 // it refers to a name space context (level).
487 //
488 Ptr<Object> namedObject = Names::Find<Object>(root, item);
489 if (namedObject)
490 {
491 NS_LOG_DEBUG("Name system resolved item = " << item << " to " << namedObject);
492 m_workStack.push_back(item);
493 DoResolve(pathLeft, namedObject);
494 m_workStack.pop_back();
495 return;
496 }
497
498 //
499 // We're done with the object name service hooks, so proceed down the path
500 // of types and attributes; but only if root is nonzero. If root is zero
501 // and we find ourselves here, we are trying to check in the namespace for
502 // a path that is not in the "/Names" namespace. We will have previously
503 // found any matches, so we just bail out.
504 //
505 if (!root)
506 {
507 return;
508 }
509 std::string::size_type dollarPos = item.find('$');
510 if (dollarPos == 0)
511 {
512 // This is a call to GetObject
513 std::string tidString = item.substr(1, item.size() - 1);
514 NS_LOG_DEBUG("GetObject=" << tidString << " on path=" << GetResolvedPath());
515 TypeId tid = TypeId::LookupByName(tidString);
516 Ptr<Object> object = root->GetObject<Object>(tid);
517 if (!object)
518 {
519 NS_LOG_DEBUG("GetObject (" << tidString << ") failed on path=" << GetResolvedPath());
520 return;
521 }
522 m_workStack.push_back(item);
523 DoResolve(pathLeft, object);
524 m_workStack.pop_back();
525 }
526 else
527 {
528 // this is a normal attribute.
529 TypeId tid;
530 TypeId nextTid = root->GetInstanceTypeId();
531 bool foundMatch = false;
532
533 do
534 {
535 tid = nextTid;
536
537 for (uint32_t i = 0; i < tid.GetAttributeN(); i++)
538 {
540 info = tid.GetAttribute(i);
541 if (info.name != item && item != "*")
542 {
543 continue;
544 }
545 // attempt to cast to a pointer checker.
546 const auto pChecker =
547 dynamic_cast<const PointerChecker*>(PeekPointer(info.checker));
548 if (pChecker != nullptr)
549 {
550 NS_LOG_DEBUG("GetAttribute(ptr)=" << info.name
551 << " on path=" << GetResolvedPath());
552 PointerValue pValue;
553 root->GetAttribute(info.name, pValue);
554 Ptr<Object> object = pValue.Get<Object>();
555 if (!object)
556 {
557 NS_LOG_ERROR("Requested object name=\"" << item << "\" exists on path=\""
558 << GetResolvedPath()
559 << "\""
560 " but is null.");
561 continue;
562 }
563 foundMatch = true;
564 m_workStack.push_back(info.name);
565 DoResolve(pathLeft, object);
566 m_workStack.pop_back();
567 }
568 // attempt to cast to an object vector.
569 const auto vectorChecker =
570 dynamic_cast<const ObjectPtrContainerChecker*>(PeekPointer(info.checker));
571 if (vectorChecker != nullptr)
572 {
573 NS_LOG_DEBUG("GetAttribute(vector)=" << info.name << " on path="
574 << GetResolvedPath() << pathLeft);
575 foundMatch = true;
577 root->GetAttribute(info.name, vector);
578 m_workStack.push_back(info.name);
579 DoArrayResolve(pathLeft, vector);
580 m_workStack.pop_back();
581 }
582 // this could be anything else and we don't know what to do with it.
583 // So, we just ignore it.
584 }
585
586 nextTid = tid.GetParent();
587 } while (nextTid != tid);
588
589 if (!foundMatch)
590 {
591 NS_LOG_DEBUG("Requested item=" << item
592 << " does not exist on path=" << GetResolvedPath());
593 return;
594 }
595 }
596}
597
598void
599Resolver::DoArrayResolve(std::string path, const ObjectPtrContainerValue& container)
600{
601 NS_LOG_FUNCTION(this << path << &container);
602 NS_ASSERT(!path.empty());
603 NS_ASSERT((path.find('/')) == 0);
604 std::string::size_type next = path.find('/', 1);
605 if (next == std::string::npos)
606 {
607 return;
608 }
609 std::string item = path.substr(1, next - 1);
610 std::string pathLeft = path.substr(next, path.size() - next);
611
612 ArrayMatcher matcher = ArrayMatcher(item);
614 for (it = container.Begin(); it != container.End(); ++it)
615 {
616 if (matcher.Matches((*it).first))
617 {
618 std::ostringstream oss;
619 oss << (*it).first;
620 m_workStack.push_back(oss.str());
621 DoResolve(pathLeft, (*it).second);
622 m_workStack.pop_back();
623 }
624 }
625}
626
627/**
628 * @ingroup config-impl
629 * Config system implementation class.
630 */
631class ConfigImpl : public Singleton<ConfigImpl>
632{
633 public:
634 // Keep Set and SetFailSafe since their errors are triggered
635 // by the underlying ObjectBase functions.
636 /** @copydoc ns3::Config::Set() */
637 void Set(std::string path, const AttributeValue& value);
638 /** @copydoc ns3::Config::SetFailSafe() */
639 bool SetFailSafe(std::string path, const AttributeValue& value);
640 /** @copydoc ns3::Config::ConnectWithoutContextFailSafe() */
641 bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase& cb);
642 /** @copydoc ns3::Config::ConnectFailSafe() */
643 bool ConnectFailSafe(std::string path, const CallbackBase& cb);
644 /** @copydoc ns3::Config::DisconnectWithoutContext() */
645 void DisconnectWithoutContext(std::string path, const CallbackBase& cb);
646 /** @copydoc ns3::Config::Disconnect() */
647 void Disconnect(std::string path, const CallbackBase& cb);
648 /** @copydoc ns3::Config::LookupMatches() */
649 MatchContainer LookupMatches(std::string path);
650
651 /** @copydoc ns3::Config::RegisterRootNamespaceObject() */
653 /** @copydoc ns3::Config::UnregisterRootNamespaceObject() */
655
656 /** @copydoc ns3::Config::GetRootNamespaceObjectN() */
657 std::size_t GetRootNamespaceObjectN() const;
658 /** @copydoc ns3::Config::GetRootNamespaceObject() */
659 Ptr<Object> GetRootNamespaceObject(std::size_t i) const;
660
661 private:
662 /**
663 * Break a Config path into the leading path and the last leaf token.
664 * @param [in] path The Config path.
665 * @param [in,out] root The leading part of the \pname{path},
666 * up to the final slash.
667 * @param [in,out] leaf The trailing part of the \pname{path}.
668 */
669 void ParsePath(std::string path, std::string* root, std::string* leaf) const;
670
671 /** Container type to hold the root Config path tokens. */
672 typedef std::vector<Ptr<Object>> Roots;
673
674 /** The list of Config path roots. */
676
677 // end of class ConfigImpl
678};
679
680void
681ConfigImpl::ParsePath(std::string path, std::string* root, std::string* leaf) const
682{
683 NS_LOG_FUNCTION(this << path << root << leaf);
684
685 std::string::size_type slash = path.find_last_of('/');
686 NS_ASSERT(slash != std::string::npos);
687 *root = path.substr(0, slash);
688 *leaf = path.substr(slash + 1, path.size() - (slash + 1));
689 NS_LOG_FUNCTION(path << *root << *leaf);
690}
691
692void
693ConfigImpl::Set(std::string path, const AttributeValue& value)
694{
695 NS_LOG_FUNCTION(this << path << &value);
696
697 std::string root;
698 std::string leaf;
699 ParsePath(path, &root, &leaf);
700 MatchContainer container = LookupMatches(root);
701 container.Set(leaf, value);
702}
703
704bool
705ConfigImpl::SetFailSafe(std::string path, const AttributeValue& value)
706{
707 NS_LOG_FUNCTION(this << path << &value);
708
709 std::string root;
710 std::string leaf;
711 ParsePath(path, &root, &leaf);
712 MatchContainer container = LookupMatches(root);
713 return container.SetFailSafe(leaf, value);
714}
715
716bool
718{
719 NS_LOG_FUNCTION(this << path << &cb);
720 std::string root;
721 std::string leaf;
722 ParsePath(path, &root, &leaf);
723 MatchContainer container = LookupMatches(root);
724 return container.ConnectWithoutContextFailSafe(leaf, cb);
725}
726
727void
729{
730 NS_LOG_FUNCTION(this << path << &cb);
731 std::string root;
732 std::string leaf;
733 ParsePath(path, &root, &leaf);
734 MatchContainer container = LookupMatches(root);
735 if (container.GetN() == 0)
736 {
737 std::size_t lastFwdSlash = root.rfind('/');
738 NS_LOG_WARN("Failed to disconnect "
739 << leaf << ", the Requested object name = " << root.substr(lastFwdSlash + 1)
740 << " does not exits on path " << root.substr(0, lastFwdSlash));
741 }
742 container.DisconnectWithoutContext(leaf, cb);
743}
744
745bool
746ConfigImpl::ConnectFailSafe(std::string path, const CallbackBase& cb)
747{
748 NS_LOG_FUNCTION(this << path << &cb);
749
750 std::string root;
751 std::string leaf;
752 ParsePath(path, &root, &leaf);
753 MatchContainer container = LookupMatches(root);
754 return container.ConnectFailSafe(leaf, cb);
755}
756
757void
758ConfigImpl::Disconnect(std::string path, const CallbackBase& cb)
759{
760 NS_LOG_FUNCTION(this << path << &cb);
761
762 std::string root;
763 std::string leaf;
764 ParsePath(path, &root, &leaf);
765 MatchContainer container = LookupMatches(root);
766 if (container.GetN() == 0)
767 {
768 std::size_t lastFwdSlash = root.rfind('/');
769 NS_LOG_WARN("Failed to disconnect "
770 << leaf << ", the Requested object name = " << root.substr(lastFwdSlash + 1)
771 << " does not exits on path " << root.substr(0, lastFwdSlash));
772 }
773 container.Disconnect(leaf, cb);
774}
775
778{
779 NS_LOG_FUNCTION(this << path);
780
781 class LookupMatchesResolver : public Resolver
782 {
783 public:
784 LookupMatchesResolver(std::string path)
785 : Resolver(path)
786 {
787 }
788
789 void DoOne(Ptr<Object> object, std::string path) override
790 {
791 m_objects.push_back(object);
792 m_contexts.push_back(path);
793 }
794
795 std::vector<Ptr<Object>> m_objects;
796 std::vector<std::string> m_contexts;
797 } resolver = LookupMatchesResolver(path);
798
799 for (auto i = m_roots.begin(); i != m_roots.end(); i++)
800 {
801 resolver.Resolve(*i);
802 }
803
804 //
805 // See if we can do something with the object name service. Starting with
806 // the root pointer zeroed indicates to the resolver that it should start
807 // looking at the root of the "/Names" namespace during this go.
808 //
809 resolver.Resolve(nullptr);
810
811 return MatchContainer(resolver.m_objects, resolver.m_contexts, path);
812}
813
814void
816{
817 NS_LOG_FUNCTION(this << obj);
818 m_roots.push_back(obj);
819}
820
821void
823{
824 NS_LOG_FUNCTION(this << obj);
825
826 for (auto i = m_roots.begin(); i != m_roots.end(); i++)
827 {
828 if (*i == obj)
829 {
830 m_roots.erase(i);
831 return;
832 }
833 }
834}
835
836std::size_t
838{
839 NS_LOG_FUNCTION(this);
840 return m_roots.size();
841}
842
845{
846 NS_LOG_FUNCTION(this << i);
847 return m_roots[i];
848}
849
850void
852{
854 // First, let's reset the initial value of every attribute
855 for (uint16_t i = 0; i < TypeId::GetRegisteredN(); i++)
856 {
858 for (uint32_t j = 0; j < tid.GetAttributeN(); j++)
859 {
862 }
863 }
864 // now, let's reset the initial value of every global value.
865 for (auto i = GlobalValue::Begin(); i != GlobalValue::End(); ++i)
866 {
867 (*i)->ResetInitialValue();
868 }
869}
870
871void
872Set(std::string path, const AttributeValue& value)
873{
874 NS_LOG_FUNCTION(path << &value);
875 ConfigImpl::Get()->Set(path, value);
876}
877
878bool
879SetFailSafe(std::string path, const AttributeValue& value)
880{
881 NS_LOG_FUNCTION(path << &value);
882 return ConfigImpl::Get()->SetFailSafe(path, value);
883}
884
885void
886SetDefault(std::string name, const AttributeValue& value)
887{
888 NS_LOG_FUNCTION(name << &value);
889 if (!SetDefaultFailSafe(name, value))
890 {
891 NS_FATAL_ERROR("Could not set default value for " << name);
892 }
893}
894
895bool
896SetDefaultFailSafe(std::string fullName, const AttributeValue& value)
897{
898 NS_LOG_FUNCTION(fullName << &value);
899 std::string::size_type pos = fullName.rfind("::");
900 if (pos == std::string::npos)
901 {
902 return false;
903 }
904 std::string tidName = fullName.substr(0, pos);
905 std::string paramName = fullName.substr(pos + 2, fullName.size() - (pos + 2));
906 TypeId tid;
907 bool ok = TypeId::LookupByNameFailSafe(tidName, &tid);
908 if (!ok)
909 {
910 return false;
911 }
913 tid.LookupAttributeByName(paramName, &info);
914 for (uint32_t j = 0; j < tid.GetAttributeN(); j++)
915 {
917 if (tmp.name == paramName)
918 {
919 Ptr<AttributeValue> v = tmp.checker->CreateValidValue(value);
920 if (!v)
921 {
922 return false;
923 }
924 tid.SetAttributeInitialValue(j, v);
925 return true;
926 }
927 }
928 return false;
929}
930
931void
932SetGlobal(std::string name, const AttributeValue& value)
933{
934 NS_LOG_FUNCTION(name << &value);
935 GlobalValue::Bind(name, value);
936}
937
938bool
939SetGlobalFailSafe(std::string name, const AttributeValue& value)
940{
941 NS_LOG_FUNCTION(name << &value);
942 return GlobalValue::BindFailSafe(name, value);
943}
944
945void
946ConnectWithoutContext(std::string path, const CallbackBase& cb)
947{
948 NS_LOG_FUNCTION(path << &cb);
949 if (!ConnectWithoutContextFailSafe(path, cb))
950 {
951 NS_FATAL_ERROR("Could not connect callback to " << path);
952 }
953}
954
955bool
956ConnectWithoutContextFailSafe(std::string path, const CallbackBase& cb)
957{
958 NS_LOG_FUNCTION(path << &cb);
960}
961
962void
963DisconnectWithoutContext(std::string path, const CallbackBase& cb)
964{
965 NS_LOG_FUNCTION(path << &cb);
967}
968
969void
970Connect(std::string path, const CallbackBase& cb)
971{
972 NS_LOG_FUNCTION(path << &cb);
973 if (!ConnectFailSafe(path, cb))
974 {
975 NS_FATAL_ERROR("Could not connect callback to " << path);
976 }
977}
978
979bool
980ConnectFailSafe(std::string path, const CallbackBase& cb)
981{
982 NS_LOG_FUNCTION(path << &cb);
983 return ConfigImpl::Get()->ConnectFailSafe(path, cb);
984}
985
986void
987Disconnect(std::string path, const CallbackBase& cb)
988{
989 NS_LOG_FUNCTION(path << &cb);
990 ConfigImpl::Get()->Disconnect(path, cb);
991}
992
993MatchContainer
994LookupMatches(std::string path)
995{
996 NS_LOG_FUNCTION(path);
997 return ConfigImpl::Get()->LookupMatches(path);
998}
999
1000void
1006
1007void
1013
1014std::size_t
1020
1027
1028} // namespace Config
1029
1030} // namespace ns3
Hold a value for an Attribute.
Definition attribute.h:59
Base class for Callback class.
Definition callback.h:344
Helper to test if an array entry matches a config path specification.
Definition config.cc:195
ArrayMatcher(std::string element)
Construct from a Config path specification.
Definition config.cc:226
bool StringToUint32(std::string str, uint32_t *value) const
Convert a string to an uint32_t.
Definition config.cc:295
bool Matches(std::size_t i) const
Test if a specific index matches the Config Path.
Definition config.cc:233
std::string m_element
The Config path element.
Definition config.cc:221
Config system implementation class.
Definition config.cc:632
void UnregisterRootNamespaceObject(Ptr< Object > obj)
Definition config.cc:822
void DisconnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:728
Roots m_roots
The list of Config path roots.
Definition config.cc:675
Ptr< Object > GetRootNamespaceObject(std::size_t i) const
Definition config.cc:844
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:746
std::size_t GetRootNamespaceObjectN() const
Definition config.cc:837
bool SetFailSafe(std::string path, const AttributeValue &value)
Definition config.cc:705
void Set(std::string path, const AttributeValue &value)
Definition config.cc:693
void ParsePath(std::string path, std::string *root, std::string *leaf) const
Break a Config path into the leading path and the last leaf token.
Definition config.cc:681
void Disconnect(std::string path, const CallbackBase &cb)
Definition config.cc:758
std::vector< Ptr< Object > > Roots
Container type to hold the root Config path tokens.
Definition config.cc:672
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:717
void RegisterRootNamespaceObject(Ptr< Object > obj)
Definition config.cc:815
MatchContainer LookupMatches(std::string path)
Definition config.cc:777
hold a set of objects which match a specific search string.
Definition config.h:184
bool SetFailSafe(std::string name, const AttributeValue &value)
Definition config.cc:108
void Connect(std::string name, const CallbackBase &cb)
Definition config.cc:121
void DisconnectWithoutContext(std::string name, const CallbackBase &cb)
Definition config.cc:180
void Set(std::string name, const AttributeValue &value)
Definition config.cc:96
Ptr< Object > Get(std::size_t i) const
Definition config.cc:75
void Disconnect(std::string name, const CallbackBase &cb)
Definition config.cc:167
std::string GetMatchedPath(uint32_t i) const
Definition config.cc:82
MatchContainer::Iterator End() const
Definition config.cc:61
bool ConnectFailSafe(std::string name, const CallbackBase &cb)
Definition config.cc:130
std::string GetPath() const
Definition config.cc:89
bool ConnectWithoutContextFailSafe(std::string name, const CallbackBase &cb)
Definition config.cc:154
std::string m_path
The path used to perform the object matching.
Definition config.h:342
void ConnectWithoutContext(std::string name, const CallbackBase &cb)
Definition config.cc:145
std::size_t GetN() const
Definition config.cc:68
std::vector< Ptr< Object > >::const_iterator Iterator
Const iterator over the objects in this container.
Definition config.h:187
std::vector< Ptr< Object > > m_objects
The list of objects in this container.
Definition config.h:338
MatchContainer::Iterator Begin() const
Definition config.cc:54
std::vector< std::string > m_contexts
The context for each object.
Definition config.h:340
Abstract class to parse Config paths into object references.
Definition config.cc:309
std::vector< std::string > m_workStack
Current list of path tokens.
Definition config.cc:368
std::string GetResolvedPath() const
Get the current Config path.
Definition config.cc:416
Resolver(std::string path)
Construct from a base Config path.
Definition config.cc:375
void Resolve(Ptr< Object > root)
Parse the stored Config path into an object reference, beginning at the indicated root object.
Definition config.cc:408
void DoResolveOne(Ptr< Object > object)
Handle one object found on the path.
Definition config.cc:429
virtual void DoOne(Ptr< Object > object, std::string path)=0
Handle one found object.
void DoResolve(std::string path, Ptr< Object > root)
Parse the next element in the Config path.
Definition config.cc:438
std::string m_path
The Config path.
Definition config.cc:370
void Canonicalize()
Ensure the Config path starts and ends with a '/'.
Definition config.cc:388
virtual ~Resolver()
Destructor.
Definition config.cc:382
void DoArrayResolve(std::string path, const ObjectPtrContainerValue &vector)
Parse an index on the Config path.
Definition config.cc:599
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
static Iterator Begin()
The Begin iterator.
static bool BindFailSafe(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
static Iterator End()
The End iterator.
static Ptr< T > Find(std::string path)
Given a name path string, look to see if there's an object in the system with that associated to it.
Definition names.h:443
A base class which provides memory management and object aggregation.
Definition object.h:78
AttributeChecker implementation for ObjectPtrContainerValue.
Container for a set of ns3::Object pointers.
std::map< std::size_t, Ptr< Object > >::const_iterator Iterator
Iterator type for traversing this container.
AttributeChecker implementation for PointerValue.
Definition pointer.h:114
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
A template singleton.
Definition singleton.h:57
static ConfigImpl * Get()
Definition singleton.h:96
a unique identifier for an interface.
Definition type-id.h:49
bool SetAttributeInitialValue(std::size_t i, Ptr< const AttributeValue > initialValue)
Set the initial value of an Attribute.
Definition type-id.cc:1146
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
static uint16_t GetRegisteredN()
Get the number of registered TypeIds.
Definition type-id.cc:926
std::size_t GetAttributeN() const
Get the number of attributes.
Definition type-id.cc:1170
TypeId GetParent() const
Get the parent of this TypeId.
Definition type-id.cc:1025
static TypeId GetRegistered(uint16_t i)
Get a TypeId by index.
Definition type-id.cc:933
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition type-id.cc:1178
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition type-id.cc:886
bool LookupAttributeByName(std::string name, AttributeInformation *info, bool permissive=false) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition type-id.cc:968
Declaration of the various ns3::Config functions and classes.
ns3::GlobalValue declaration.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
void Reset()
Reset the initial value of every attribute as well as the value of every global to what they were bef...
Definition config.cc:851
void SetGlobal(std::string name, const AttributeValue &value)
Definition config.cc:932
bool SetFailSafe(std::string path, const AttributeValue &value)
Definition config.cc:879
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:886
void Disconnect(std::string path, const CallbackBase &cb)
Definition config.cc:987
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
MatchContainer LookupMatches(std::string path)
Definition config.cc:994
void DisconnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:963
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:946
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:980
void UnregisterRootNamespaceObject(Ptr< Object > obj)
Definition config.cc:1008
Ptr< Object > GetRootNamespaceObject(uint32_t i)
Definition config.cc:1022
bool SetGlobalFailSafe(std::string name, const AttributeValue &value)
Definition config.cc:939
void Set(std::string path, const AttributeValue &value)
Definition config.cc:872
void RegisterRootNamespaceObject(Ptr< Object > obj)
Definition config.cc:1001
std::size_t GetRootNamespaceObjectN()
Definition config.cc:1015
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition config.cc:896
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:956
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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 ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
Debug message logging.
Declaration of class ns3::Names.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
ns3::ObjectPtrContainerValue attribute value declarations and template implementations.
ns3::Object class declaration, which is the root of the Object hierarchy and Aggregation.
ns3::PointerValue attribute value declarations and template implementations.
ns3::Singleton declaration and template implementation.
Attribute implementation.
Definition type-id.h:86
Ptr< const AttributeValue > originalInitialValue
Default initial value.
Definition type-id.h:94
std::string name
Attribute name.
Definition type-id.h:88
Ptr< const AttributeChecker > checker
Checker object.
Definition type-id.h:100