|
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-vector.h" |
|
24 #include "ns3/string.h" |
|
25 #include <fstream> |
|
26 |
|
27 |
|
28 NS_LOG_COMPONENT_DEFINE ("AttributeIterator"); |
|
29 |
|
30 namespace ns3 { |
|
31 |
|
32 |
|
33 AttributeIterator::AttributeIterator () |
|
34 { |
|
35 } |
|
36 |
|
37 AttributeIterator::~AttributeIterator () |
|
38 { |
|
39 } |
|
40 |
|
41 void |
|
42 AttributeIterator::Iterate (void) |
|
43 { |
|
44 for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i) |
|
45 { |
|
46 Ptr<Object> object = Config::GetRootNamespaceObject (i); |
|
47 StartVisitObject (object); |
|
48 DoIterate (object); |
|
49 EndVisitObject (); |
|
50 } |
|
51 NS_ASSERT (m_currentPath.empty ()); |
|
52 NS_ASSERT (m_examined.empty ()); |
|
53 } |
|
54 |
|
55 bool |
|
56 AttributeIterator::IsExamined (Ptr<const Object> object) |
|
57 { |
|
58 for (uint32_t i = 0; i < m_examined.size (); ++i) |
|
59 { |
|
60 if (object == m_examined[i]) |
|
61 { |
|
62 return true; |
|
63 } |
|
64 } |
|
65 return false; |
|
66 } |
|
67 |
|
68 |
|
69 std::string |
|
70 AttributeIterator::GetCurrentPath (std::string attr) const |
|
71 { |
|
72 std::ostringstream oss; |
|
73 for (uint32_t i = 0; i < m_currentPath.size (); ++i) |
|
74 { |
|
75 oss << "/" << m_currentPath[i]; |
|
76 } |
|
77 if (attr != "") |
|
78 { |
|
79 oss << "/" << attr; |
|
80 } |
|
81 return oss.str (); |
|
82 } |
|
83 |
|
84 std::string |
|
85 AttributeIterator::GetCurrentPath (void) const |
|
86 { |
|
87 std::ostringstream oss; |
|
88 for (uint32_t i = 0; i < m_currentPath.size (); ++i) |
|
89 { |
|
90 oss << "/" << m_currentPath[i]; |
|
91 } |
|
92 return oss.str (); |
|
93 } |
|
94 |
|
95 void |
|
96 AttributeIterator::DoStartVisitObject (Ptr<Object> object) |
|
97 { |
|
98 } |
|
99 void |
|
100 AttributeIterator::DoEndVisitObject (void) |
|
101 { |
|
102 } |
|
103 void |
|
104 AttributeIterator::DoStartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> item) |
|
105 { |
|
106 } |
|
107 void |
|
108 AttributeIterator::DoEndVisitPointerAttribute (void) |
|
109 { |
|
110 } |
|
111 void |
|
112 AttributeIterator::DoStartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector) |
|
113 { |
|
114 } |
|
115 void |
|
116 AttributeIterator::DoEndVisitArrayAttribute (void) |
|
117 { |
|
118 } |
|
119 void |
|
120 AttributeIterator::DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item) |
|
121 { |
|
122 } |
|
123 void |
|
124 AttributeIterator::DoEndVisitArrayItem (void) |
|
125 { |
|
126 } |
|
127 |
|
128 void |
|
129 AttributeIterator::VisitAttribute (Ptr<Object> object, std::string name) |
|
130 { |
|
131 m_currentPath.push_back (name); |
|
132 DoVisitAttribute (object, name); |
|
133 m_currentPath.pop_back (); |
|
134 } |
|
135 |
|
136 void |
|
137 AttributeIterator::StartVisitObject (Ptr<Object> object) |
|
138 { |
|
139 m_currentPath.push_back ("$" + object->GetInstanceTypeId ().GetName ()); |
|
140 DoStartVisitObject (object); |
|
141 } |
|
142 void |
|
143 AttributeIterator::EndVisitObject (void) |
|
144 { |
|
145 m_currentPath.pop_back (); |
|
146 DoEndVisitObject (); |
|
147 } |
|
148 void |
|
149 AttributeIterator::StartVisitPointerAttribute (Ptr<Object> object, std::string name, Ptr<Object> value) |
|
150 { |
|
151 m_currentPath.push_back (name); |
|
152 m_currentPath.push_back ("$" + value->GetInstanceTypeId ().GetName ()); |
|
153 DoStartVisitPointerAttribute (object, name, value); |
|
154 } |
|
155 void |
|
156 AttributeIterator::EndVisitPointerAttribute (void) |
|
157 { |
|
158 m_currentPath.pop_back (); |
|
159 m_currentPath.pop_back (); |
|
160 DoEndVisitPointerAttribute (); |
|
161 } |
|
162 void |
|
163 AttributeIterator::StartVisitArrayAttribute (Ptr<Object> object, std::string name, const ObjectVectorValue &vector) |
|
164 { |
|
165 m_currentPath.push_back (name); |
|
166 DoStartVisitArrayAttribute (object, name, vector); |
|
167 } |
|
168 void |
|
169 AttributeIterator::EndVisitArrayAttribute (void) |
|
170 { |
|
171 m_currentPath.pop_back (); |
|
172 DoEndVisitArrayAttribute (); |
|
173 } |
|
174 |
|
175 void |
|
176 AttributeIterator::StartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item) |
|
177 { |
|
178 std::ostringstream oss; |
|
179 oss << index; |
|
180 m_currentPath.push_back (oss.str ()); |
|
181 m_currentPath.push_back ("$" + item->GetInstanceTypeId ().GetName ()); |
|
182 DoStartVisitArrayItem (vector, index, item); |
|
183 } |
|
184 void |
|
185 AttributeIterator::EndVisitArrayItem (void) |
|
186 { |
|
187 m_currentPath.pop_back (); |
|
188 m_currentPath.pop_back (); |
|
189 DoEndVisitArrayItem (); |
|
190 } |
|
191 |
|
192 |
|
193 void |
|
194 AttributeIterator::DoIterate (Ptr<Object> object) |
|
195 { |
|
196 if (IsExamined (object)) |
|
197 { |
|
198 return; |
|
199 } |
|
200 TypeId tid; |
|
201 for (tid = object->GetInstanceTypeId (); tid.HasParent (); tid = tid.GetParent ()) |
|
202 { |
|
203 NS_LOG_DEBUG ("store " << tid.GetName ()); |
|
204 for (uint32_t i = 0; i < tid.GetAttributeN (); ++i) |
|
205 { |
|
206 Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i); |
|
207 const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (checker)); |
|
208 if (ptrChecker != 0) |
|
209 { |
|
210 NS_LOG_DEBUG ("pointer attribute " << tid.GetAttributeName (i)); |
|
211 PointerValue ptr; |
|
212 object->GetAttribute (tid.GetAttributeName (i), ptr); |
|
213 Ptr<Object> tmp = ptr.Get<Object> (); |
|
214 if (tmp != 0) |
|
215 { |
|
216 StartVisitPointerAttribute (object, tid.GetAttributeName (i), |
|
217 tmp); |
|
218 m_examined.push_back (object); |
|
219 DoIterate (tmp); |
|
220 m_examined.pop_back (); |
|
221 EndVisitPointerAttribute (); |
|
222 } |
|
223 continue; |
|
224 } |
|
225 // attempt to cast to an object vector. |
|
226 const ObjectVectorChecker *vectorChecker = dynamic_cast<const ObjectVectorChecker *> (PeekPointer (checker)); |
|
227 if (vectorChecker != 0) |
|
228 { |
|
229 NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i)); |
|
230 ObjectVectorValue vector; |
|
231 object->GetAttribute (tid.GetAttributeName (i), vector); |
|
232 StartVisitArrayAttribute (object, tid.GetAttributeName (i), vector); |
|
233 for (uint32_t j = 0; j < vector.GetN (); ++j) |
|
234 { |
|
235 NS_LOG_DEBUG ("vector attribute item " << j); |
|
236 Ptr<Object> tmp = vector.Get (j); |
|
237 StartVisitArrayItem (vector, j, tmp); |
|
238 m_examined.push_back (object); |
|
239 DoIterate (tmp); |
|
240 m_examined.pop_back (); |
|
241 EndVisitArrayItem (); |
|
242 } |
|
243 EndVisitArrayAttribute (); |
|
244 continue; |
|
245 } |
|
246 uint32_t flags = tid.GetAttributeFlags (i); |
|
247 Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i); |
|
248 if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () && |
|
249 (flags & TypeId::ATTR_SET) && accessor->HasSetter ()) |
|
250 { |
|
251 VisitAttribute (object, tid.GetAttributeName (i)); |
|
252 } |
|
253 else |
|
254 { |
|
255 NS_LOG_DEBUG ("could not store " << tid.GetAttributeName (i)); |
|
256 } |
|
257 } |
|
258 } |
|
259 Object::AggregateIterator iter = object->GetAggregateIterator (); |
|
260 bool recursiveAggregate = false; |
|
261 while (iter.HasNext ()) |
|
262 { |
|
263 Ptr<const Object> tmp = iter.Next (); |
|
264 if (IsExamined (tmp)) |
|
265 { |
|
266 recursiveAggregate = true; |
|
267 } |
|
268 } |
|
269 if (!recursiveAggregate) |
|
270 { |
|
271 iter = object->GetAggregateIterator (); |
|
272 while (iter.HasNext ()) |
|
273 { |
|
274 Ptr<Object> tmp = const_cast<Object *> (PeekPointer (iter.Next ())); |
|
275 StartVisitObject (tmp); |
|
276 m_examined.push_back (object); |
|
277 DoIterate (tmp); |
|
278 m_examined.pop_back (); |
|
279 EndVisitObject (); |
|
280 } |
|
281 } |
|
282 } |
|
283 |
|
284 |
|
285 } // namespace ns3 |