A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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"
24#include "log.h"
25#include "string.h"
27
28#include "ns3/core-config.h"
29
36namespace ns3
37{
38
39NS_LOG_COMPONENT_DEFINE("ObjectBase");
40
42
51static TypeId
53{
55 TypeId tid = TypeId("ns3::ObjectBase");
56 tid.SetParent(tid);
57 tid.SetGroupName("Core");
58 return tid;
59}
60
63{
65 static TypeId tid = GetObjectIid();
66 return tid;
67}
68
70{
71 NS_LOG_FUNCTION(this);
72}
73
74void
76{
77 NS_LOG_FUNCTION(this);
78}
79
80void
82{
83 // loop over the inheritance tree back to the Object base class.
84 NS_LOG_FUNCTION(this << &attributes);
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 {
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
184bool
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
199void
200ObjectBase::SetAttribute(std::string name, const AttributeValue& value)
201{
202 NS_LOG_FUNCTION(this << name << &value);
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
222bool
224{
225 NS_LOG_FUNCTION(this << name << &value);
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
239void
240ObjectBase::GetAttribute(std::string name, AttributeValue& value) const
241{
242 NS_LOG_FUNCTION(this << name << &value);
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
276bool
278{
279 NS_LOG_FUNCTION(this << name << &value);
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
310bool
312{
313 NS_LOG_FUNCTION(this << name << &cb);
316 if (!accessor)
317 {
318 return false;
319 }
320 bool ok = accessor->ConnectWithoutContext(this, cb);
321 return ok;
322}
323
324bool
325ObjectBase::TraceConnect(std::string name, std::string context, const CallbackBase& cb)
326{
327 NS_LOG_FUNCTION(this << name << context << &cb);
330 if (!accessor)
331 {
332 return false;
333 }
334 bool ok = accessor->Connect(this, context, cb);
335 return ok;
336}
337
338bool
340{
341 NS_LOG_FUNCTION(this << name << &cb);
344 if (!accessor)
345 {
346 return false;
347 }
348 bool ok = accessor->DisconnectWithoutContext(this, cb);
349 return ok;
350}
351
352bool
353ObjectBase::TraceDisconnect(std::string name, std::string context, const CallbackBase& cb)
354{
355 NS_LOG_FUNCTION(this << name << context << &cb);
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:360
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: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:1120
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
TypeId SetGroupName(std::string groupName)
Set the group name.
Definition: type-id.cc:944
Ptr< const TraceSourceAccessor > LookupTraceSourceByName(std::string name) const
Find a TraceSource by name.
Definition: type-id.cc:1203
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1113
bool LookupAttributeByName(std::string name, AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:898
std::string GetName() const
Get the name.
Definition: type-id.cc:996
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
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.