A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 <stdlib.h>
28 #endif
29 
30 NS_LOG_COMPONENT_DEFINE ("ObjectBase");
31 
32 namespace ns3 {
33 
34 NS_OBJECT_ENSURE_REGISTERED (ObjectBase);
35 
36 static TypeId
38 {
39  TypeId tid = TypeId ("ns3::ObjectBase");
40  tid.SetParent (tid);
41  return tid;
42 }
43 
44 TypeId
46 {
47  static TypeId tid = GetObjectIid ();
48  return tid;
49 }
50 
52 {
53 }
54 
55 void
57 {}
58 
59 void
61 {
62  // loop over the inheritance tree back to the Object base class.
63  TypeId tid = GetInstanceTypeId ();
64  do {
65  // loop over all attributes in object type
66  NS_LOG_DEBUG ("construct tid="<<tid.GetName ()<<", params="<<tid.GetAttributeN ());
67  for (uint32_t i = 0; i < tid.GetAttributeN (); i++)
68  {
69  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
70  NS_LOG_DEBUG ("try to construct \""<< tid.GetName ()<<"::"<<
71  info.name <<"\"");
72  if (!(info.flags & TypeId::ATTR_CONSTRUCT))
73  {
74  continue;
75  }
76  bool found = false;
77  // is this attribute stored in this AttributeConstructionList instance ?
78  Ptr<AttributeValue> value = attributes.Find(info.checker);
79  if (value != 0)
80  {
81  // We have a matching attribute value.
82  if (DoSet (info.accessor, info.checker, *value))
83  {
84  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
85  info.name<<"\"");
86  found = true;
87  continue;
88  }
89  }
90  if (!found)
91  {
92  // No matching attribute value so we try to look at the env var.
93 #ifdef HAVE_GETENV
94  char *envVar = getenv ("NS_ATTRIBUTE_DEFAULT");
95  if (envVar != 0)
96  {
97  std::string env = std::string (envVar);
98  std::string::size_type cur = 0;
99  std::string::size_type next = 0;
100  while (next != std::string::npos)
101  {
102  next = env.find (";", cur);
103  std::string tmp = std::string (env, cur, next-cur);
104  std::string::size_type equal = tmp.find ("=");
105  if (equal != std::string::npos)
106  {
107  std::string name = tmp.substr (0, equal);
108  std::string value = tmp.substr (equal+1, tmp.size () - equal - 1);
109  if (name == tid.GetAttributeFullName (i))
110  {
111  if (DoSet (info.accessor, info.checker, StringValue (value)))
112  {
113  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
114  info.name <<"\" from env var");
115  found = true;
116  break;
117  }
118  }
119  }
120  cur = next + 1;
121  }
122  }
123 #endif /* HAVE_GETENV */
124  }
125  if (!found)
126  {
127  // No matching attribute value so we try to set the default value.
128  DoSet (info.accessor, info.checker, *info.initialValue);
129  NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
130  info.name <<"\" from initial value.");
131  }
132  }
133  tid = tid.GetParent ();
134  } while (tid != ObjectBase::GetTypeId ());
136 }
137 
138 bool
141  const AttributeValue &value)
142 {
143  Ptr<AttributeValue> v = checker->CreateValidValue (value);
144  if (v == 0)
145  {
146  return false;
147  }
148  bool ok = accessor->Set (this, *v);
149  return ok;
150 }
151 void
152 ObjectBase::SetAttribute (std::string name, const AttributeValue &value)
153 {
154  struct TypeId::AttributeInformation info;
155  TypeId tid = GetInstanceTypeId ();
156  if (!tid.LookupAttributeByName (name, &info))
157  {
158  NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
159  }
160  if (!(info.flags & TypeId::ATTR_SET) ||
161  !info.accessor->HasSetter ())
162  {
163  NS_FATAL_ERROR ("Attribute name="<<name<<" is not settable for this object: tid="<<tid.GetName ());
164  }
165  if (!DoSet (info.accessor, info.checker, value))
166  {
167  NS_FATAL_ERROR ("Attribute name="<<name<<" could not be set for this object: tid="<<tid.GetName ());
168  }
169 }
170 bool
171 ObjectBase::SetAttributeFailSafe (std::string name, const AttributeValue &value)
172 {
173  struct TypeId::AttributeInformation info;
174  TypeId tid = GetInstanceTypeId ();
175  if (!tid.LookupAttributeByName (name, &info))
176  {
177  return false;
178  }
179  if (!(info.flags & TypeId::ATTR_SET) ||
180  !info.accessor->HasSetter ())
181  {
182  return false;
183  }
184  return DoSet (info.accessor, info.checker, value);
185 }
186 
187 void
188 ObjectBase::GetAttribute (std::string name, AttributeValue &value) const
189 {
190  struct TypeId::AttributeInformation info;
191  TypeId tid = GetInstanceTypeId ();
192  if (!tid.LookupAttributeByName (name, &info))
193  {
194  NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
195  }
196  if (!(info.flags & TypeId::ATTR_GET) ||
197  !info.accessor->HasGetter ())
198  {
199  NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
200  }
201  bool ok = info.accessor->Get (this, value);
202  if (ok)
203  {
204  return;
205  }
206  StringValue *str = dynamic_cast<StringValue *> (&value);
207  if (str == 0)
208  {
209  NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": input value is not a string");
210  }
211  Ptr<AttributeValue> v = info.checker->Create ();
212  ok = info.accessor->Get (this, *PeekPointer (v));
213  if (!ok)
214  {
215  NS_FATAL_ERROR ("Attribute name="<<name<<" tid="<<tid.GetName () << ": could not get value");
216  }
217  str->Set (v->SerializeToString (info.checker));
218 }
219 
220 
221 bool
222 ObjectBase::GetAttributeFailSafe (std::string name, AttributeValue &value) const
223 {
224  struct TypeId::AttributeInformation info;
225  TypeId tid = GetInstanceTypeId ();
226  if (!tid.LookupAttributeByName (name, &info))
227  {
228  return false;
229  }
230  if (!(info.flags & TypeId::ATTR_GET) ||
231  !info.accessor->HasGetter ())
232  {
233  return false;
234  }
235  bool ok = info.accessor->Get (this, value);
236  if (ok)
237  {
238  return true;
239  }
240  StringValue *str = dynamic_cast<StringValue *> (&value);
241  if (str == 0)
242  {
243  return false;
244  }
245  Ptr<AttributeValue> v = info.checker->Create ();
246  ok = info.accessor->Get (this, *PeekPointer (v));
247  if (!ok)
248  {
249  return false;
250  }
251  str->Set (v->SerializeToString (info.checker));
252  return true;
253 }
254 
255 bool
257 {
258  TypeId tid = GetInstanceTypeId ();
260  if (accessor == 0)
261  {
262  return false;
263  }
264  bool ok = accessor->ConnectWithoutContext (this, cb);
265  return ok;
266 }
267 bool
268 ObjectBase::TraceConnect (std::string name, std::string context, const CallbackBase &cb)
269 {
270  TypeId tid = GetInstanceTypeId ();
272  if (accessor == 0)
273  {
274  return false;
275  }
276  bool ok = accessor->Connect (this, context, cb);
277  return ok;
278 }
279 bool
281 {
282  TypeId tid = GetInstanceTypeId ();
284  if (accessor == 0)
285  {
286  return false;
287  }
288  bool ok = accessor->DisconnectWithoutContext (this, cb);
289  return ok;
290 }
291 bool
292 ObjectBase::TraceDisconnect (std::string name, std::string context, const CallbackBase &cb)
293 {
294  TypeId tid = GetInstanceTypeId ();
296  if (accessor == 0)
297  {
298  return false;
299  }
300  bool ok = accessor->Disconnect (this, context, cb);
301  return ok;
302 }
303 
304 
305 
306 } // namespace ns3