1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation;
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
17 */
18
19 #include "attribute-iterator.h"
20 #include "ns3/config.h"
21 #include "ns3/log.h"
22 #include "ns3/pointer.h"
23 #include "ns3/object-ptr-container.h"
24 #include "ns3/string.h"
25 #include <fstream>
26
27
28 namespace ns3 {
29
30 NS_LOG_COMPONENT_DEFINE ("AttributeIterator");
31
AttributeIterator()32 AttributeIterator::AttributeIterator ()
33 {
34 }
35
~AttributeIterator()36 AttributeIterator::~AttributeIterator ()
37 {
38 }
39
40 void
Iterate(void)41 AttributeIterator::Iterate (void)
42 {
43 for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
44 {
45 Ptr<Object> object = Config::GetRootNamespaceObject (i);
46 StartVisitObject (object);
47 DoIterate (object);
48 EndVisitObject ();
49 }
50 NS_ASSERT (m_currentPath.empty ());
51 NS_ASSERT (m_examined.empty ());
52 }
53
54 bool
IsExamined(Ptr<const Object> object)55 AttributeIterator::IsExamined (Ptr<const Object> object)
56 {
57 for (uint32_t i = 0; i < m_examined.size (); ++i)
58 {
59 if (object == m_examined[i])
60 {
61 return true;
62 }
63 }
64 return false;
65 }
66
67
68 std::string
GetCurrentPath(std::string attr) const69 AttributeIterator::GetCurrentPath (std::string attr) const
70 {
71 std::ostringstream oss;
72 for (uint32_t i = 0; i < m_currentPath.size (); ++i)
73 {
74 oss << "/" << m_currentPath[i];
75 }
76 if (attr != "")
77 {
78 oss << "/" << attr;
79 }
80 return oss.str ();
81 }
82
83 std::string
GetCurrentPath(void) const84 AttributeIterator::GetCurrentPath (void) const
85 {
86 std::ostringstream oss;
87 for (uint32_t i = 0; i < m_currentPath.size (); ++i)
88 {
89 oss << "/" << m_currentPath[i];
90 }
91 return oss.str ();
92 }
93
94 void
DoStartVisitObject(Ptr<Object> object)95 AttributeIterator::DoStartVisitObject (Ptr<Object> object)
96 {
97 }
98 void
DoEndVisitObject(void)99 AttributeIterator::DoEndVisitObject (void)
100 {
101 }
102 void
DoStartVisitPointerAttribute(Ptr<Object> object,std::string name,Ptr<Object> item)103 AttributeIterator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> item)
104 {
105 }
106 void
DoEndVisitPointerAttribute(void)107 AttributeIterator::DoEndVisitPointerAttribute (void)
108 {
109 }
110 void
DoStartVisitArrayAttribute(Ptr<Object> object,std::string name,const ObjectPtrContainerValue & vector)111 AttributeIterator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectPtrContainerValue &vector)
112 {
113 }
114 void
DoEndVisitArrayAttribute(void)115 AttributeIterator::DoEndVisitArrayAttribute (void)
116 {
117 }
118 void
DoStartVisitArrayItem(const ObjectPtrContainerValue & vector,uint32_t index,Ptr<Object> item)119 AttributeIterator::DoStartVisitArrayItem (const ObjectPtrContainerValue &vector, uint32_t index, Ptr<Object> item)
120 {
121 }
122 void
DoEndVisitArrayItem(void)123 AttributeIterator::DoEndVisitArrayItem (void)
124 {
125 }
126
127 void
VisitAttribute(Ptr<Object> object,std::string name)128 AttributeIterator::VisitAttribute (Ptr<Object> object, std::string name)
129 {
130 m_currentPath.push_back (name);
131 DoVisitAttribute (object, name);
132 m_currentPath.pop_back ();
133 }
134
135 void
StartVisitObject(Ptr<Object> object)136 AttributeIterator::StartVisitObject (Ptr<Object> object)
137 {
138 m_currentPath.push_back ("$" + object->GetInstanceTypeId ().GetName ());
139 DoStartVisitObject (object);
140 }
141 void
EndVisitObject(void)142 AttributeIterator::EndVisitObject (void)
143 {
144 m_currentPath.pop_back ();
145 DoEndVisitObject ();
146 }
147 void
StartVisitPointerAttribute(Ptr<Object> object,std::string name,Ptr<Object> value)148 AttributeIterator::StartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value)
149 {
150 m_currentPath.push_back (name);
151 m_currentPath.push_back ("$" + value->GetInstanceTypeId ().GetName ());
152 DoStartVisitPointerAttribute (object, name, value);
153 }
154 void
EndVisitPointerAttribute(void)155 AttributeIterator::EndVisitPointerAttribute (void)
156 {
157 m_currentPath.pop_back ();
158 m_currentPath.pop_back ();
159 DoEndVisitPointerAttribute ();
160 }
161 void
StartVisitArrayAttribute(Ptr<Object> object,std::string name,const ObjectPtrContainerValue & vector)162 AttributeIterator::StartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectPtrContainerValue &vector)
163 {
164 m_currentPath.push_back (name);
165 DoStartVisitArrayAttribute (object, name, vector);
166 }
167 void
EndVisitArrayAttribute(void)168 AttributeIterator::EndVisitArrayAttribute (void)
169 {
170 m_currentPath.pop_back ();
171 DoEndVisitArrayAttribute ();
172 }
173
174 void
StartVisitArrayItem(const ObjectPtrContainerValue & vector,uint32_t index,Ptr<Object> item)175 AttributeIterator::StartVisitArrayItem (const ObjectPtrContainerValue &vector, uint32_t index, Ptr<Object> item)
176 {
177 std::ostringstream oss;
178 oss << index;
179 m_currentPath.push_back (oss.str ());
180 m_currentPath.push_back ("$" + item->GetInstanceTypeId ().GetName ());
181 DoStartVisitArrayItem (vector, index, item);
182 }
183 void
EndVisitArrayItem(void)184 AttributeIterator::EndVisitArrayItem (void)
185 {
186 m_currentPath.pop_back ();
187 m_currentPath.pop_back ();
188 DoEndVisitArrayItem ();
189 }
190
191
192 void
DoIterate(Ptr<Object> object)193 AttributeIterator::DoIterate (Ptr<Object> object)
194 {
195 if (IsExamined (object))
196 {
197 return;
198 }
199 TypeId tid;
200 for (tid = object->GetInstanceTypeId (); tid.HasParent (); tid = tid.GetParent ())
201 {
202 NS_LOG_DEBUG ("store " << tid.GetName ());
203 for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
204 {
205 struct TypeId::AttributeInformation info = tid.GetAttribute(i);
206 const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
207 if (ptrChecker != 0)
208 {
209 NS_LOG_DEBUG ("pointer attribute " << info.name);
210 PointerValue ptr;
211 object->GetAttribute (info.name, ptr);
212 Ptr<Object> tmp = ptr.Get<Object> ();
213 if (tmp != 0)
214 {
215 StartVisitPointerAttribute (object, info.name,
216 tmp);
217 m_examined.push_back (object);
218 DoIterate (tmp);
219 m_examined.pop_back ();
220 EndVisitPointerAttribute ();
221 }
222 continue;
223 }
224 // attempt to cast to an object container
225 const ObjectPtrContainerChecker *vectorChecker = dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
226 if (vectorChecker != 0)
227 {
228 NS_LOG_DEBUG ("ObjectPtrContainer attribute " << info.name);
229 ObjectPtrContainerValue vector;
230 object->GetAttribute (info.name, vector);
231 StartVisitArrayAttribute (object, info.name, vector);
232 ObjectPtrContainerValue::Iterator it;
233 for (it = vector.Begin (); it != vector.End (); ++it)
234 {
235 uint32_t j = (*it).first;
236 NS_LOG_DEBUG ("ObjectPtrContainer attribute item " << j);
237 Ptr<Object> tmp = (*it).second;
238 if (tmp)
239 {
240 StartVisitArrayItem (vector, j, tmp);
241 m_examined.push_back (object);
242 DoIterate (tmp);
243 m_examined.pop_back ();
244 EndVisitArrayItem ();
245 }
246 }
247 EndVisitArrayAttribute ();
248 continue;
249 }
250 if ((info.flags & TypeId::ATTR_GET) && info.accessor->HasGetter () &&
251 (info.flags & TypeId::ATTR_SET) && info.accessor->HasSetter ())
252 {
253 VisitAttribute (object, info.name);
254 }
255 else
256 {
257 NS_LOG_DEBUG ("could not store " << info.name);
258 }
259 }
260 }
261 Object::AggregateIterator iter = object->GetAggregateIterator ();
262 bool recursiveAggregate = false;
263 while (iter.HasNext ())
264 {
265 Ptr<const Object> tmp = iter.Next ();
266 if (IsExamined (tmp))
267 {
268 recursiveAggregate = true;
269 }
270 }
271 if (!recursiveAggregate)
272 {
273 iter = object->GetAggregateIterator ();
274 while (iter.HasNext ())
275 {
276 Ptr<Object> tmp = const_cast<Object *> (PeekPointer (iter.Next ()));
277 StartVisitObject (tmp);
278 m_examined.push_back (object);
279 DoIterate (tmp);
280 m_examined.pop_back ();
281 EndVisitObject ();
282 }
283 }
284 }
285
286
287 } // namespace ns3
288