A Discrete-Event Network Simulator
API
object-factory.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-factory.h"
20 
21 #include "log.h"
22 
23 #include <sstream>
24 
31 namespace ns3
32 {
33 
34 NS_LOG_COMPONENT_DEFINE("ObjectFactory");
35 
37 {
38  NS_LOG_FUNCTION(this);
39 }
40 
41 void
43 {
44  NS_LOG_FUNCTION(this << tid.GetName());
45  m_tid = tid;
46 }
47 
48 void
49 ObjectFactory::SetTypeId(std::string tid)
50 {
51  NS_LOG_FUNCTION(this << tid);
53 }
54 
55 bool
57 {
58  return m_tid.GetUid() != 0;
59 }
60 
61 void
62 ObjectFactory::DoSet(const std::string& name, const AttributeValue& value)
63 {
64  NS_LOG_FUNCTION(this << name << &value);
65  if (name.empty())
66  {
67  return;
68  }
69 
71  if (!m_tid.LookupAttributeByName(name, &info))
72  {
73  NS_FATAL_ERROR("Invalid attribute set (" << name << ") on " << m_tid.GetName());
74  return;
75  }
76  Ptr<AttributeValue> v = info.checker->CreateValidValue(value);
77  if (!v)
78  {
79  NS_FATAL_ERROR("Invalid value for attribute set (" << name << ") on " << m_tid.GetName());
80  return;
81  }
82  m_parameters.Add(name, info.checker, value.Copy());
83 }
84 
85 TypeId
87 {
88  NS_LOG_FUNCTION(this);
89  return m_tid;
90 }
91 
94 {
95  NS_LOG_FUNCTION(this);
97  ObjectBase* base = cb();
98  auto derived = dynamic_cast<Object*>(base);
99  NS_ASSERT(derived != nullptr);
100  derived->SetTypeId(m_tid);
101  derived->Construct(m_parameters);
102  Ptr<Object> object = Ptr<Object>(derived, false);
103  return object;
104 }
105 
106 std::ostream&
107 operator<<(std::ostream& os, const ObjectFactory& factory)
108 {
109  os << factory.m_tid.GetName() << "[";
110  bool first = true;
111  for (auto i = factory.m_parameters.Begin(); i != factory.m_parameters.End(); ++i)
112  {
113  os << i->name << "=" << i->value->SerializeToString(i->checker);
114  if (first)
115  {
116  os << "|";
117  }
118  }
119  os << "]";
120  return os;
121 }
122 
123 std::istream&
124 operator>>(std::istream& is, ObjectFactory& factory)
125 {
126  std::string v;
127  is >> v;
128  std::string::size_type lbracket;
129  std::string::size_type rbracket;
130  lbracket = v.find('[');
131  rbracket = v.find(']');
132  if (lbracket == std::string::npos && rbracket == std::string::npos)
133  {
134  factory.SetTypeId(v);
135  return is;
136  }
137  if (lbracket == std::string::npos || rbracket == std::string::npos)
138  {
139  return is;
140  }
141  NS_ASSERT(lbracket != std::string::npos);
142  NS_ASSERT(rbracket != std::string::npos);
143  std::string tid = v.substr(0, lbracket);
144  std::string parameters = v.substr(lbracket + 1, rbracket - (lbracket + 1));
145  factory.SetTypeId(tid);
146  std::string::size_type cur;
147  cur = 0;
148  while (cur != parameters.size())
149  {
150  std::string::size_type equal = parameters.find('=', cur);
151  if (equal == std::string::npos)
152  {
153  is.setstate(std::ios_base::failbit);
154  break;
155  }
156  else
157  {
158  std::string name = parameters.substr(cur, equal - cur);
160  if (!factory.m_tid.LookupAttributeByName(name, &info))
161  {
162  is.setstate(std::ios_base::failbit);
163  break;
164  }
165  else
166  {
167  std::string::size_type next = parameters.find('|', cur);
168  std::string value;
169  if (next == std::string::npos)
170  {
171  value = parameters.substr(equal + 1, parameters.size() - (equal + 1));
172  cur = parameters.size();
173  }
174  else
175  {
176  value = parameters.substr(equal + 1, next - (equal + 1));
177  cur = next + 1;
178  }
179  Ptr<AttributeValue> val = info.checker->Create();
180  bool ok = val->DeserializeFromString(value, info.checker);
181  if (!ok)
182  {
183  is.setstate(std::ios_base::failbit);
184  break;
185  }
186  else
187  {
188  factory.m_parameters.Add(name, info.checker, val);
189  }
190  }
191  }
192  }
193  NS_ABORT_MSG_IF(is.bad(), "Failure to parse " << parameters);
194  return is;
195 }
196 
198 
199 } // namespace ns3
void Add(std::string name, Ptr< const AttributeChecker > checker, Ptr< AttributeValue > value)
Add an Attribute to the list.
Hold a value for an Attribute.
Definition: attribute.h:70
Callback template class.
Definition: callback.h:438
Anchor the ns-3 type and attribute system.
Definition: object-base.h:173
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
TypeId GetTypeId() const
Get the TypeId which will be created by this ObjectFactory.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
TypeId m_tid
The TypeId this factory will create.
ObjectFactory()
Default constructor.
void DoSet(const std::string &name, const AttributeValue &value)
Set an attribute to be set during construction.
AttributeConstructionList m_parameters
The list of attributes and values to be used in constructing objects by this factory.
bool IsTypeIdSet() const
Check if the ObjectFactory has been configured with a TypeId.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
Callback< ObjectBase * > GetConstructor() const
Get the constructor callback.
Definition: type-id.cc:1084
uint16_t GetUid() const
Get the internal id of this TypeId.
Definition: type-id.cc:1205
bool LookupAttributeByName(std::string name, AttributeInformation *info) const
Find an Attribute by name, retrieving the associated AttributeInformation.
Definition: type-id.cc:893
std::string GetName() const
Get the name.
Definition: type-id.cc:991
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Debug message logging.
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ATTRIBUTE_HELPER_CPP(ValueClassTest)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
ns3::ObjectFactory class declaration.
Attribute implementation.
Definition: type-id.h:81
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:95