A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 // Explicit instantiation declaration
41 template class CallbackImpl<ObjectBase*>;
42 
43 NS_LOG_COMPONENT_DEFINE("ObjectBase");
44 
46 
55 static TypeId
57 {
59  TypeId tid = TypeId("ns3::ObjectBase");
60  tid.SetParent(tid);
61  tid.SetGroupName("Core");
62  return tid;
63 }
64 
65 TypeId
67 {
69  static TypeId tid = GetObjectIid();
70  return tid;
71 }
72 
74 {
75  NS_LOG_FUNCTION(this);
76 }
77 
78 void
80 {
81  NS_LOG_FUNCTION(this);
82 }
83 
84 void
86 {
87  // loop over the inheritance tree back to the Object base class.
88  NS_LOG_FUNCTION(this << &attributes);
89  TypeId tid = GetInstanceTypeId();
90  do // Do this tid and all parents
91  {
92  // loop over all attributes in object type
93  NS_LOG_DEBUG("construct tid=" << tid.GetName() << ", params=" << tid.GetAttributeN());
94  for (uint32_t i = 0; i < tid.GetAttributeN(); i++)
95  {
97  NS_LOG_DEBUG("try to construct \"" << tid.GetName() << "::" << info.name << "\"");
98  // is this attribute stored in this AttributeConstructionList instance ?
99  Ptr<const AttributeValue> value = attributes.Find(info.checker);
100  std::string where = "argument";
101 
102  // See if this attribute should not be set here in the
103  // constructor.
104  if (!(info.flags & TypeId::ATTR_CONSTRUCT))
105  {
106  // Handle this attribute if it should not be
107  // set here.
108  if (!value)
109  {
110  // Skip this attribute if it's not in the
111  // AttributeConstructionList.
112  NS_LOG_DEBUG("skipping, not settable at construction");
113  continue;
114  }
115  else
116  {
117  // This is an error because this attribute is not
118  // settable in its constructor but is present in
119  // the AttributeConstructionList.
120  NS_FATAL_ERROR("Attribute name="
121  << info.name << " tid=" << tid.GetName()
122  << ": initial value cannot be set using attributes");
123  }
124  }
125 
126  if (!value)
127  {
128  NS_LOG_DEBUG("trying to set from environment variable NS_ATTRIBUTE_DEFAULT");
129  auto [found, val] =
130  EnvironmentVariable::Get("NS_ATTRIBUTE_DEFAULT", tid.GetAttributeFullName(i));
131  if (found)
132  {
133  NS_LOG_DEBUG("found in environment: " << val);
134  value = Create<StringValue>(val);
135  where = "env var";
136  }
137  }
138 
139  bool initial{false};
140  if (!value)
141  {
142  // This is guaranteed to exist
143  NS_LOG_DEBUG("falling back to initial value from tid");
144  value = info.initialValue;
145  where = "initial value";
146  initial = true;
147  }
148 
149  // We have a matching attribute value, if only from the initialValue
150  if (DoSet(info.accessor, info.checker, *value) || initial)
151  {
152  // Setting from initial value may fail, e.g. setting
153  // ObjectVectorValue from ""
154  // That's ok, so we still report success since construction is complete
155  NS_LOG_DEBUG("construct \"" << tid.GetName() << "::" << info.name << "\" from "
156  << where);
157  }
158  else
159  {
160  /*
161  One would think this is an error...
162 
163  but there are cases where `attributes.Find(info.checker)`
164  returns a non-null value which still fails the `DoSet()` call.
165  For example, `value` is sometimes a real `PointerValue`
166  containing 0 as the pointed-to address. Since value
167  is not null (it just contains null) the initial
168  value is not used, the DoSet fails, and we end up
169  here.
170 
171  If we were adventurous we might try to fix this deep
172  below DoSet, but there be dragons.
173  */
174  /*
175  NS_ASSERT_MSG(false,
176  "Failed to set attribute '" << info.name << "' from '"
177  << value->SerializeToString(info.checker)
178  << "'");
179  */
180  }
181 
182  } // for i attributes
183  tid = tid.GetParent();
184  } while (tid != ObjectBase::GetTypeId());
186 }
187 
188 bool
191  const AttributeValue& value)
192 {
193  NS_LOG_FUNCTION(this << accessor << checker << &value);
194  Ptr<AttributeValue> v = checker->CreateValidValue(value);
195  if (!v)
196  {
197  return false;
198  }
199  bool ok = accessor->Set(this, *v);
200  return ok;
201 }
202 
203 void
204 ObjectBase::SetAttribute(std::string name, const AttributeValue& value)
205 {
206  NS_LOG_FUNCTION(this << name << &value);
208  TypeId tid = GetInstanceTypeId();
209  if (!tid.LookupAttributeByName(name, &info))
210  {
212  "Attribute name=" << name << " does not exist for this object: tid=" << tid.GetName());
213  }
214  if (!(info.flags & TypeId::ATTR_SET) || !info.accessor->HasSetter())
215  {
217  "Attribute name=" << name << " is not settable for this object: tid=" << tid.GetName());
218  }
219  if (!DoSet(info.accessor, info.checker, value))
220  {
221  NS_FATAL_ERROR("Attribute name=" << name << " could not be set for this object: tid="
222  << tid.GetName());
223  }
224 }
225 
226 bool
227 ObjectBase::SetAttributeFailSafe(std::string name, const AttributeValue& value)
228 {
229  NS_LOG_FUNCTION(this << name << &value);
231  TypeId tid = GetInstanceTypeId();
232  if (!tid.LookupAttributeByName(name, &info))
233  {
234  return false;
235  }
236  if (!(info.flags & TypeId::ATTR_SET) || !info.accessor->HasSetter())
237  {
238  return false;
239  }
240  return DoSet(info.accessor, info.checker, value);
241 }
242 
243 void
244 ObjectBase::GetAttribute(std::string name, AttributeValue& value) const
245 {
246  NS_LOG_FUNCTION(this << name << &value);
248  TypeId tid = GetInstanceTypeId();
249  if (!tid.LookupAttributeByName(name, &info))
250  {
252  "Attribute name=" << name << " does not exist for this object: tid=" << tid.GetName());
253  }
254  if (!(info.flags & TypeId::ATTR_GET) || !info.accessor->HasGetter())
255  {
257  "Attribute name=" << name << " is not gettable for this object: tid=" << tid.GetName());
258  }
259  bool ok = info.accessor->Get(this, value);
260  if (ok)
261  {
262  return;
263  }
264  auto str = dynamic_cast<StringValue*>(&value);
265  if (str == nullptr)
266  {
267  NS_FATAL_ERROR("Attribute name=" << name << " tid=" << tid.GetName()
268  << ": input value is not a string");
269  }
270  Ptr<AttributeValue> v = info.checker->Create();
271  ok = info.accessor->Get(this, *PeekPointer(v));
272  if (!ok)
273  {
274  NS_FATAL_ERROR("Attribute name=" << name << " tid=" << tid.GetName()
275  << ": could not get value");
276  }
277  str->Set(v->SerializeToString(info.checker));
278 }
279 
280 bool
281 ObjectBase::GetAttributeFailSafe(std::string name, AttributeValue& value) const
282 {
283  NS_LOG_FUNCTION(this << name << &value);
285  TypeId tid = GetInstanceTypeId();
286  if (!tid.LookupAttributeByName(name, &info))
287  {
288  return false;
289  }
290  if (!(info.flags & TypeId::ATTR_GET) || !info.accessor->HasGetter())
291  {
292  return false;
293  }
294  bool ok = info.accessor->Get(this, value);
295  if (ok)
296  {
297  return true;
298  }
299  auto str = dynamic_cast<StringValue*>(&value);
300  if (str == nullptr)
301  {
302  return false;
303  }
304  Ptr<AttributeValue> v = info.checker->Create();
305  ok = info.accessor->Get(this, *PeekPointer(v));
306  if (!ok)
307  {
308  return false;
309  }
310  str->Set(v->SerializeToString(info.checker));
311  return true;
312 }
313 
314 bool
316 {
317  NS_LOG_FUNCTION(this << name << &cb);
318  TypeId tid = GetInstanceTypeId();
320  if (!accessor)
321  {
322  return false;
323  }
324  bool ok = accessor->ConnectWithoutContext(this, cb);
325  return ok;
326 }
327 
328 bool
329 ObjectBase::TraceConnect(std::string name, std::string context, const CallbackBase& cb)
330 {
331  NS_LOG_FUNCTION(this << name << context << &cb);
332  TypeId tid = GetInstanceTypeId();
334  if (!accessor)
335  {
336  return false;
337  }
338  bool ok = accessor->Connect(this, context, cb);
339  return ok;
340 }
341 
342 bool
344 {
345  NS_LOG_FUNCTION(this << name << &cb);
346  TypeId tid = GetInstanceTypeId();
348  if (!accessor)
349  {
350  return false;
351  }
352  bool ok = accessor->DisconnectWithoutContext(this, cb);
353  return ok;
354 }
355 
356 bool
357 ObjectBase::TraceDisconnect(std::string name, std::string context, const CallbackBase& cb)
358 {
359  NS_LOG_FUNCTION(this << name << context << &cb);
360  TypeId tid = GetInstanceTypeId();
362  if (!accessor)
363  {
364  return false;
365  }
366  bool ok = accessor->Disconnect(this, context, cb);
367  return ok;
368 }
369 
370 } // 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:360
Callback template class.
Definition: callback.h:438
friend class Callback
Definition: callback.h:440
CallbackImpl class with varying numbers of argument types.
Definition: callback.h:242
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.
Anchor the ns-3 type and attribute system.
Definition: object-base.h:173
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:315
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:357
static TypeId GetObjectIid()
Ensure the TypeId for ObjectBase gets fully configured to anchor the inheritance tree properly.
Definition: object-base.cc:56
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:343
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:85
virtual ~ObjectBase()
Virtual destructor.
Definition: object-base.cc:73
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising errors.
Definition: object-base.cc:281
virtual void NotifyConstructionCompleted()
Notifier called once the ObjectBase is fully constructed.
Definition: object-base.cc:79
static TypeId GetTypeId()
Get the type ID.
Definition: object-base.cc:66
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
bool TraceConnect(std::string name, std::string context, const CallbackBase &cb)
Connect a TraceSource to a Callback with a context.
Definition: object-base.cc:329
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:189
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Hold variables of type string.
Definition: string.h:56
a unique identifier for an interface.
Definition: type-id.h:59
@ ATTR_GET
The attribute can be read.
Definition: type-id.h:64
@ ATTR_SET
The attribute can be written.
Definition: type-id.h:65
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
Definition: type-id.h:66
std::string GetAttributeFullName(std::size_t i) const
Get the Attribute name by index.
Definition: type-id.cc:1115
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
TypeId SetGroupName(std::string groupName)
Set the group name.
Definition: type-id.cc:939
Ptr< const TraceSourceAccessor > LookupTraceSourceByName(std::string name) const
Find a TraceSource by name.
Definition: type-id.cc:1198
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1108
bool LookupAttributeByName(std::string name, AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:893
std::string GetName() const
Get the name.
Definition: type-id.cc:991
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.
template Callback< ObjectBase * > MakeCallback< ObjectBase * >(ObjectBase *(*)())
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449
ns3::ObjectBase declaration and NS_OBJECT_ENSURE_REGISTERED() macro definition.
ns3::StringValue attribute value declarations.
Attribute implementation.
Definition: type-id.h:81
std::string name
Attribute name.
Definition: type-id.h:83
Ptr< const AttributeAccessor > accessor
Accessor object.
Definition: type-id.h:93
uint32_t flags
AttributeFlags value.
Definition: type-id.h:87
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:95
Ptr< const AttributeValue > initialValue
Configured initial value.
Definition: type-id.h:91
ns3::TraceSourceAccessor and ns3::MakeTraceSourceAccessor declarations.