A Discrete-Event Network Simulator
API
object-base.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "object-base.h"
21 #include "log.h"
22 #include "trace-source-accessor.h"
24 #include "string.h"
25 #include "ns3/core-config.h"
26 #ifdef HAVE_STDLIB_H
27 #include <cstdlib>
28 #endif
29 
36 namespace ns3 {
37 
38 NS_LOG_COMPONENT_DEFINE ("ObjectBase");
39 
40 NS_OBJECT_ENSURE_REGISTERED (ObjectBase);
41 
50 static TypeId
52 {
54  TypeId tid = TypeId ("ns3::ObjectBase");
55  tid.SetParent (tid);
56  tid.SetGroupName ("Core");
57  return tid;
58 }
59 
60 TypeId
62 {
64  static TypeId tid = GetObjectIid ();
65  return tid;
66 }
67 
69 {
70  NS_LOG_FUNCTION (this);
71 }
72 
73 void
75 {
76  NS_LOG_FUNCTION (this);
77 }
78 
79 void
81 {
82  // loop over the inheritance tree back to the Object base class.
83  NS_LOG_FUNCTION (this << &attributes);
84  TypeId tid = GetInstanceTypeId ();
85  do {
86  // loop over all attributes in object type
87  NS_LOG_DEBUG ("construct tid="<<tid.GetName ()<<", params="<<tid.GetAttributeN ());
88  for (uint32_t i = 0; i < tid.GetAttributeN (); i++)
89  {
90  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
91  NS_LOG_DEBUG ("try to construct \""<< tid.GetName ()<<"::"<<
92  info.name <<"\"");
93  // is this attribute stored in this AttributeConstructionList instance ?
94  Ptr<AttributeValue> value = attributes.Find(info.checker);
95  // See if this attribute should not be set here in the
96  // constructor.
97  if (!(info.flags & TypeId::ATTR_CONSTRUCT))
98  {
99  // Handle this attribute if it should not be
100  // set here.
101  if (value == 0)
102  {
103  // Skip this attribute if it's not in the
104  // AttributeConstructionList.
105  continue;
106  }
107  else
108  {
109  // This is an error because this attribute is not
110  // settable in its constructor but is present in
111  // the AttributeConstructionList.
112  NS_FATAL_ERROR ("Attribute name="<<info.name<<" tid="<<tid.GetName () << ": initial value cannot be set using attributes");
113  }
114  }
115  bool found = false;
116  if (value != 0)
117  {
118  // We have a matching attribute value.
119  if (DoSet (info.accessor, info.checker, *value))
120  {
121  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
122  info.name<<"\"");
123  found = true;
124  continue;
125  }
126  }
127  if (!found)
128  {
129  // No matching attribute value so we try to look at the env var.
130 #ifdef HAVE_GETENV
131  char *envVar = getenv ("NS_ATTRIBUTE_DEFAULT");
132  if (envVar != 0)
133  {
134  std::string env = std::string (envVar);
135  std::string::size_type cur = 0;
136  std::string::size_type next = 0;
137  while (next != std::string::npos)
138  {
139  next = env.find (";", cur);
140  std::string tmp = std::string (env, cur, next-cur);
141  std::string::size_type equal = tmp.find ("=");
142  if (equal != std::string::npos)
143  {
144  std::string name = tmp.substr (0, equal);
145  std::string value = tmp.substr (equal+1, tmp.size () - equal - 1);
146  if (name == tid.GetAttributeFullName (i))
147  {
148  if (DoSet (info.accessor, info.checker, StringValue (value)))
149  {
150  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
151  info.name <<"\" from env var");
152  found = true;
153  break;
154  }
155  }
156  }
157  cur = next + 1;
158  }
159  }
160 #endif /* HAVE_GETENV */
161  }
162  if (!found)
163  {
164  // No matching attribute value so we try to set the default value.
165  DoSet (info.accessor, info.checker, *info.initialValue);
166  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
167  info.name <<"\" from initial value.");
168  }
169  }
170  tid = tid.GetParent ();
171  } while (tid != ObjectBase::GetTypeId ());
173 }
174 
175 bool
178  const AttributeValue &value)
179 {
180  NS_LOG_FUNCTION (this << accessor << checker << &value);
181  Ptr<AttributeValue> v = checker->CreateValidValue (value);
182  if (v == 0)
183  {
184  return false;
185  }
186  bool ok = accessor->Set (this, *v);
187  return ok;
188 }
189 
190 void
191 ObjectBase::SetAttribute (std::string name, const AttributeValue &value)
192 {
193  NS_LOG_FUNCTION (this << name << &value);
194  struct TypeId::AttributeInformation info;
195  TypeId tid = GetInstanceTypeId ();
196  if (!tid.LookupAttributeByName (name, &info))
197  {
198  NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
199  }
200  if (!(info.flags & TypeId::ATTR_SET) ||
201  !info.accessor->HasSetter ())
202  {
203  NS_FATAL_ERROR ("Attribute name="<<name<<" is not settable for this object: tid="<<tid.GetName ());
204  }
205  if (!DoSet (info.accessor, info.checker, value))
206  {
207  NS_FATAL_ERROR ("Attribute name="<<name<<" could not be set for this object: tid="<<tid.GetName ());
208  }
209 }
210 bool
211 ObjectBase::SetAttributeFailSafe (std::string name, const AttributeValue &value)
212 {
213  NS_LOG_FUNCTION (this << name << &value);
214  struct TypeId::AttributeInformation info;
215  TypeId tid = GetInstanceTypeId ();
216  if (!tid.LookupAttributeByName (name, &info))
217  {
218  return false;
219  }
220  if (!(info.flags & TypeId::ATTR_SET) ||
221  !info.accessor->HasSetter ())
222  {
223  return false;
224  }
225  return DoSet (info.accessor, info.checker, value);
226 }
227 
228 void
229 ObjectBase::GetAttribute (std::string name, AttributeValue &value) const
230 {
231  NS_LOG_FUNCTION (this << name << &value);
232  struct TypeId::AttributeInformation info;
233  TypeId tid = GetInstanceTypeId ();
234  if (!tid.LookupAttributeByName (name, &info))
235  {
236  NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
237  }
238  if (!(info.flags & TypeId::ATTR_GET) ||
239  !info.accessor->HasGetter ())
240  {
241  NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
242  }
243  bool ok = info.accessor->Get (this, value);
244  if (ok)
245  {
246  return;
247  }
248  StringValue *str = dynamic_cast<StringValue *> (&value);
249  if (str == 0)
250  {
251  NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": input value is not a string");
252  }
253  Ptr<AttributeValue> v = info.checker->Create ();
254  ok = info.accessor->Get (this, *PeekPointer (v));
255  if (!ok)
256  {
257  NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": could not get value");
258  }
259  str->Set (v->SerializeToString (info.checker));
260 }
261 
262 
263 bool
264 ObjectBase::GetAttributeFailSafe (std::string name, AttributeValue &value) const
265 {
266  NS_LOG_FUNCTION (this << name << &value);
267  struct TypeId::AttributeInformation info;
268  TypeId tid = GetInstanceTypeId ();
269  if (!tid.LookupAttributeByName (name, &info))
270  {
271  return false;
272  }
273  if (!(info.flags & TypeId::ATTR_GET) ||
274  !info.accessor->HasGetter ())
275  {
276  return false;
277  }
278  bool ok = info.accessor->Get (this, value);
279  if (ok)
280  {
281  return true;
282  }
283  StringValue *str = dynamic_cast<StringValue *> (&value);
284  if (str == 0)
285  {
286  return false;
287  }
288  Ptr<AttributeValue> v = info.checker->Create ();
289  ok = info.accessor->Get (this, *PeekPointer (v));
290  if (!ok)
291  {
292  return false;
293  }
294  str->Set (v->SerializeToString (info.checker));
295  return true;
296 }
297 
298 bool
300 {
301  NS_LOG_FUNCTION (this << name << &cb);
302  TypeId tid = GetInstanceTypeId ();
304  if (accessor == 0)
305  {
306  return false;
307  }
308  bool ok = accessor->ConnectWithoutContext (this, cb);
309  return ok;
310 }
311 bool
312 ObjectBase::TraceConnect (std::string name, std::string context, const CallbackBase &cb)
313 {
314  NS_LOG_FUNCTION (this << name << context << &cb);
315  TypeId tid = GetInstanceTypeId ();
317  if (accessor == 0)
318  {
319  return false;
320  }
321  bool ok = accessor->Connect (this, context, cb);
322  return ok;
323 }
324 bool
326 {
327  NS_LOG_FUNCTION (this << name << &cb);
328  TypeId tid = GetInstanceTypeId ();
330  if (accessor == 0)
331  {
332  return false;
333  }
334  bool ok = accessor->DisconnectWithoutContext (this, cb);
335  return ok;
336 }
337 bool
338 ObjectBase::TraceDisconnect (std::string name, std::string context, const CallbackBase &cb)
339 {
340  NS_LOG_FUNCTION (this << name << context << &cb);
341  TypeId tid = GetInstanceTypeId ();
343  if (accessor == 0)
344  {
345  return false;
346  }
347  bool ok = accessor->Disconnect (this, context, cb);
348  return ok;
349 }
350 
351 
352 
353 } // namespace ns3
uint32_t GetAttributeN(void) const
Get the number of attributes.
Definition: type-id.cc:1058
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#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:44
virtual ~ObjectBase()
Virtual destructor.
Definition: object-base.cc:68
Hold variables of type string.
Definition: string.h:41
void Set(const std::string &value)
Set the value.
Definition: string.cc:31
String attribute value declarations.
Hold a value for an Attribute.
Definition: attribute.h:68
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:562
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
TypeId GetParent(void) const
Get the parent of this TypeId.
Definition: type-id.cc:925
Base class for Callback class.
Definition: callback.h:1104
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:211
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
static TypeId GetTypeId(void)
Get the type ID.
Definition: object-base.cc:61
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising erros.
Definition: object-base.cc:264
The attribute can be written at construction-time.
Definition: type-id.h:65
Ptr< AttributeValue > Find(Ptr< const AttributeChecker > checker) const
Find an Attribute in the list from its AttributeChecker.
ns3::AttributeConstructionList declaration.
Ptr< const AttributeAccessor > accessor
Accessor object.
Definition: type-id.h:88
ns3::ObjectBase class declaration and NS_OBJECT_ENSURE_REGISTERED() definition.
static TypeId GetObjectIid(void)
Ensure the TypeId for ObjectBase gets fully configured to anchor the inheritance tree properly...
Definition: object-base.cc:51
Ptr< const TraceSourceAccessor > LookupTraceSourceByName(std::string name) const
Find a TraceSource by name.
Definition: type-id.cc:1165
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:338
Ptr< const AttributeValue > initialValue
Configured initial value.
Definition: type-id.h:86
List of Attribute name, value and checker triples used to construct Objects.
virtual void NotifyConstructionCompleted(void)
Notifier called once the ObjectBase is fully constructed.
Definition: object-base.cc:74
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:325
Attribute implementation.
Definition: type-id.h:76
uint32_t flags
AttributeFlags value.
Definition: type-id.h:82
TypeId SetGroupName(std::string groupName)
Set the group name.
Definition: type-id.cc:911
The attribute can be written.
Definition: type-id.h:64
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:90
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:299
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::string name
Attribute name.
Definition: type-id.h:78
ns3::TraceSourceAccessor and ns3::MakeTraceSourceAccessor declarations.
void ConstructSelf(const AttributeConstructionList &attributes)
Complete construction of ObjectBase; invoked by derived classes.
Definition: object-base.cc:80
std::string GetName(void) const
Get the name.
Definition: type-id.cc:958
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:229
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:176
The attribute can be read.
Definition: type-id.h:63
virtual TypeId GetInstanceTypeId(void) const =0
Get the most derived TypeId for this Object.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
bool TraceConnect(std::string name, std::string context, const CallbackBase &cb)
Connect a TraceSource to a Callback with a context.
Definition: object-base.cc:312
std::string GetAttributeFullName(uint32_t i) const
Get the Attribute name by index.
Definition: type-id.cc:1071
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Get Attribute information by index.
Definition: type-id.cc:1065
Debug message logging.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:191
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904