1 #include "xml-config.h" |
|
2 #include "attribute-default-iterator.h" |
|
3 #include "attribute-iterator.h" |
|
4 #include "ns3/fatal-error.h" |
|
5 #include "ns3/log.h" |
|
6 #include "ns3/global-value.h" |
|
7 #include "ns3/string.h" |
|
8 #include "ns3/config.h" |
|
9 #include <libxml/encoding.h> |
|
10 #include <libxml/xmlwriter.h> |
|
11 |
|
12 NS_LOG_COMPONENT_DEFINE ("XmlConfig"); |
|
13 |
|
14 namespace ns3 { |
|
15 |
|
16 XmlConfigSave::XmlConfigSave () |
|
17 : m_writer (0) |
|
18 { |
|
19 NS_LOG_FUNCTION (this); |
|
20 } |
|
21 void |
|
22 XmlConfigSave::SetFilename (std::string filename) |
|
23 { |
|
24 NS_LOG_FUNCTION (filename); |
|
25 if (filename == "") |
|
26 { |
|
27 return; |
|
28 } |
|
29 int rc; |
|
30 |
|
31 /* Create a new XmlWriter for uri, with no compression. */ |
|
32 m_writer = xmlNewTextWriterFilename(filename.c_str (), 0); |
|
33 if (m_writer == NULL) |
|
34 { |
|
35 NS_FATAL_ERROR ("Error creating the xml writer"); |
|
36 } |
|
37 rc = xmlTextWriterSetIndent (m_writer, 1); |
|
38 if (rc < 0) |
|
39 { |
|
40 NS_FATAL_ERROR ("Error at xmlTextWriterSetIndent"); |
|
41 } |
|
42 /* Start the document with the xml default for the version, |
|
43 * encoding utf-8 and the default for the standalone |
|
44 * declaration. */ |
|
45 rc = xmlTextWriterStartDocument(m_writer, NULL, "utf-8", NULL); |
|
46 if (rc < 0) |
|
47 { |
|
48 NS_FATAL_ERROR ("Error at xmlTextWriterStartDocument"); |
|
49 } |
|
50 |
|
51 /* Start an element named "ns3". Since thist is the first |
|
52 * element, this will be the root element of the document. */ |
|
53 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "ns3"); |
|
54 if (rc < 0) |
|
55 { |
|
56 NS_FATAL_ERROR ("Error at xmlTextWriterStartElement\n"); |
|
57 } |
|
58 } |
|
59 XmlConfigSave::~XmlConfigSave () |
|
60 { |
|
61 NS_LOG_FUNCTION (this); |
|
62 if (m_writer == 0) |
|
63 { |
|
64 return; |
|
65 } |
|
66 int rc; |
|
67 /* Here we could close the remaining elements using the |
|
68 * function xmlTextWriterEndElement, but since we do not want to |
|
69 * write any other elements, we simply call xmlTextWriterEndDocument, |
|
70 * which will do all the work. */ |
|
71 rc = xmlTextWriterEndDocument(m_writer); |
|
72 if (rc < 0) |
|
73 { |
|
74 NS_FATAL_ERROR ("Error at xmlTextWriterEndDocument\n"); |
|
75 } |
|
76 |
|
77 xmlFreeTextWriter(m_writer); |
|
78 m_writer = 0; |
|
79 } |
|
80 void |
|
81 XmlConfigSave::Default (void) |
|
82 { |
|
83 class XmlDefaultIterator : public AttributeDefaultIterator |
|
84 { |
|
85 public: |
|
86 XmlDefaultIterator (xmlTextWriterPtr writer) { |
|
87 m_writer = writer; |
|
88 } |
|
89 private: |
|
90 virtual void StartVisitTypeId (std::string name) { |
|
91 m_typeid = name; |
|
92 } |
|
93 virtual void DoVisitAttribute (std::string name, std::string defaultValue) { |
|
94 int rc; |
|
95 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "default"); |
|
96 if (rc < 0) |
|
97 { |
|
98 NS_FATAL_ERROR ("Error at xmlTextWriterStartElement"); |
|
99 } |
|
100 std::string fullname = m_typeid + "::" + name; |
|
101 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name", |
|
102 BAD_CAST fullname.c_str ()); |
|
103 if (rc < 0) |
|
104 { |
|
105 NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); |
|
106 } |
|
107 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", |
|
108 BAD_CAST defaultValue.c_str ()); |
|
109 if (rc < 0) |
|
110 { |
|
111 NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); |
|
112 } |
|
113 rc = xmlTextWriterEndElement(m_writer); |
|
114 if (rc < 0) |
|
115 { |
|
116 NS_FATAL_ERROR ("Error at xmlTextWriterEndElement"); |
|
117 } |
|
118 } |
|
119 xmlTextWriterPtr m_writer; |
|
120 std::string m_typeid; |
|
121 }; |
|
122 XmlDefaultIterator iterator = XmlDefaultIterator (m_writer); |
|
123 iterator.Iterate (); |
|
124 } |
|
125 |
|
126 void |
|
127 XmlConfigSave::Attributes (void) |
|
128 { |
|
129 class XmlTextAttributeIterator : public AttributeIterator |
|
130 { |
|
131 public: |
|
132 XmlTextAttributeIterator (xmlTextWriterPtr writer) |
|
133 : m_writer (writer) {} |
|
134 private: |
|
135 virtual void DoVisitAttribute (Ptr<Object> object, std::string name) { |
|
136 StringValue str; |
|
137 object->GetAttribute (name, str); |
|
138 int rc; |
|
139 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "value"); |
|
140 if (rc < 0) |
|
141 { |
|
142 NS_FATAL_ERROR ("Error at xmlTextWriterStartElement"); |
|
143 } |
|
144 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "path", |
|
145 BAD_CAST GetCurrentPath ().c_str ()); |
|
146 if (rc < 0) |
|
147 { |
|
148 NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); |
|
149 } |
|
150 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", |
|
151 BAD_CAST str.Get ().c_str ()); |
|
152 if (rc < 0) |
|
153 { |
|
154 NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); |
|
155 } |
|
156 rc = xmlTextWriterEndElement(m_writer); |
|
157 if (rc < 0) |
|
158 { |
|
159 NS_FATAL_ERROR ("Error at xmlTextWriterEndElement"); |
|
160 } |
|
161 } |
|
162 xmlTextWriterPtr m_writer; |
|
163 }; |
|
164 |
|
165 XmlTextAttributeIterator iter = XmlTextAttributeIterator (m_writer); |
|
166 iter.Iterate (); |
|
167 } |
|
168 |
|
169 void |
|
170 XmlConfigSave::Global (void) |
|
171 { |
|
172 int rc; |
|
173 for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i) |
|
174 { |
|
175 StringValue value; |
|
176 (*i)->GetValue (value); |
|
177 |
|
178 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "global"); |
|
179 if (rc < 0) |
|
180 { |
|
181 NS_FATAL_ERROR ("Error at xmlTextWriterStartElement"); |
|
182 } |
|
183 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name", |
|
184 BAD_CAST (*i)->GetName ().c_str ()); |
|
185 if (rc < 0) |
|
186 { |
|
187 NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); |
|
188 } |
|
189 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", |
|
190 BAD_CAST value.Get ().c_str ()); |
|
191 if (rc < 0) |
|
192 { |
|
193 NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); |
|
194 } |
|
195 rc = xmlTextWriterEndElement(m_writer); |
|
196 if (rc < 0) |
|
197 { |
|
198 NS_FATAL_ERROR ("Error at xmlTextWriterEndElement"); |
|
199 } |
|
200 } |
|
201 } |
|
202 |
|
203 XmlConfigLoad::XmlConfigLoad () |
|
204 { |
|
205 NS_LOG_FUNCTION (this); |
|
206 } |
|
207 XmlConfigLoad::~XmlConfigLoad () |
|
208 { |
|
209 NS_LOG_FUNCTION (this); |
|
210 } |
|
211 |
|
212 void |
|
213 XmlConfigLoad::SetFilename (std::string filename) |
|
214 { |
|
215 NS_LOG_FUNCTION (filename); |
|
216 m_filename = filename; |
|
217 } |
|
218 void |
|
219 XmlConfigLoad::Default (void) |
|
220 { |
|
221 xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str ()); |
|
222 if (reader == NULL) |
|
223 { |
|
224 NS_FATAL_ERROR ("Error at xmlReaderForFile"); |
|
225 } |
|
226 int rc; |
|
227 rc = xmlTextReaderRead (reader); |
|
228 while (rc > 0) |
|
229 { |
|
230 const xmlChar *type = xmlTextReaderConstName(reader); |
|
231 if (type == 0) |
|
232 { |
|
233 NS_FATAL_ERROR ("Invalid value"); |
|
234 } |
|
235 if (std::string ((char*)type) == "default") |
|
236 { |
|
237 xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name"); |
|
238 if (name == 0) |
|
239 { |
|
240 NS_FATAL_ERROR ("Error getting attribute 'name'"); |
|
241 } |
|
242 xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value"); |
|
243 if (value == 0) |
|
244 { |
|
245 NS_FATAL_ERROR ("Error getting attribute 'value'"); |
|
246 } |
|
247 NS_LOG_DEBUG ("default="<<(char*)name<<", value=" <<value); |
|
248 Config::SetDefault ((char*)name, StringValue ((char*)value)); |
|
249 xmlFree (name); |
|
250 xmlFree (value); |
|
251 } |
|
252 rc = xmlTextReaderRead (reader); |
|
253 } |
|
254 xmlFreeTextReader (reader); |
|
255 } |
|
256 void |
|
257 XmlConfigLoad::Global (void) |
|
258 { |
|
259 xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str ()); |
|
260 if (reader == NULL) |
|
261 { |
|
262 NS_FATAL_ERROR ("Error at xmlReaderForFile"); |
|
263 } |
|
264 int rc; |
|
265 rc = xmlTextReaderRead (reader); |
|
266 while (rc > 0) |
|
267 { |
|
268 const xmlChar *type = xmlTextReaderConstName(reader); |
|
269 if (type == 0) |
|
270 { |
|
271 NS_FATAL_ERROR ("Invalid value"); |
|
272 } |
|
273 if (std::string ((char*)type) == "global") |
|
274 { |
|
275 xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name"); |
|
276 if (name == 0) |
|
277 { |
|
278 NS_FATAL_ERROR ("Error getting attribute 'name'"); |
|
279 } |
|
280 xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value"); |
|
281 if (value == 0) |
|
282 { |
|
283 NS_FATAL_ERROR ("Error getting attribute 'value'"); |
|
284 } |
|
285 NS_LOG_DEBUG ("global="<<(char*)name<<", value=" <<value); |
|
286 Config::SetGlobal ((char*)name, StringValue ((char*)value)); |
|
287 xmlFree (name); |
|
288 xmlFree (value); |
|
289 } |
|
290 rc = xmlTextReaderRead (reader); |
|
291 } |
|
292 xmlFreeTextReader (reader); |
|
293 } |
|
294 void |
|
295 XmlConfigLoad::Attributes (void) |
|
296 { |
|
297 xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str ()); |
|
298 if (reader == NULL) |
|
299 { |
|
300 NS_FATAL_ERROR ("Error at xmlReaderForFile"); |
|
301 } |
|
302 int rc; |
|
303 rc = xmlTextReaderRead (reader); |
|
304 while (rc > 0) |
|
305 { |
|
306 const xmlChar *type = xmlTextReaderConstName(reader); |
|
307 if (type == 0) |
|
308 { |
|
309 NS_FATAL_ERROR ("Invalid value"); |
|
310 } |
|
311 if (std::string ((char*)type) == "value") |
|
312 { |
|
313 xmlChar *path = xmlTextReaderGetAttribute (reader, BAD_CAST "path"); |
|
314 if (path == 0) |
|
315 { |
|
316 NS_FATAL_ERROR ("Error getting attribute 'path'"); |
|
317 } |
|
318 xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value"); |
|
319 if (value == 0) |
|
320 { |
|
321 NS_FATAL_ERROR ("Error getting attribute 'value'"); |
|
322 } |
|
323 NS_LOG_DEBUG ("path="<<(char*)path << ", value=" << (char*)value); |
|
324 Config::Set ((char*)path, StringValue ((char*)value)); |
|
325 xmlFree (path); |
|
326 xmlFree (value); |
|
327 } |
|
328 rc = xmlTextReaderRead (reader); |
|
329 } |
|
330 xmlFreeTextReader (reader); |
|
331 } |
|
332 |
|
333 |
|
334 |
|
335 } // namespace ns3 |
|