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
22#include "log.h"
23#include "string.h"
25
26#include "ns3/core-config.h"
27
28#include <cstdlib> // getenv
29#include <cstring> // strlen
30#include <unordered_map>
31
38namespace ns3
39{
40
41NS_LOG_COMPONENT_DEFINE("ObjectBase");
42
44
46namespace
47{
48
55std::pair<bool, std::string>
56EnvDictionary(std::string key)
57{
58 static std::unordered_map<std::string, std::string> dict;
59
60 if (dict.size() == 0)
61 {
62 const char* envVar = getenv("NS_ATTRIBUTE_DEFAULT");
63 if (envVar != nullptr && std::strlen(envVar) > 0)
64 {
65 std::string env = envVar;
66 std::string::size_type cur = 0;
67 std::string::size_type next = 0;
68 while (next != std::string::npos)
69 {
70 next = env.find(';', cur);
71 std::string tmp = std::string(env, cur, next - cur);
72 std::string::size_type equal = tmp.find('=');
73 if (equal != std::string::npos)
74 {
75 std::string name = tmp.substr(0, equal);
76 std::string envval = tmp.substr(equal + 1, tmp.size() - equal - 1);
77 dict.insert({name, envval});
78 }
79 cur = next + 1;
80 }
81 }
82 else
83 {
84 // insert an empty key, so we don't do this again
85 dict.insert({"", ""});
86 }
87 }
88
89 std::string value;
90 bool found{false};
91
92 auto loc = dict.find(key);
93 if (loc != dict.end())
94 {
95 value = loc->second;
96 found = true;
97 }
98 return {found, value};
99}
100
101} // unnamed namespace
102
111static TypeId
113{
115 TypeId tid = TypeId("ns3::ObjectBase");
116 tid.SetParent(tid);
117 tid.SetGroupName("Core");
118 return tid;
119}
120
121TypeId
123{
125 static TypeId tid = GetObjectIid();
126 return tid;
127}
128
130{
131 NS_LOG_FUNCTION(this);
132}
133
134void
136{
137 NS_LOG_FUNCTION(this);
138}
139
146#ifdef NS3_LOG_ENABLE
147#define LOG_WHERE_VALUE(where, value) \
148 do \
149 { \
150 std::string valStr{"nothing"}; \
151 if (value) \
152 { \
153 valStr = "\"" + value->SerializeToString(info.checker) + "\""; \
154 } \
155 NS_LOG_DEBUG(where << " gave " << valStr); \
156 } while (false)
157#else
158#define LOG_WHERE_VALUE(where, value)
159#endif
160
161void
163{
164 // loop over the inheritance tree back to the Object base class.
165 NS_LOG_FUNCTION(this << &attributes);
167 do // Do this tid and all parents
168 {
169 // loop over all attributes in object type
170 NS_LOG_DEBUG("construct tid=" << tid.GetName() << ", params=" << tid.GetAttributeN());
171 for (uint32_t i = 0; i < tid.GetAttributeN(); i++)
172 {
173 struct TypeId::AttributeInformation info = tid.GetAttribute(i);
174 NS_LOG_DEBUG("try to construct \"" << tid.GetName() << "::" << info.name << "\"");
175
176 Ptr<const AttributeValue> value = attributes.Find(info.checker);
177 std::string where = "argument";
178
179 LOG_WHERE_VALUE(where, value);
180 // See if this attribute should not be set here in the
181 // constructor.
182 if (!(info.flags & TypeId::ATTR_CONSTRUCT))
183 {
184 // Handle this attribute if it should not be
185 // set here.
186 if (!value)
187 {
188 // Skip this attribute if it's not in the
189 // AttributeConstructionList.
190 NS_LOG_DEBUG("skipping, not settable at construction");
191 continue;
192 }
193 else
194 {
195 // This is an error because this attribute is not
196 // settable in its constructor but is present in
197 // the AttributeConstructionList.
198 NS_FATAL_ERROR("Attribute name="
199 << info.name << " tid=" << tid.GetName()
200 << ": initial value cannot be set using attributes");
201 }
202 }
203
204 if (!value)
205 {
206 auto [found, val] = EnvDictionary(tid.GetAttributeFullName(i));
207 if (found)
208 {
209 value = Create<StringValue>(val);
210 where = "env var";
211 LOG_WHERE_VALUE(where, value);
212 }
213 }
214
215 bool initial = false;
216 if (!value)
217 {
218 // Set from Tid initialValue, which is guaranteed to exist
219 value = info.initialValue;
220 where = "initial value";
221 initial = true;
222 LOG_WHERE_VALUE(where, value);
223 }
224
225 if (DoSet(info.accessor, info.checker, *value) || initial)
226 {
227 // Setting from initial value may fail, e.g. setting
228 // ObjectVectorValue from ""
229 // That's ok, so we still report success since construction is complete
230 NS_LOG_DEBUG("construct \"" << tid.GetName() << "::" << info.name << "\" from "
231 << where);
232 }
233
234 } // for i attributes
235 tid = tid.GetParent();
236 } while (tid != ObjectBase::GetTypeId());
238}
239
240#undef LOG_WHERE_VALUE
241
242bool
245 const AttributeValue& value)
246{
247 NS_LOG_FUNCTION(this << accessor << checker << &value);
248 Ptr<AttributeValue> v = checker->CreateValidValue(value);
249 if (!v)
250 {
251 return false;
252 }
253 bool ok = accessor->Set(this, *v);
254 return ok;
255}
256
257void
259{
260 NS_LOG_FUNCTION(this << name << &value);
263 if (!tid.LookupAttributeByName(name, &info))
264 {
266 "Attribute name=" << name << " does not exist for this object: tid=" << tid.GetName());
267 }
268 if (!(info.flags & TypeId::ATTR_SET) || !info.accessor->HasSetter())
269 {
271 "Attribute name=" << name << " is not settable for this object: tid=" << tid.GetName());
272 }
273 if (!DoSet(info.accessor, info.checker, value))
274 {
275 NS_FATAL_ERROR("Attribute name=" << name << " could not be set for this object: tid="
276 << tid.GetName());
277 }
278}
279
280bool
282{
283 NS_LOG_FUNCTION(this << name << &value);
286 if (!tid.LookupAttributeByName(name, &info))
287 {
288 return false;
289 }
290 if (!(info.flags & TypeId::ATTR_SET) || !info.accessor->HasSetter())
291 {
292 return false;
293 }
294 return DoSet(info.accessor, info.checker, value);
295}
296
297void
299{
300 NS_LOG_FUNCTION(this << name << &value);
303 if (!tid.LookupAttributeByName(name, &info))
304 {
306 "Attribute name=" << name << " does not exist for this object: tid=" << tid.GetName());
307 }
308 if (!(info.flags & TypeId::ATTR_GET) || !info.accessor->HasGetter())
309 {
311 "Attribute name=" << name << " is not gettable for this object: tid=" << tid.GetName());
312 }
313 bool ok = info.accessor->Get(this, value);
314 if (ok)
315 {
316 return;
317 }
318 StringValue* str = dynamic_cast<StringValue*>(&value);
319 if (str == nullptr)
320 {
321 NS_FATAL_ERROR("Attribute name=" << name << " tid=" << tid.GetName()
322 << ": input value is not a string");
323 }
324 Ptr<AttributeValue> v = info.checker->Create();
325 ok = info.accessor->Get(this, *PeekPointer(v));
326 if (!ok)
327 {
328 NS_FATAL_ERROR("Attribute name=" << name << " tid=" << tid.GetName()
329 << ": could not get value");
330 }
331 str->Set(v->SerializeToString(info.checker));
332}
333
334bool
336{
337 NS_LOG_FUNCTION(this << name << &value);
340 if (!tid.LookupAttributeByName(name, &info))
341 {
342 return false;
343 }
344 if (!(info.flags & TypeId::ATTR_GET) || !info.accessor->HasGetter())
345 {
346 return false;
347 }
348 bool ok = info.accessor->Get(this, value);
349 if (ok)
350 {
351 return true;
352 }
353 StringValue* str = dynamic_cast<StringValue*>(&value);
354 if (str == nullptr)
355 {
356 return false;
357 }
358 Ptr<AttributeValue> v = info.checker->Create();
359 ok = info.accessor->Get(this, *PeekPointer(v));
360 if (!ok)
361 {
362 return false;
363 }
364 str->Set(v->SerializeToString(info.checker));
365 return true;
366}
367
368bool
370{
371 NS_LOG_FUNCTION(this << name << &cb);
374 if (!accessor)
375 {
376 return false;
377 }
378 bool ok = accessor->ConnectWithoutContext(this, cb);
379 return ok;
380}
381
382bool
383ObjectBase::TraceConnect(std::string name, std::string context, const CallbackBase& cb)
384{
385 NS_LOG_FUNCTION(this << name << context << &cb);
388 if (!accessor)
389 {
390 return false;
391 }
392 bool ok = accessor->Connect(this, context, cb);
393 return ok;
394}
395
396bool
398{
399 NS_LOG_FUNCTION(this << name << &cb);
402 if (!accessor)
403 {
404 return false;
405 }
406 bool ok = accessor->DisconnectWithoutContext(this, cb);
407 return ok;
408}
409
410bool
411ObjectBase::TraceDisconnect(std::string name, std::string context, const CallbackBase& cb)
412{
413 NS_LOG_FUNCTION(this << name << context << &cb);
416 if (!accessor)
417 {
418 return false;
419 }
420 bool ok = accessor->Disconnect(this, context, cb);
421 return ok;
422}
423
424} // namespace ns3
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
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:369
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:411
static TypeId GetObjectIid()
Ensure the TypeId for ObjectBase gets fully configured to anchor the inheritance tree properly.
Definition: object-base.cc:112
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:397
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:162
virtual ~ObjectBase()
Virtual destructor.
Definition: object-base.cc:129
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising erros.
Definition: object-base.cc:335
virtual void NotifyConstructionCompleted()
Notifier called once the ObjectBase is fully constructed.
Definition: object-base.cc:135
static TypeId GetTypeId()
Get the type ID.
Definition: object-base.cc:122
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:281
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:258
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:298
bool TraceConnect(std::string name, std::string context, const CallbackBase &cb)
Connect a TraceSource to a Callback with a context.
Definition: object-base.cc:383
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:243
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Hold variables of type string.
Definition: string.h:42
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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#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:45
Debug message logging.
std::pair< bool, std::string > EnvDictionary(std::string key)
Get key, value pairs from the "NS_ATTRIBUTE_DEFAULT" environment variable.
Definition: object-base.cc:56
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
#define LOG_WHERE_VALUE(where, value)
Log where and what value we find for the attribute.
Definition: object-base.cc:147
ns3::ObjectBase declaration and NS_OBJECT_ENSURE_REGISTERED() madro 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.