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