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