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 private:
110  virtual void StartVisitTypeId (std::string name) {
111  m_typeid = name;
112  }
113  virtual void DoVisitAttribute (std::string name, std::string defaultValue) {
114  int rc;
115  rc = xmlTextWriterStartElement (m_writer, BAD_CAST "default");
116  if (rc < 0)
117  {
118  NS_FATAL_ERROR ("Error at xmlTextWriterStartElement");
119  }
120  std::string fullname = m_typeid + "::" + name;
121  rc = xmlTextWriterWriteAttribute (m_writer, BAD_CAST "name",
122  BAD_CAST fullname.c_str ());
123  if (rc < 0)
124  {
125  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
126  }
127  rc = xmlTextWriterWriteAttribute (m_writer, BAD_CAST "value",
128  BAD_CAST defaultValue.c_str ());
129  if (rc < 0)
130  {
131  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
132  }
133  rc = xmlTextWriterEndElement (m_writer);
134  if (rc < 0)
135  {
136  NS_FATAL_ERROR ("Error at xmlTextWriterEndElement");
137  }
138  }
139  xmlTextWriterPtr m_writer;
140  std::string m_typeid;
141  };
142  XmlDefaultIterator iterator = XmlDefaultIterator (m_writer);
143  iterator.Iterate ();
144 }
145 
146 void
148 {
149  class XmlTextAttributeIterator : public AttributeIterator
150  {
151 public:
152  XmlTextAttributeIterator (xmlTextWriterPtr writer)
153  : m_writer (writer) {}
154 private:
155  virtual void DoVisitAttribute (Ptr<Object> object, std::string name) {
156  StringValue str;
157  object->GetAttribute (name, str);
158  int rc;
159  rc = xmlTextWriterStartElement (m_writer, BAD_CAST "value");
160  if (rc < 0)
161  {
162  NS_FATAL_ERROR ("Error at xmlTextWriterStartElement");
163  }
164  rc = xmlTextWriterWriteAttribute (m_writer, BAD_CAST "path",
165  BAD_CAST GetCurrentPath ().c_str ());
166  if (rc < 0)
167  {
168  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
169  }
170  rc = xmlTextWriterWriteAttribute (m_writer, BAD_CAST "value",
171  BAD_CAST str.Get ().c_str ());
172  if (rc < 0)
173  {
174  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
175  }
176  rc = xmlTextWriterEndElement (m_writer);
177  if (rc < 0)
178  {
179  NS_FATAL_ERROR ("Error at xmlTextWriterEndElement");
180  }
181  }
182  xmlTextWriterPtr m_writer;
183  };
184 
185  XmlTextAttributeIterator iter = XmlTextAttributeIterator (m_writer);
186  iter.Iterate ();
187 }
188 
189 void
191 {
192  int rc;
194  {
195  StringValue value;
196  (*i)->GetValue (value);
197 
198  rc = xmlTextWriterStartElement (m_writer, BAD_CAST "global");
199  if (rc < 0)
200  {
201  NS_FATAL_ERROR ("Error at xmlTextWriterStartElement");
202  }
203  rc = xmlTextWriterWriteAttribute (m_writer, BAD_CAST "name",
204  BAD_CAST (*i)->GetName ().c_str ());
205  if (rc < 0)
206  {
207  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
208  }
209  rc = xmlTextWriterWriteAttribute (m_writer, BAD_CAST "value",
210  BAD_CAST value.Get ().c_str ());
211  if (rc < 0)
212  {
213  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
214  }
215  rc = xmlTextWriterEndElement (m_writer);
216  if (rc < 0)
217  {
218  NS_FATAL_ERROR ("Error at xmlTextWriterEndElement");
219  }
220  }
221 }
222 
224 {
225  NS_LOG_FUNCTION (this);
226 }
228 {
229  NS_LOG_FUNCTION (this);
230 }
231 
232 void
233 XmlConfigLoad::SetFilename (std::string filename)
234 {
235  NS_LOG_FUNCTION (filename);
236  m_filename = filename;
237 }
238 void
240 {
241  xmlTextReaderPtr reader = xmlNewTextReaderFilename (m_filename.c_str ());
242  if (reader == NULL)
243  {
244  NS_FATAL_ERROR ("Error at xmlReaderForFile");
245  }
246  int rc;
247  rc = xmlTextReaderRead (reader);
248  while (rc > 0)
249  {
250  const xmlChar *type = xmlTextReaderConstName (reader);
251  if (type == 0)
252  {
253  NS_FATAL_ERROR ("Invalid value");
254  }
255  if (std::string ((char*)type) == "default")
256  {
257  xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name");
258  if (name == 0)
259  {
260  NS_FATAL_ERROR ("Error getting attribute 'name'");
261  }
262  xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value");
263  if (value == 0)
264  {
265  NS_FATAL_ERROR ("Error getting attribute 'value'");
266  }
267  NS_LOG_DEBUG ("default="<<(char*)name<<", value=" <<value);
268  Config::SetDefault ((char*)name, StringValue ((char*)value));
269  xmlFree (name);
270  xmlFree (value);
271  }
272  rc = xmlTextReaderRead (reader);
273  }
274  xmlFreeTextReader (reader);
275 }
276 void
278 {
279  xmlTextReaderPtr reader = xmlNewTextReaderFilename (m_filename.c_str ());
280  if (reader == NULL)
281  {
282  NS_FATAL_ERROR ("Error at xmlReaderForFile");
283  }
284  int rc;
285  rc = xmlTextReaderRead (reader);
286  while (rc > 0)
287  {
288  const xmlChar *type = xmlTextReaderConstName (reader);
289  if (type == 0)
290  {
291  NS_FATAL_ERROR ("Invalid value");
292  }
293  if (std::string ((char*)type) == "global")
294  {
295  xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name");
296  if (name == 0)
297  {
298  NS_FATAL_ERROR ("Error getting attribute 'name'");
299  }
300  xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value");
301  if (value == 0)
302  {
303  NS_FATAL_ERROR ("Error getting attribute 'value'");
304  }
305  NS_LOG_DEBUG ("global="<<(char*)name<<", value=" <<value);
306  Config::SetGlobal ((char*)name, StringValue ((char*)value));
307  xmlFree (name);
308  xmlFree (value);
309  }
310  rc = xmlTextReaderRead (reader);
311  }
312  xmlFreeTextReader (reader);
313 }
314 void
316 {
317  xmlTextReaderPtr reader = xmlNewTextReaderFilename (m_filename.c_str ());
318  if (reader == NULL)
319  {
320  NS_FATAL_ERROR ("Error at xmlReaderForFile");
321  }
322  int rc;
323  rc = xmlTextReaderRead (reader);
324  while (rc > 0)
325  {
326  const xmlChar *type = xmlTextReaderConstName (reader);
327  if (type == 0)
328  {
329  NS_FATAL_ERROR ("Invalid value");
330  }
331  if (std::string ((char*)type) == "value")
332  {
333  xmlChar *path = xmlTextReaderGetAttribute (reader, BAD_CAST "path");
334  if (path == 0)
335  {
336  NS_FATAL_ERROR ("Error getting attribute 'path'");
337  }
338  xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value");
339  if (value == 0)
340  {
341  NS_FATAL_ERROR ("Error getting attribute 'value'");
342  }
343  NS_LOG_DEBUG ("path="<<(char*)path << ", value=" << (char*)value);
344  Config::Set ((char*)path, StringValue ((char*)value));
345  xmlFree (path);
346  xmlFree (value);
347  }
348  rc = xmlTextReaderRead (reader);
349  }
350  xmlFreeTextReader (reader);
351 }
352 
353 
354 
355 } // namespace ns3
virtual void Attributes(void)
Load or save the attributes values.
Definition: xml-config.cc:315
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void SetFilename(std::string filename)
Set the file name.
Definition: xml-config.cc:233
Hold variables of type string.
Definition: string.h:41
virtual void Default(void)
Load or save the default values.
Definition: xml-config.cc:101
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:807
virtual ~XmlConfigSave()
Definition: xml-config.cc:79
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Vector::const_iterator Iterator
Iterator type for the list of all global values.
Definition: global-value.h:80
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
virtual ~XmlConfigLoad()
Definition: xml-config.cc:227
std::string Get(void) const
Definition: string.cc:31
static Iterator Begin(void)
The Begin iterator.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void SetFilename(std::string filename)
Set the file name.
Definition: xml-config.cc:42
virtual void Global(void)
Load or save the global values.
Definition: xml-config.cc:190
std::string m_filename
the file name
Definition: xml-config.h:65
virtual void Attributes(void)
Load or save the attributes values.
Definition: xml-config.cc:147
void SetGlobal(std::string name, const AttributeValue &value)
Definition: config.cc:852
virtual void Global(void)
Load or save the global values.
Definition: xml-config.cc:277
static Iterator End(void)
The End iterator.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:812
virtual void Default(void)
Load or save the default values.
Definition: xml-config.cc:239
Iterator to iterate on the values of attributes of an ns3::Object.
xmlTextWriterPtr m_writer
XML writer.
Definition: xml-config.h:47
Iterator to iterate on the default values of attributes of an ns3::Object.