A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
xml-config.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 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 * Author: Mathieu Lacage <mathieu.lacage@cutebugs.net>
18 */
19
20#include "xml-config.h"
21
23#include "attribute-iterator.h"
24
25#include "ns3/config.h"
26#include "ns3/fatal-error.h"
27#include "ns3/global-value.h"
28#include "ns3/log.h"
29#include "ns3/string.h"
30
31#include <libxml/encoding.h>
32#include <libxml/xmlreader.h>
33#include <libxml/xmlwriter.h>
34
35namespace ns3
36{
37
38NS_LOG_COMPONENT_DEFINE("XmlConfig");
39
41 : m_writer(nullptr)
42{
43 NS_LOG_FUNCTION(this);
44}
45
46void
47XmlConfigSave::SetFilename(std::string filename)
48{
49 NS_LOG_FUNCTION(filename);
50 if (filename.empty())
51 {
52 return;
53 }
54 int rc;
55
56 /* Create a new XmlWriter for uri, with no compression. */
57 m_writer = xmlNewTextWriterFilename(filename.c_str(), 0);
58 if (m_writer == nullptr)
59 {
60 NS_FATAL_ERROR("Error creating the XML writer");
61 }
62 rc = xmlTextWriterSetIndent(m_writer, 1);
63 if (rc < 0)
64 {
65 NS_FATAL_ERROR("Error at xmlTextWriterSetIndent");
66 }
67 /* Start the document with the XML default for the version,
68 * encoding utf-8 and the default for the standalone
69 * declaration. */
70 rc = xmlTextWriterStartDocument(m_writer, nullptr, "utf-8", nullptr);
71 if (rc < 0)
72 {
73 NS_FATAL_ERROR("Error at xmlTextWriterStartDocument");
74 }
75
76 /* Start an element named "ns3". Since this is the first
77 * element, this will be the root element of the document. */
78 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "ns3");
79 if (rc < 0)
80 {
81 NS_FATAL_ERROR("Error at xmlTextWriterStartElement\n");
82 }
83}
84
86{
87 NS_LOG_FUNCTION(this);
88 if (m_writer == nullptr)
89 {
90 return;
91 }
92 int rc;
93 /* Here we could close the remaining elements using the
94 * function xmlTextWriterEndElement, but since we do not want to
95 * write any other elements, we simply call xmlTextWriterEndDocument,
96 * which will do all the work. */
97 rc = xmlTextWriterEndDocument(m_writer);
98 if (rc < 0)
99 {
100 NS_FATAL_ERROR("Error at xmlTextWriterEndDocument\n");
101 }
102
103 xmlFreeTextWriter(m_writer);
104 m_writer = nullptr;
105}
106
107void
109{
110 class XmlDefaultIterator : public AttributeDefaultIterator
111 {
112 public:
113 XmlDefaultIterator(xmlTextWriterPtr writer)
114 {
115 m_writer = writer;
116 }
117
118 void SetSaveDeprecated(bool saveDeprecated)
119 {
120 m_saveDeprecated = saveDeprecated;
121 }
122
123 private:
124 void StartVisitTypeId(std::string name) override
125 {
126 m_typeid = name;
127 }
128
129 void DoVisitAttribute(std::string name, std::string defaultValue) override
130 {
131 TypeId tid = TypeId::LookupByName(m_typeid);
132 ns3::TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED;
133 for (std::size_t i = 0; i < tid.GetAttributeN(); i++)
134 {
135 struct TypeId::AttributeInformation tmp = tid.GetAttribute(i);
136 if (tmp.name == name)
137 {
138 supportLevel = tmp.supportLevel;
139 break;
140 }
141 }
142 if (supportLevel == TypeId::SupportLevel::OBSOLETE)
143 {
144 NS_LOG_WARN("Global attribute " << m_typeid << "::" << name
145 << " was not saved because it is OBSOLETE");
146 return;
147 }
148 else if ((supportLevel == TypeId::SupportLevel::DEPRECATED) &&
149 (m_saveDeprecated == false))
150 {
151 NS_LOG_WARN("Global attribute " << m_typeid << "::" << name
152 << " was not saved because it is DEPRECATED");
153 return;
154 }
155
156 int rc;
157 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "default");
158 if (rc < 0)
159 {
160 NS_FATAL_ERROR("Error at xmlTextWriterStartElement");
161 }
162 std::string fullname = m_typeid + "::" + name;
163 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name", BAD_CAST fullname.c_str());
164 if (rc < 0)
165 {
166 NS_FATAL_ERROR("Error at xmlTextWriterWriteAttribute");
167 }
168 rc = xmlTextWriterWriteAttribute(m_writer,
169 BAD_CAST "value",
170 BAD_CAST defaultValue.c_str());
171 if (rc < 0)
172 {
173 NS_FATAL_ERROR("Error at xmlTextWriterWriteAttribute");
174 }
175 rc = xmlTextWriterEndElement(m_writer);
176 if (rc < 0)
177 {
178 NS_FATAL_ERROR("Error at xmlTextWriterEndElement");
179 }
180 }
181
182 xmlTextWriterPtr m_writer;
183 std::string m_typeid;
184 bool m_saveDeprecated;
185 };
186
187 XmlDefaultIterator iterator = XmlDefaultIterator(m_writer);
188 iterator.SetSaveDeprecated(m_saveDeprecated);
189 iterator.Iterate();
190}
191
192void
194{
195 class XmlTextAttributeIterator : public AttributeIterator
196 {
197 public:
198 XmlTextAttributeIterator(xmlTextWriterPtr writer)
199 : m_writer(writer)
200 {
201 }
202
203 void SetSaveDeprecated(bool saveDeprecated)
204 {
205 m_saveDeprecated = saveDeprecated;
206 }
207
208 private:
209 void DoVisitAttribute(Ptr<Object> object, std::string name) override
210 {
211 TypeId tid = object->GetInstanceTypeId();
212 ns3::TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED;
213 for (std::size_t i = 0; i < tid.GetAttributeN(); i++)
214 {
215 struct TypeId::AttributeInformation tmp = tid.GetAttribute(i);
216 if (tmp.name == name)
217 {
218 supportLevel = tmp.supportLevel;
219 break;
220 }
221 }
222 if (supportLevel == TypeId::SupportLevel::OBSOLETE)
223 {
224 NS_LOG_WARN("Attribute " << GetCurrentPath()
225 << " was not saved because it is OBSOLETE");
226 return;
227 }
228 else if ((supportLevel == TypeId::SupportLevel::DEPRECATED) &&
229 (m_saveDeprecated == false))
230 {
231 NS_LOG_WARN("Attribute " << GetCurrentPath()
232 << " was not saved because it is DEPRECATED");
233 return;
234 }
235 StringValue str;
236 object->GetAttribute(name, str);
237 int rc;
238 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "value");
239 if (rc < 0)
240 {
241 NS_FATAL_ERROR("Error at xmlTextWriterStartElement");
242 }
243 rc = xmlTextWriterWriteAttribute(m_writer,
244 BAD_CAST "path",
245 BAD_CAST GetCurrentPath().c_str());
246 if (rc < 0)
247 {
248 NS_FATAL_ERROR("Error at xmlTextWriterWriteAttribute");
249 }
250 rc =
251 xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", BAD_CAST str.Get().c_str());
252 if (rc < 0)
253 {
254 NS_FATAL_ERROR("Error at xmlTextWriterWriteAttribute");
255 }
256 rc = xmlTextWriterEndElement(m_writer);
257 if (rc < 0)
258 {
259 NS_FATAL_ERROR("Error at xmlTextWriterEndElement");
260 }
261 }
262
263 xmlTextWriterPtr m_writer;
264 bool m_saveDeprecated;
265 };
266
267 XmlTextAttributeIterator iter = XmlTextAttributeIterator(m_writer);
268 iter.SetSaveDeprecated(m_saveDeprecated);
269 iter.Iterate();
270}
271
272void
274{
275 int rc;
277 {
278 StringValue value;
279 (*i)->GetValue(value);
280
281 rc = xmlTextWriterStartElement(m_writer, BAD_CAST "global");
282 if (rc < 0)
283 {
284 NS_FATAL_ERROR("Error at xmlTextWriterStartElement");
285 }
286 rc =
287 xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name", BAD_CAST(*i)->GetName().c_str());
288 if (rc < 0)
289 {
290 NS_FATAL_ERROR("Error at xmlTextWriterWriteAttribute");
291 }
292 rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", BAD_CAST value.Get().c_str());
293 if (rc < 0)
294 {
295 NS_FATAL_ERROR("Error at xmlTextWriterWriteAttribute");
296 }
297 rc = xmlTextWriterEndElement(m_writer);
298 if (rc < 0)
299 {
300 NS_FATAL_ERROR("Error at xmlTextWriterEndElement");
301 }
302 }
303}
304
306{
307 NS_LOG_FUNCTION(this);
308}
309
311{
312 NS_LOG_FUNCTION(this);
313}
314
315void
316XmlConfigLoad::SetFilename(std::string filename)
317{
318 NS_LOG_FUNCTION(filename);
319 m_filename = filename;
320}
321
322void
324{
325 xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str());
326 if (reader == nullptr)
327 {
328 NS_FATAL_ERROR("Error at xmlReaderForFile");
329 }
330 int rc;
331 rc = xmlTextReaderRead(reader);
332 while (rc > 0)
333 {
334 const xmlChar* type = xmlTextReaderConstName(reader);
335 if (type == nullptr)
336 {
337 NS_FATAL_ERROR("Invalid value");
338 }
339 if (std::string((char*)type) == "default")
340 {
341 xmlChar* name = xmlTextReaderGetAttribute(reader, BAD_CAST "name");
342 if (name == nullptr)
343 {
344 NS_FATAL_ERROR("Error getting attribute 'name'");
345 }
346 xmlChar* value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
347 if (value == nullptr)
348 {
349 NS_FATAL_ERROR("Error getting attribute 'value'");
350 }
351 NS_LOG_DEBUG("default=" << (char*)name << ", value=" << value);
352 Config::SetDefault((char*)name, StringValue((char*)value));
353 xmlFree(name);
354 xmlFree(value);
355 }
356 rc = xmlTextReaderRead(reader);
357 }
358 xmlFreeTextReader(reader);
359}
360
361void
363{
364 xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str());
365 if (reader == nullptr)
366 {
367 NS_FATAL_ERROR("Error at xmlReaderForFile");
368 }
369 int rc;
370 rc = xmlTextReaderRead(reader);
371 while (rc > 0)
372 {
373 const xmlChar* type = xmlTextReaderConstName(reader);
374 if (type == nullptr)
375 {
376 NS_FATAL_ERROR("Invalid value");
377 }
378 if (std::string((char*)type) == "global")
379 {
380 xmlChar* name = xmlTextReaderGetAttribute(reader, BAD_CAST "name");
381 if (name == nullptr)
382 {
383 NS_FATAL_ERROR("Error getting attribute 'name'");
384 }
385 xmlChar* value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
386 if (value == nullptr)
387 {
388 NS_FATAL_ERROR("Error getting attribute 'value'");
389 }
390 NS_LOG_DEBUG("global=" << (char*)name << ", value=" << value);
391 Config::SetGlobal((char*)name, StringValue((char*)value));
392 xmlFree(name);
393 xmlFree(value);
394 }
395 rc = xmlTextReaderRead(reader);
396 }
397 xmlFreeTextReader(reader);
398}
399
400void
402{
403 xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str());
404 if (reader == nullptr)
405 {
406 NS_FATAL_ERROR("Error at xmlReaderForFile");
407 }
408 int rc;
409 rc = xmlTextReaderRead(reader);
410 while (rc > 0)
411 {
412 const xmlChar* type = xmlTextReaderConstName(reader);
413 if (type == nullptr)
414 {
415 NS_FATAL_ERROR("Invalid value");
416 }
417 if (std::string((char*)type) == "value")
418 {
419 xmlChar* path = xmlTextReaderGetAttribute(reader, BAD_CAST "path");
420 if (path == nullptr)
421 {
422 NS_FATAL_ERROR("Error getting attribute 'path'");
423 }
424 xmlChar* value = xmlTextReaderGetAttribute(reader, BAD_CAST "value");
425 if (value == nullptr)
426 {
427 NS_FATAL_ERROR("Error getting attribute 'value'");
428 }
429 NS_LOG_DEBUG("path=" << (char*)path << ", value=" << (char*)value);
430 Config::Set((char*)path, StringValue((char*)value));
431 xmlFree(path);
432 xmlFree(value);
433 }
434 rc = xmlTextReaderRead(reader);
435 }
436 xmlFreeTextReader(reader);
437}
438
439} // namespace ns3
Iterator to iterate on the default values of attributes of an ns3::Object.
Iterator to iterate on the values of attributes of an ns3::Object.
bool m_saveDeprecated
save deprecated attributes
Definition: file-config.h:61
Vector::const_iterator Iterator
Iterator type for the list of all global values.
Definition: global-value.h:82
static Iterator Begin()
The Begin iterator.
static Iterator End()
The End iterator.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Hold variables of type string.
Definition: string.h:56
std::string Get() const
Definition: string.cc:31
a unique identifier for an interface.
Definition: type-id.h:60
struct TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1112
std::size_t GetAttributeN() const
Get the number of attributes.
Definition: type-id.cc:1104
SupportLevel
The level of support or deprecation for attributes or trace sources.
Definition: type-id.h:74
void Global() override
Load or save the global values.
Definition: xml-config.cc:362
void SetFilename(std::string filename) override
Set the file name.
Definition: xml-config.cc:316
void Default() override
Load or save the default values.
Definition: xml-config.cc:323
std::string m_filename
the file name
Definition: xml-config.h:71
void Attributes() override
Load or save the attributes values.
Definition: xml-config.cc:401
~XmlConfigLoad() override
Definition: xml-config.cc:310
void Global() override
Load or save the global values.
Definition: xml-config.cc:273
void Attributes() override
Load or save the attributes values.
Definition: xml-config.cc:193
~XmlConfigSave() override
Definition: xml-config.cc:85
xmlTextWriterPtr m_writer
XML writer.
Definition: xml-config.h:52
void SetFilename(std::string filename) override
Set the file name.
Definition: xml-config.cc:47
void Default() override
Load or save the default values.
Definition: xml-config.cc:108
void SetGlobal(std::string name, const AttributeValue &value)
Definition: config.cc:937
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:877
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Attribute implementation.
Definition: type-id.h:82
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.h:98
std::string name
Attribute name.
Definition: type-id.h:84
xmlTextWriter * xmlTextWriterPtr
Definition: xml-config.h:30