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