A Discrete-Event Network Simulator
API
object-base.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 "object-base.h"
20 
21 #include "assert.h"
23 #include "environment-variable.h"
24 #include "log.h"
25 #include "string.h"
26 #include "trace-source-accessor.h"
27 
28 #include "ns3/core-config.h"
29 
36 namespace ns3
37 {
38 
39 NS_LOG_COMPONENT_DEFINE("ObjectBase");
40 
41 NS_OBJECT_ENSURE_REGISTERED(ObjectBase);
42 
51 static TypeId
53 {
55  TypeId tid = TypeId("ns3::ObjectBase");
56  tid.SetParent(tid);
57  tid.SetGroupName("Core");
58  return tid;
59 }
60 
61 TypeId
63 {
65  static TypeId tid = GetObjectIid();
66  return tid;
67 }
68 
70 {
71  NS_LOG_FUNCTION(this);
72 }
73 
74 void
76 {
77  NS_LOG_FUNCTION(this);
78 }
79 
80 void
82 {
83  // loop over the inheritance tree back to the Object base class.
84  NS_LOG_FUNCTION(this << &attributes);
85  TypeId tid = GetInstanceTypeId();
86  do // Do this tid and all parents
87  {
88  // loop over all attributes in object type
89  NS_LOG_DEBUG("construct tid=" << tid.GetName() << ", params=" << tid.GetAttributeN());
90  for (uint32_t i = 0; i < tid.GetAttributeN(); i++)
91  {
92  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
93  NS_LOG_DEBUG("try to construct \"" << tid.GetName() << "::" << info.name << "\"");
94  // is this attribute stored in this AttributeConstructionList instance ?
95  Ptr<const AttributeValue> value = attributes.Find(info.checker);
96  std::string where = "argument";
97 
98  // See if this attribute should not be set here in the
99  // constructor.
100  if (!(info.flags & TypeId::ATTR_CONSTRUCT))
101  {
102  // Handle this attribute if it should not be
103  // set here.
104  if (!value)
105  {
106  // Skip this attribute if it's not in the
107  // AttributeConstructionList.
108  NS_LOG_DEBUG("skipping, not settable at construction");
109  continue;
110  }
111  else
112  {
113  // This is an error because this attribute is not
114  // settable in its constructor but is present in
115  // the AttributeConstructionList.
116  NS_FATAL_ERROR("Attribute name="
117  << info.name << " tid=" << tid.GetName()
118  << ": initial value cannot be set using attributes");
119  }
120  }
121 
122  if (!value)
123  {
124  NS_LOG_DEBUG("trying to set from environment variable NS_ATTRIBUTE_DEFAULT");
125  auto [found, val] =
126  EnvironmentVariable::Get("NS_ATTRIBUTE_DEFAULT", tid.GetAttributeFullName(i));
127  if (found)
128  {
129  NS_LOG_DEBUG("found in environment: " << val);
130  value = Create<StringValue>(val);
131  where = "env var";
132  }
133  }
134 
135  bool initial{false};
136  if (!value)
137  {
138  // This is guaranteed to exist
139  NS_LOG_DEBUG("falling back to initial value from tid");
140  value = info.initialValue;
141  where = "initial value";
142  initial = true;
143  }
144 
145  // We have a matching attribute value, if only from the initialValue
146  if (DoSet(info.accessor, info.checker, *value) || initial)
147  {
148  // Setting from initial value may fail, e.g. setting
149  // ObjectVectorValue from ""
150  // That's ok, so we still report success since construction is complete
151  NS_LOG_DEBUG("construct \"" << tid.GetName() << "::" << info.name << "\" from "
152  << where);
153  }
154  else
155  {
156  /*
157  One would think this is an error...
158 
159  but there are cases where `attributes.Find(info.checker)`
160  returns a non-null value which still fails the `DoSet()` call.
161  For example, `value` is sometimes a real `PointerValue`
162  containing 0 as the pointed-to address. Since value
163  is not null (it just contains null) the initial
164  value is not used, the DoSet fails, and we end up
165  here.
166 
167  If we were adventurous we might try to fix this deep
168  below DoSet, but there be dragons.
169  */
170  /*
171  NS_ASSERT_MSG(false,
172  "Failed to set attribute '" << info.name << "' from '"
173  << value->SerializeToString(info.checker)
174  << "'");
175  */
176  }
177 
178  } // for i attributes
179  tid = tid.GetParent();
180  } while (tid != ObjectBase::GetTypeId());
182 }
183 
184 bool
187  const AttributeValue& value)
188 {
189  NS_LOG_FUNCTION(this << accessor << checker << &value);
190  Ptr<AttributeValue> v = checker->CreateValidValue(value);
191  if (!v)
192  {
193  return false;
194  }
195  bool ok = accessor->Set(this, *v);
196  return ok;
197 }
198 
199 void
201 {
202  NS_LOG_FUNCTION(this << name << &value);
203  struct TypeId::AttributeInformation info;
204  TypeId tid = GetInstanceTypeId();
205  if (!tid.LookupAttributeByName(name, &info))
206  {
208  "Attribute name=" << name << " does not exist for this object: tid=" << tid.GetName());
209  }
210  if (!(info.flags & TypeId::ATTR_SET) || !info.accessor->HasSetter())
211  {
213  "Attribute name=" << name << " is not settable for this object: tid=" << tid.GetName());
214  }
215  if (!DoSet(info.accessor, info.checker, value))
216  {
217  NS_FATAL_ERROR("Attribute name=" << name << " could not be set for this object: tid="
218  << tid.GetName());
219  }
220 }
221 
222 bool
224 {
225  NS_LOG_FUNCTION(this << name << &value);
226  struct TypeId::AttributeInformation info;
227  TypeId tid = GetInstanceTypeId();
228  if (!tid.LookupAttributeByName(name, &info))
229  {
230  return false;
231  }
232  if (!(info.flags & TypeId::ATTR_SET) || !info.accessor->HasSetter())
233  {
234  return false;
235  }
236  return DoSet(info.accessor, info.checker, value);
237 }
238 
239 void
241 {
242  NS_LOG_FUNCTION(this << name << &value);
243  struct TypeId::AttributeInformation info;
244  TypeId tid = GetInstanceTypeId();
245  if (!tid.LookupAttributeByName(name, &info))
246  {
248  "Attribute name=" << name << " does not exist for this object: tid=" << tid.GetName());
249  }
250  if (!(info.flags & TypeId::ATTR_GET) || !info.accessor->HasGetter())
251  {
253  "Attribute name=" << name << " is not gettable for this object: tid=" << tid.GetName());
254  }
255  bool ok = info.accessor->Get(this, value);
256  if (ok)
257  {
258  return;
259  }
260  StringValue* str = dynamic_cast<StringValue*>(&value);
261  if (str == nullptr)
262  {
263  NS_FATAL_ERROR("Attribute name=" << name << " tid=" << tid.GetName()
264  << ": input value is not a string");
265  }
266  Ptr<AttributeValue> v = info.checker->Create();
267  ok = info.accessor->Get(this, *PeekPointer(v));
268  if (!ok)
269  {
270  NS_FATAL_ERROR("Attribute name=" << name << " tid=" << tid.GetName()
271  << ": could not get value");
272  }
273  str->Set(v->SerializeToString(info.checker));
274 }
275 
276 bool
278 {
279  NS_LOG_FUNCTION(this << name << &value);
280  struct TypeId::AttributeInformation info;
281  TypeId tid = GetInstanceTypeId();
282  if (!tid.LookupAttributeByName(name, &info))
283  {
284  return false;
285  }
286  if (!(info.flags & TypeId::ATTR_GET) || !info.accessor->HasGetter())
287  {
288  return false;
289  }
290  bool ok = info.accessor->Get(this, value);
291  if (ok)
292  {
293  return true;
294  }
295  StringValue* str = dynamic_cast<StringValue*>(&value);
296  if (str == nullptr)
297  {
298  return false;
299  }
300  Ptr<AttributeValue> v = info.checker->Create();
301  ok = info.accessor->Get(this, *PeekPointer(v));
302  if (!ok)
303  {
304  return false;
305  }
306  str->Set(v->SerializeToString(info.checker));
307  return true;
308 }
309 
310 bool
312 {
313  NS_LOG_FUNCTION(this << name << &cb);
314  TypeId tid = GetInstanceTypeId();
316  if (!accessor)
317  {
318  return false;
319  }
320  bool ok = accessor->ConnectWithoutContext(this, cb);
321  return ok;
322 }
323 
324 bool
325 ObjectBase::TraceConnect(std::string name, std::string context, const CallbackBase& cb)
326 {
327  NS_LOG_FUNCTION(this << name << context << &cb);
328  TypeId tid = GetInstanceTypeId();
330  if (!accessor)
331  {
332  return false;
333  }
334  bool ok = accessor->Connect(this, context, cb);
335  return ok;
336 }
337 
338 bool
340 {
341  NS_LOG_FUNCTION(this << name << &cb);
342  TypeId tid = GetInstanceTypeId();
344  if (!accessor)
345  {
346  return false;
347  }
348  bool ok = accessor->DisconnectWithoutContext(this, cb);
349  return ok;
350 }
351 
352 bool
353 ObjectBase::TraceDisconnect(std::string name, std::string context, const CallbackBase& cb)
354 {
355  NS_LOG_FUNCTION(this << name << context << &cb);
356  TypeId tid = GetInstanceTypeId();
358  if (!accessor)
359  {
360  return false;
361  }
362  bool ok = accessor->Disconnect(this, context, cb);
363  return ok;
364 }
365 
366 } // namespace ns3
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
ns3::AttributeConstructionList declaration.
List of Attribute name, value and checker triples used to construct Objects.
Ptr< AttributeValue > Find(Ptr< const AttributeChecker > checker) const
Find an Attribute in the list from its AttributeChecker.
Hold a value for an Attribute.
Definition: attribute.h:70
Base class for Callback class.
Definition: callback.h:365
static KeyFoundType Get(const std::string &envvar, const std::string &key="", const std::string &delim=";")
Get the value corresponding to a key from an environment variable.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:311
bool TraceDisconnect(std::string name, std::string context, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected with a context.
Definition: object-base.cc:353
static TypeId GetObjectIid()
Ensure the TypeId for ObjectBase gets fully configured to anchor the inheritance tree properly.
Definition: object-base.cc:52
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:339
virtual TypeId GetInstanceTypeId() const =0
Get the most derived TypeId for this Object.
void ConstructSelf(const AttributeConstructionList &attributes)
Complete construction of ObjectBase; invoked by derived classes.
Definition: object-base.cc:81
virtual ~ObjectBase()
Virtual destructor.
Definition: object-base.cc:69
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising errors.
Definition: object-base.cc:277
virtual void NotifyConstructionCompleted()
Notifier called once the ObjectBase is fully constructed.
Definition: object-base.cc:75
static TypeId GetTypeId()
Get the type ID.
Definition: object-base.cc:62
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:223
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:240
bool TraceConnect(std::string name, std::string context, const CallbackBase &cb)
Connect a TraceSource to a Callback with a context.
Definition: object-base.cc:325
bool DoSet(Ptr< const AttributeAccessor > spec, Ptr< const AttributeChecker > checker, const AttributeValue &value)
Attempt to set the value referenced by the accessor spec to a valid value according to the checker,...
Definition: object-base.cc:185
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Hold variables of type string.
Definition: string.h:56
void Set(const std::string &value)
Set the value.
Definition: string.cc:31
a unique identifier for an interface.
Definition: type-id.h:60
@ ATTR_GET
The attribute can be read.
Definition: type-id.h:65
@ ATTR_SET
The attribute can be written.
Definition: type-id.h:66
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
Definition: type-id.h:67
std::string GetAttributeFullName(std::size_t i) const
Get the Attribute name by index.
Definition: type-id.cc:1119
struct TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1112
std::size_t GetAttributeN() const
Get the number of attributes.
Definition: type-id.cc:1104
TypeId GetParent() const
Get the parent of this TypeId.
Definition: type-id.cc:959
TypeId SetGroupName(std::string groupName)
Set the group name.
Definition: type-id.cc:943
Ptr< const TraceSourceAccessor > LookupTraceSourceByName(std::string name) const
Find a TraceSource by name.
Definition: type-id.cc:1202
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
std::string GetName() const
Get the name.
Definition: type-id.cc:995
Class Environment declaration.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Debug message logging.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
value
Definition: second.py:41
ns3::ObjectBase declaration and NS_OBJECT_ENSURE_REGISTERED() macro definition.
ns3::StringValue attribute value declarations.
Attribute implementation.
Definition: type-id.h:82
std::string name
Attribute name.
Definition: type-id.h:84
Ptr< const AttributeAccessor > accessor
Accessor object.
Definition: type-id.h:94
uint32_t flags
AttributeFlags value.
Definition: type-id.h:88
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:96
Ptr< const AttributeValue > initialValue
Configured initial value.
Definition: type-id.h:92
ns3::TraceSourceAccessor and ns3::MakeTraceSourceAccessor declarations.