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  return tid;
57 }
58 
59 TypeId
61 {
63  static TypeId tid = GetObjectIid ();
64  return tid;
65 }
66 
68 {
69  NS_LOG_FUNCTION (this);
70 }
71 
72 void
74 {
75  NS_LOG_FUNCTION (this);
76 }
77 
78 void
80 {
81  // loop over the inheritance tree back to the Object base class.
82  NS_LOG_FUNCTION (this << &attributes);
83  TypeId tid = GetInstanceTypeId ();
84  do {
85  // loop over all attributes in object type
86  NS_LOG_DEBUG ("construct tid="<<tid.GetName ()<<", params="<<tid.GetAttributeN ());
87  for (uint32_t i = 0; i < tid.GetAttributeN (); i++)
88  {
89  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
90  NS_LOG_DEBUG ("try to construct \""<< tid.GetName ()<<"::"<<
91  info.name <<"\"");
92  // is this attribute stored in this AttributeConstructionList instance ?
93  Ptr<AttributeValue> value = attributes.Find(info.checker);
94  // See if this attribute should not be set here in the
95  // constructor.
96  if (!(info.flags & TypeId::ATTR_CONSTRUCT))
97  {
98  // Handle this attribute if it should not be
99  // set here.
100  if (value == 0)
101  {
102  // Skip this attribute if it's not in the
103  // AttributeConstructionList.
104  continue;
105  }
106  else
107  {
108  // This is an error because this attribute is not
109  // settable in its constructor but is present in
110  // the AttributeConstructionList.
111  NS_FATAL_ERROR ("Attribute name="<<info.name<<" tid="<<tid.GetName () << ": initial value cannot be set using attributes");
112  }
113  }
114  bool found = false;
115  if (value != 0)
116  {
117  // We have a matching attribute value.
118  if (DoSet (info.accessor, info.checker, *value))
119  {
120  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
121  info.name<<"\"");
122  found = true;
123  continue;
124  }
125  }
126  if (!found)
127  {
128  // No matching attribute value so we try to look at the env var.
129 #ifdef HAVE_GETENV
130  char *envVar = getenv ("NS_ATTRIBUTE_DEFAULT");
131  if (envVar != 0)
132  {
133  std::string env = std::string (envVar);
134  std::string::size_type cur = 0;
135  std::string::size_type next = 0;
136  while (next != std::string::npos)
137  {
138  next = env.find (";", cur);
139  std::string tmp = std::string (env, cur, next-cur);
140  std::string::size_type equal = tmp.find ("=");
141  if (equal != std::string::npos)
142  {
143  std::string name = tmp.substr (0, equal);
144  std::string value = tmp.substr (equal+1, tmp.size () - equal - 1);
145  if (name == tid.GetAttributeFullName (i))
146  {
147  if (DoSet (info.accessor, info.checker, StringValue (value)))
148  {
149  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
150  info.name <<"\" from env var");
151  found = true;
152  break;
153  }
154  }
155  }
156  cur = next + 1;
157  }
158  }
159 #endif /* HAVE_GETENV */
160  }
161  if (!found)
162  {
163  // No matching attribute value so we try to set the default value.
164  DoSet (info.accessor, info.checker, *info.initialValue);
165  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
166  info.name <<"\" from initial value.");
167  }
168  }
169  tid = tid.GetParent ();
170  } while (tid != ObjectBase::GetTypeId ());
172 }
173 
174 bool
177  const AttributeValue &value)
178 {
179  NS_LOG_FUNCTION (this << accessor << checker << &value);
180  Ptr<AttributeValue> v = checker->CreateValidValue (value);
181  if (v == 0)
182  {
183  return false;
184  }
185  bool ok = accessor->Set (this, *v);
186  return ok;
187 }
188 
189 void
190 ObjectBase::SetAttribute (std::string name, const AttributeValue &value)
191 {
192  NS_LOG_FUNCTION (this << name << &value);
193  struct TypeId::AttributeInformation info;
194  TypeId tid = GetInstanceTypeId ();
195  if (!tid.LookupAttributeByName (name, &info))
196  {
197  NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
198  }
199  if (!(info.flags & TypeId::ATTR_SET) ||
200  !info.accessor->HasSetter ())
201  {
202  NS_FATAL_ERROR ("Attribute name="<<name<<" is not settable for this object: tid="<<tid.GetName ());
203  }
204  if (!DoSet (info.accessor, info.checker, value))
205  {
206  NS_FATAL_ERROR ("Attribute name="<<name<<" could not be set for this object: tid="<<tid.GetName ());
207  }
208 }
209 bool
210 ObjectBase::SetAttributeFailSafe (std::string name, const AttributeValue &value)
211 {
212  NS_LOG_FUNCTION (this << name << &value);
213  struct TypeId::AttributeInformation info;
214  TypeId tid = GetInstanceTypeId ();
215  if (!tid.LookupAttributeByName (name, &info))
216  {
217  return false;
218  }
219  if (!(info.flags & TypeId::ATTR_SET) ||
220  !info.accessor->HasSetter ())
221  {
222  return false;
223  }
224  return DoSet (info.accessor, info.checker, value);
225 }
226 
227 void
228 ObjectBase::GetAttribute (std::string name, AttributeValue &value) const
229 {
230  NS_LOG_FUNCTION (this << name << &value);
231  struct TypeId::AttributeInformation info;
232  TypeId tid = GetInstanceTypeId ();
233  if (!tid.LookupAttributeByName (name, &info))
234  {
235  NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
236  }
237  if (!(info.flags & TypeId::ATTR_GET) ||
238  !info.accessor->HasGetter ())
239  {
240  NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
241  }
242  bool ok = info.accessor->Get (this, value);
243  if (ok)
244  {
245  return;
246  }
247  StringValue *str = dynamic_cast<StringValue *> (&value);
248  if (str == 0)
249  {
250  NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": input value is not a string");
251  }
252  Ptr<AttributeValue> v = info.checker->Create ();
253  ok = info.accessor->Get (this, *PeekPointer (v));
254  if (!ok)
255  {
256  NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": could not get value");
257  }
258  str->Set (v->SerializeToString (info.checker));
259 }
260 
261 
262 bool
263 ObjectBase::GetAttributeFailSafe (std::string name, AttributeValue &value) const
264 {
265  NS_LOG_FUNCTION (this << name << &value);
266  struct TypeId::AttributeInformation info;
267  TypeId tid = GetInstanceTypeId ();
268  if (!tid.LookupAttributeByName (name, &info))
269  {
270  return false;
271  }
272  if (!(info.flags & TypeId::ATTR_GET) ||
273  !info.accessor->HasGetter ())
274  {
275  return false;
276  }
277  bool ok = info.accessor->Get (this, value);
278  if (ok)
279  {
280  return true;
281  }
282  StringValue *str = dynamic_cast<StringValue *> (&value);
283  if (str == 0)
284  {
285  return false;
286  }
287  Ptr<AttributeValue> v = info.checker->Create ();
288  ok = info.accessor->Get (this, *PeekPointer (v));
289  if (!ok)
290  {
291  return false;
292  }
293  str->Set (v->SerializeToString (info.checker));
294  return true;
295 }
296 
297 bool
299 {
300  NS_LOG_FUNCTION (this << name << &cb);
301  TypeId tid = GetInstanceTypeId ();
303  if (accessor == 0)
304  {
305  return false;
306  }
307  bool ok = accessor->ConnectWithoutContext (this, cb);
308  return ok;
309 }
310 bool
311 ObjectBase::TraceConnect (std::string name, std::string context, const CallbackBase &cb)
312 {
313  NS_LOG_FUNCTION (this << name << context << &cb);
314  TypeId tid = GetInstanceTypeId ();
316  if (accessor == 0)
317  {
318  return false;
319  }
320  bool ok = accessor->Connect (this, context, cb);
321  return ok;
322 }
323 bool
325 {
326  NS_LOG_FUNCTION (this << name << &cb);
327  TypeId tid = GetInstanceTypeId ();
329  if (accessor == 0)
330  {
331  return false;
332  }
333  bool ok = accessor->DisconnectWithoutContext (this, cb);
334  return ok;
335 }
336 bool
337 ObjectBase::TraceDisconnect (std::string name, std::string context, const CallbackBase &cb)
338 {
339  NS_LOG_FUNCTION (this << name << context << &cb);
340  TypeId tid = GetInstanceTypeId ();
342  if (accessor == 0)
343  {
344  return false;
345  }
346  bool ok = accessor->Disconnect (this, context, cb);
347  return ok;
348 }
349 
350 
351 
352 } // namespace ns3
uint32_t GetAttributeN(void) const
Definition: type-id.cc:780
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:67
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
Definition: type-id.cc:659
Base class for Callback class.
Definition: callback.h:906
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:210
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
static TypeId GetTypeId(void)
Get the type ID.
Definition: object-base.cc:60
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
The attribute can be written at construction-time.
Definition: type-id.h:66
bool GetAttributeFailSafe(std::string name, AttributeValue &value) const
Get the value of an attribute without raising erros.
Definition: object-base.cc:263
The attribute can be read.
Definition: type-id.h:64
Ptr< AttributeValue > Find(Ptr< const AttributeChecker > checker) const
Find an Attribute in the list from its AttributeChecker.
ns3::AttributeConstructionList declaration.
Ptr< const AttributeAccessor > accessor
Definition: type-id.h:75
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
Definition: type-id.cc:842
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:337
Ptr< const AttributeValue > initialValue
Definition: type-id.h:74
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:73
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
Definition: object-base.cc:324
Ptr< const AttributeChecker > checker
Definition: type-id.h:76
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:298
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::TraceSourceAccessor and ns3::MakeTraceSourceAccessor declarations.
The attribute can be written.
Definition: type-id.h:65
void ConstructSelf(const AttributeConstructionList &attributes)
Complete construction of ObjectBase; invoked by derived classes.
Definition: object-base.cc:79
std::string GetName(void) const
Definition: type-id.cc:692
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:228
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:175
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:311
std::string GetAttributeFullName(uint32_t i) const
Definition: type-id.cc:793
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Definition: type-id.cc:787
Debug message logging.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:190
a unique identifier for an interface.
Definition: type-id.h:57
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638