A Discrete-Event Network Simulator
API
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"
24 #include "object-ptr-container.h"
25 #include "object.h"
26 #include "pointer.h"
27 #include "singleton.h"
28 
29 #include <sstream>
30 
37 namespace ns3
38 {
39 
40 NS_LOG_COMPONENT_DEFINE("Config");
41 
42 namespace Config
43 {
44 
46 {
47  NS_LOG_FUNCTION(this);
48 }
49 
50 MatchContainer::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 
74 std::size_t
76 {
77  NS_LOG_FUNCTION(this);
78  return m_objects.size();
79 }
80 
82 MatchContainer::Get(std::size_t i) const
83 {
84  NS_LOG_FUNCTION(this << i);
85  return m_objects[i];
86 }
87 
88 std::string
90 {
91  NS_LOG_FUNCTION(this << i);
92  return m_contexts[i];
93 }
94 
95 std::string
97 {
98  NS_LOG_FUNCTION(this);
99  return m_path;
100 }
101 
102 void
103 MatchContainer::Set(std::string name, const AttributeValue& value)
104 {
105  NS_LOG_FUNCTION(this << name << &value);
106  for (auto 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 
114 bool
115 MatchContainer::SetFailSafe(std::string name, const AttributeValue& value)
116 {
117  NS_LOG_FUNCTION(this << name << &value);
118  bool ok = false;
119  for (auto tmp = Begin(); tmp != End(); ++tmp)
120  {
121  Ptr<Object> object = *tmp;
122  ok |= object->SetAttributeFailSafe(name, value);
123  }
124  return ok;
125 }
126 
127 void
128 MatchContainer::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 
136 bool
137 MatchContainer::ConnectFailSafe(std::string name, const CallbackBase& cb)
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 
151 void
153 {
154  if (!ConnectWithoutContextFailSafe(name, cb))
155  {
156  NS_FATAL_ERROR("Could not connect callback to " << name);
157  }
158 }
159 
160 bool
162 {
163  NS_LOG_FUNCTION(this << name << &cb);
164  bool ok = false;
165  for (auto tmp = Begin(); tmp != End(); ++tmp)
166  {
167  Ptr<Object> object = *tmp;
168  ok |= object->TraceConnectWithoutContext(name, cb);
169  }
170  return ok;
171 }
172 
173 void
174 MatchContainer::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 
186 void
188 {
189  NS_LOG_FUNCTION(this << name << &cb);
190  for (auto 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 
232 ArrayMatcher::ArrayMatcher(std::string element)
233  : m_element(element)
234 {
235  NS_LOG_FUNCTION(this << element);
236 }
237 
238 bool
239 ArrayMatcher::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));
276  uint32_t min;
277  uint32_t max;
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 
300 bool
301 ArrayMatcher::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 
314 class Resolver
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 
380 Resolver::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 
392 void
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 
412 void
414 {
415  NS_LOG_FUNCTION(this << root);
416 
417  DoResolve(m_path, root);
418 }
419 
420 std::string
422 {
423  NS_LOG_FUNCTION(this);
424 
425  std::string fullPath = "/";
426  for (auto i = m_workStack.begin(); i != m_workStack.end(); i++)
427  {
428  fullPath += *i + "/";
429  }
430  return fullPath;
431 }
432 
433 void
435 {
436  NS_LOG_FUNCTION(this << object);
437 
438  NS_LOG_DEBUG("resolved=" << GetResolvedPath());
439  DoOne(object, GetResolvedPath());
440 }
441 
442 void
443 Resolver::DoResolve(std::string path, Ptr<Object> root)
444 {
445  NS_LOG_FUNCTION(this << path << root);
446  NS_ASSERT((path.find('/')) == 0);
447  std::string::size_type next = path.find('/', 1);
448 
449  if (next == std::string::npos)
450  {
451  //
452  // If root is zero, we're beginning to see if we can use the object name
453  // service to resolve this path. It is impossible to have a object name
454  // associated with the root of the object name service since that root
455  // is not an object. This path must be referring to something in another
456  // namespace and it will have been found already since the name service
457  // is always consulted last.
458  //
459  if (root)
460  {
461  DoResolveOne(root);
462  }
463  return;
464  }
465  std::string item = path.substr(1, next - 1);
466  std::string pathLeft = path.substr(next, path.size() - next);
467 
468  //
469  // If root is zero, we're beginning to see if we can use the object name
470  // service to resolve this path. In this case, we must see the name space
471  // "/Names" on the front of this path. There is no object associated with
472  // the root of the "/Names" namespace, so we just ignore it and move on to
473  // the next segment.
474  //
475  if (!root)
476  {
477  std::string::size_type offset = path.find("/Names");
478  if (offset == 0)
479  {
480  m_workStack.push_back(item);
481  DoResolve(pathLeft, root);
482  m_workStack.pop_back();
483  return;
484  }
485  }
486 
487  //
488  // We have an item (possibly a segment of a namespace path. Check to see if
489  // we can determine that this segment refers to a named object. If root is
490  // zero, this means to look in the root of the "/Names" name space, otherwise
491  // it refers to a name space context (level).
492  //
493  Ptr<Object> namedObject = Names::Find<Object>(root, item);
494  if (namedObject)
495  {
496  NS_LOG_DEBUG("Name system resolved item = " << item << " to " << namedObject);
497  m_workStack.push_back(item);
498  DoResolve(pathLeft, namedObject);
499  m_workStack.pop_back();
500  return;
501  }
502 
503  //
504  // We're done with the object name service hooks, so proceed down the path
505  // of types and attributes; but only if root is nonzero. If root is zero
506  // and we find ourselves here, we are trying to check in the namespace for
507  // a path that is not in the "/Names" namespace. We will have previously
508  // found any matches, so we just bail out.
509  //
510  if (!root)
511  {
512  return;
513  }
514  std::string::size_type dollarPos = item.find('$');
515  if (dollarPos == 0)
516  {
517  // This is a call to GetObject
518  std::string tidString = item.substr(1, item.size() - 1);
519  NS_LOG_DEBUG("GetObject=" << tidString << " on path=" << GetResolvedPath());
520  TypeId tid = TypeId::LookupByName(tidString);
521  Ptr<Object> object = root->GetObject<Object>(tid);
522  if (!object)
523  {
524  NS_LOG_DEBUG("GetObject (" << tidString << ") failed on path=" << GetResolvedPath());
525  return;
526  }
527  m_workStack.push_back(item);
528  DoResolve(pathLeft, object);
529  m_workStack.pop_back();
530  }
531  else
532  {
533  // this is a normal attribute.
534  TypeId tid;
535  TypeId nextTid = root->GetInstanceTypeId();
536  bool foundMatch = false;
537 
538  do
539  {
540  tid = nextTid;
541 
542  for (uint32_t i = 0; i < tid.GetAttributeN(); i++)
543  {
545  info = tid.GetAttribute(i);
546  if (info.name != item && item != "*")
547  {
548  continue;
549  }
550  // attempt to cast to a pointer checker.
551  const auto pChecker =
552  dynamic_cast<const PointerChecker*>(PeekPointer(info.checker));
553  if (pChecker != nullptr)
554  {
555  NS_LOG_DEBUG("GetAttribute(ptr)=" << info.name
556  << " on path=" << GetResolvedPath());
557  PointerValue pValue;
558  root->GetAttribute(info.name, pValue);
559  Ptr<Object> object = pValue.Get<Object>();
560  if (!object)
561  {
562  NS_LOG_ERROR("Requested object name=\"" << item << "\" exists on path=\""
563  << GetResolvedPath()
564  << "\""
565  " but is null.");
566  continue;
567  }
568  foundMatch = true;
569  m_workStack.push_back(info.name);
570  DoResolve(pathLeft, object);
571  m_workStack.pop_back();
572  }
573  // attempt to cast to an object vector.
574  const auto vectorChecker =
575  dynamic_cast<const ObjectPtrContainerChecker*>(PeekPointer(info.checker));
576  if (vectorChecker != nullptr)
577  {
578  NS_LOG_DEBUG("GetAttribute(vector)=" << info.name << " on path="
579  << GetResolvedPath() << pathLeft);
580  foundMatch = true;
582  root->GetAttribute(info.name, vector);
583  m_workStack.push_back(info.name);
584  DoArrayResolve(pathLeft, vector);
585  m_workStack.pop_back();
586  }
587  // this could be anything else and we don't know what to do with it.
588  // So, we just ignore it.
589  }
590 
591  nextTid = tid.GetParent();
592  } while (nextTid != tid);
593 
594  if (!foundMatch)
595  {
596  NS_LOG_DEBUG("Requested item=" << item
597  << " does not exist on path=" << GetResolvedPath());
598  return;
599  }
600  }
601 }
602 
603 void
605 {
606  NS_LOG_FUNCTION(this << path << &container);
607  NS_ASSERT(!path.empty());
608  NS_ASSERT((path.find('/')) == 0);
609  std::string::size_type next = path.find('/', 1);
610  if (next == std::string::npos)
611  {
612  return;
613  }
614  std::string item = path.substr(1, next - 1);
615  std::string pathLeft = path.substr(next, path.size() - next);
616 
617  ArrayMatcher matcher = ArrayMatcher(item);
619  for (it = container.Begin(); it != container.End(); ++it)
620  {
621  if (matcher.Matches((*it).first))
622  {
623  std::ostringstream oss;
624  oss << (*it).first;
625  m_workStack.push_back(oss.str());
626  DoResolve(pathLeft, (*it).second);
627  m_workStack.pop_back();
628  }
629  }
630 }
631 
636 class ConfigImpl : public Singleton<ConfigImpl>
637 {
638  public:
639  // Keep Set and SetFailSafe since their errors are triggered
640  // by the underlying ObjectBase functions.
642  void Set(std::string path, const AttributeValue& value);
644  bool SetFailSafe(std::string path, const AttributeValue& value);
646  bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase& cb);
648  bool ConnectFailSafe(std::string path, const CallbackBase& cb);
650  void DisconnectWithoutContext(std::string path, const CallbackBase& cb);
652  void Disconnect(std::string path, const CallbackBase& cb);
654  MatchContainer LookupMatches(std::string path);
655 
660 
662  std::size_t GetRootNamespaceObjectN() const;
664  Ptr<Object> GetRootNamespaceObject(std::size_t i) const;
665 
666  private:
674  void ParsePath(std::string path, std::string* root, std::string* leaf) const;
675 
677  typedef std::vector<Ptr<Object>> Roots;
678 
681 
682 }; // class ConfigImpl
683 
684 void
685 ConfigImpl::ParsePath(std::string path, std::string* root, std::string* leaf) const
686 {
687  NS_LOG_FUNCTION(this << path << root << leaf);
688 
689  std::string::size_type slash = path.find_last_of('/');
690  NS_ASSERT(slash != std::string::npos);
691  *root = path.substr(0, slash);
692  *leaf = path.substr(slash + 1, path.size() - (slash + 1));
693  NS_LOG_FUNCTION(path << *root << *leaf);
694 }
695 
696 void
697 ConfigImpl::Set(std::string path, const AttributeValue& value)
698 {
699  NS_LOG_FUNCTION(this << path << &value);
700 
701  std::string root;
702  std::string leaf;
703  ParsePath(path, &root, &leaf);
705  container.Set(leaf, value);
706 }
707 
708 bool
709 ConfigImpl::SetFailSafe(std::string path, const AttributeValue& value)
710 {
711  NS_LOG_FUNCTION(this << path << &value);
712 
713  std::string root;
714  std::string leaf;
715  ParsePath(path, &root, &leaf);
717  return container.SetFailSafe(leaf, value);
718 }
719 
720 bool
722 {
723  NS_LOG_FUNCTION(this << path << &cb);
724  std::string root;
725  std::string leaf;
726  ParsePath(path, &root, &leaf);
728  return container.ConnectWithoutContextFailSafe(leaf, cb);
729 }
730 
731 void
733 {
734  NS_LOG_FUNCTION(this << path << &cb);
735  std::string root;
736  std::string leaf;
737  ParsePath(path, &root, &leaf);
739  if (container.GetN() == 0)
740  {
741  std::size_t lastFwdSlash = root.rfind('/');
742  NS_LOG_WARN("Failed to disconnect "
743  << leaf << ", the Requested object name = " << root.substr(lastFwdSlash + 1)
744  << " does not exits on path " << root.substr(0, lastFwdSlash));
745  }
746  container.DisconnectWithoutContext(leaf, cb);
747 }
748 
749 bool
750 ConfigImpl::ConnectFailSafe(std::string path, const CallbackBase& cb)
751 {
752  NS_LOG_FUNCTION(this << path << &cb);
753 
754  std::string root;
755  std::string leaf;
756  ParsePath(path, &root, &leaf);
758  return container.ConnectFailSafe(leaf, cb);
759 }
760 
761 void
762 ConfigImpl::Disconnect(std::string path, const CallbackBase& cb)
763 {
764  NS_LOG_FUNCTION(this << path << &cb);
765 
766  std::string root;
767  std::string leaf;
768  ParsePath(path, &root, &leaf);
770  if (container.GetN() == 0)
771  {
772  std::size_t lastFwdSlash = root.rfind('/');
773  NS_LOG_WARN("Failed to disconnect "
774  << leaf << ", the Requested object name = " << root.substr(lastFwdSlash + 1)
775  << " does not exits on path " << root.substr(0, lastFwdSlash));
776  }
777  container.Disconnect(leaf, cb);
778 }
779 
781 ConfigImpl::LookupMatches(std::string path)
782 {
783  NS_LOG_FUNCTION(this << path);
784 
785  class LookupMatchesResolver : public Resolver
786  {
787  public:
788  LookupMatchesResolver(std::string path)
789  : Resolver(path)
790  {
791  }
792 
793  void DoOne(Ptr<Object> object, std::string path) override
794  {
795  m_objects.push_back(object);
796  m_contexts.push_back(path);
797  }
798 
799  std::vector<Ptr<Object>> m_objects;
800  std::vector<std::string> m_contexts;
801  } resolver = LookupMatchesResolver(path);
802 
803  for (auto i = m_roots.begin(); i != m_roots.end(); i++)
804  {
805  resolver.Resolve(*i);
806  }
807 
808  //
809  // See if we can do something with the object name service. Starting with
810  // the root pointer zeroed indicates to the resolver that it should start
811  // looking at the root of the "/Names" namespace during this go.
812  //
813  resolver.Resolve(nullptr);
814 
815  return MatchContainer(resolver.m_objects, resolver.m_contexts, path);
816 }
817 
818 void
820 {
821  NS_LOG_FUNCTION(this << obj);
822  m_roots.push_back(obj);
823 }
824 
825 void
827 {
828  NS_LOG_FUNCTION(this << obj);
829 
830  for (auto i = m_roots.begin(); i != m_roots.end(); i++)
831  {
832  if (*i == obj)
833  {
834  m_roots.erase(i);
835  return;
836  }
837  }
838 }
839 
840 std::size_t
842 {
843  NS_LOG_FUNCTION(this);
844  return m_roots.size();
845 }
846 
849 {
850  NS_LOG_FUNCTION(this << i);
851  return m_roots[i];
852 }
853 
854 void
856 {
858  // First, let's reset the initial value of every attribute
859  for (uint16_t i = 0; i < TypeId::GetRegisteredN(); i++)
860  {
861  TypeId tid = TypeId::GetRegistered(i);
862  for (uint32_t j = 0; j < tid.GetAttributeN(); j++)
863  {
866  }
867  }
868  // now, let's reset the initial value of every global value.
869  for (auto i = GlobalValue::Begin(); i != GlobalValue::End(); ++i)
870  {
871  (*i)->ResetInitialValue();
872  }
873 }
874 
875 void
876 Set(std::string path, const AttributeValue& value)
877 {
878  NS_LOG_FUNCTION(path << &value);
879  ConfigImpl::Get()->Set(path, value);
880 }
881 
882 bool
883 SetFailSafe(std::string path, const AttributeValue& value)
884 {
885  NS_LOG_FUNCTION(path << &value);
886  return ConfigImpl::Get()->SetFailSafe(path, value);
887 }
888 
889 void
890 SetDefault(std::string name, const AttributeValue& value)
891 {
892  NS_LOG_FUNCTION(name << &value);
893  if (!SetDefaultFailSafe(name, value))
894  {
895  NS_FATAL_ERROR("Could not set default value for " << name);
896  }
897 }
898 
899 bool
900 SetDefaultFailSafe(std::string fullName, const AttributeValue& value)
901 {
902  NS_LOG_FUNCTION(fullName << &value);
903  std::string::size_type pos = fullName.rfind("::");
904  if (pos == std::string::npos)
905  {
906  return false;
907  }
908  std::string tidName = fullName.substr(0, pos);
909  std::string paramName = fullName.substr(pos + 2, fullName.size() - (pos + 2));
910  TypeId tid;
911  bool ok = TypeId::LookupByNameFailSafe(tidName, &tid);
912  if (!ok)
913  {
914  return false;
915  }
917  tid.LookupAttributeByName(paramName, &info);
918  for (uint32_t j = 0; j < tid.GetAttributeN(); j++)
919  {
921  if (tmp.name == paramName)
922  {
923  Ptr<AttributeValue> v = tmp.checker->CreateValidValue(value);
924  if (!v)
925  {
926  return false;
927  }
928  tid.SetAttributeInitialValue(j, v);
929  return true;
930  }
931  }
932  return false;
933 }
934 
935 void
936 SetGlobal(std::string name, const AttributeValue& value)
937 {
938  NS_LOG_FUNCTION(name << &value);
939  GlobalValue::Bind(name, value);
940 }
941 
942 bool
943 SetGlobalFailSafe(std::string name, const AttributeValue& value)
944 {
945  NS_LOG_FUNCTION(name << &value);
946  return GlobalValue::BindFailSafe(name, value);
947 }
948 
949 void
950 ConnectWithoutContext(std::string path, const CallbackBase& cb)
951 {
952  NS_LOG_FUNCTION(path << &cb);
953  if (!ConnectWithoutContextFailSafe(path, cb))
954  {
955  NS_FATAL_ERROR("Could not connect callback to " << path);
956  }
957 }
958 
959 bool
960 ConnectWithoutContextFailSafe(std::string path, const CallbackBase& cb)
961 {
962  NS_LOG_FUNCTION(path << &cb);
964 }
965 
966 void
967 DisconnectWithoutContext(std::string path, const CallbackBase& cb)
968 {
969  NS_LOG_FUNCTION(path << &cb);
971 }
972 
973 void
974 Connect(std::string path, const CallbackBase& cb)
975 {
976  NS_LOG_FUNCTION(path << &cb);
977  if (!ConnectFailSafe(path, cb))
978  {
979  NS_FATAL_ERROR("Could not connect callback to " << path);
980  }
981 }
982 
983 bool
984 ConnectFailSafe(std::string path, const CallbackBase& cb)
985 {
986  NS_LOG_FUNCTION(path << &cb);
987  return ConfigImpl::Get()->ConnectFailSafe(path, cb);
988 }
989 
990 void
991 Disconnect(std::string path, const CallbackBase& cb)
992 {
993  NS_LOG_FUNCTION(path << &cb);
994  ConfigImpl::Get()->Disconnect(path, cb);
995 }
996 
997 MatchContainer
998 LookupMatches(std::string path)
999 {
1000  NS_LOG_FUNCTION(path);
1001  return ConfigImpl::Get()->LookupMatches(path);
1002 }
1003 
1004 void
1006 {
1007  NS_LOG_FUNCTION(obj);
1009 }
1010 
1011 void
1013 {
1014  NS_LOG_FUNCTION(obj);
1016 }
1017 
1018 std::size_t
1020 {
1023 }
1024 
1027 {
1028  NS_LOG_FUNCTION(i);
1030 }
1031 
1032 } // namespace Config
1033 
1034 } // 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:637
void UnregisterRootNamespaceObject(Ptr< Object > obj)
Definition: config.cc:826
void DisconnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:732
Roots m_roots
The list of Config path roots.
Definition: config.cc:680
Ptr< Object > GetRootNamespaceObject(std::size_t i) const
Definition: config.cc:848
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:750
std::size_t GetRootNamespaceObjectN() const
Definition: config.cc:841
bool SetFailSafe(std::string path, const AttributeValue &value)
Definition: config.cc:709
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:697
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:685
void Disconnect(std::string path, const CallbackBase &cb)
Definition: config.cc:762
std::vector< Ptr< Object > > Roots
Container type to hold the root Config path tokens.
Definition: config.cc:677
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:721
void RegisterRootNamespaceObject(Ptr< Object > obj)
Definition: config.cc:819
MatchContainer LookupMatches(std::string path)
Definition: config.cc:781
hold a set of objects which match a specific search string.
Definition: config.h:195
std::vector< Ptr< Object > >::const_iterator Iterator
Const iterator over the objects in this container.
Definition: config.h:198
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 > > 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:434
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:443
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:604
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.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:315
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:343
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:227
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:244
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: object.cc:82
Container for a set of ns3::Object pointers.
std::map< std::size_t, Ptr< Object > >::const_iterator Iterator
Iterator type for traversing this container.
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get() const
Definition: pointer.h:202
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:1076
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
static uint16_t GetRegisteredN()
Get the number of registered TypeIds.
Definition: type-id.cc:879
std::size_t GetAttributeN() const
Get the number of attributes.
Definition: type-id.cc:1100
TypeId GetParent() const
Get the parent of this TypeId.
Definition: type-id.cc:955
static TypeId GetRegistered(uint16_t i)
Get a TypeId by index.
Definition: type-id.cc:886
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1108
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition: type-id.cc:844
bool LookupAttributeByName(std::string name, AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:893
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:855
void SetGlobal(std::string name, const AttributeValue &value)
Definition: config.cc:936
bool SetFailSafe(std::string path, const AttributeValue &value)
Definition: config.cc:883
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void Disconnect(std::string path, const CallbackBase &cb)
Definition: config.cc:991
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
MatchContainer LookupMatches(std::string path)
Definition: config.cc:998
void DisconnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:967
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:950
bool ConnectFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:984
void UnregisterRootNamespaceObject(Ptr< Object > obj)
Definition: config.cc:1012
Ptr< Object > GetRootNamespaceObject(uint32_t i)
Definition: config.cc:1026
bool SetGlobalFailSafe(std::string name, const AttributeValue &value)
Definition: config.cc:943
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:876
void RegisterRootNamespaceObject(Ptr< Object > obj)
Definition: config.cc:1005
std::size_t GetRootNamespaceObjectN()
Definition: config.cc:1019
bool SetDefaultFailSafe(std::string fullName, const AttributeValue &value)
Definition: config.cc:900
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:960
#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:449
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