A Discrete-Event Network Simulator
API
raw-text-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 "raw-text-config.h"
21 
23 #include "attribute-iterator.h"
24 
25 #include "ns3/config.h"
26 #include "ns3/global-value.h"
27 #include "ns3/log.h"
28 #include "ns3/string.h"
29 
30 #include <algorithm>
31 #include <functional>
32 #include <istream>
33 #include <sstream>
34 
35 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE("RawTextConfig");
39 
41  : m_os(nullptr)
42 {
43  NS_LOG_FUNCTION(this);
44 }
45 
47 {
48  NS_LOG_FUNCTION(this);
49  if (m_os != nullptr)
50  {
51  m_os->close();
52  }
53  delete m_os;
54  m_os = nullptr;
55 }
56 
57 void
58 RawTextConfigSave::SetFilename(std::string filename)
59 {
60  NS_LOG_FUNCTION(this << filename);
61  m_os = new std::ofstream();
62  m_os->open(filename, std::ios::out);
63 }
64 
65 void
67 {
68  NS_LOG_FUNCTION(this);
69 
70  class RawTextDefaultIterator : public AttributeDefaultIterator
71  {
72  public:
73  RawTextDefaultIterator(std::ostream* os)
74  {
75  m_os = os;
76  }
77 
78  void SetSaveDeprecated(bool saveDeprecated)
79  {
80  m_saveDeprecated = saveDeprecated;
81  }
82 
83  private:
84  void StartVisitTypeId(std::string name) override
85  {
86  m_typeId = name;
87  }
88 
89  void DoVisitAttribute(std::string name, std::string defaultValue) override
90  {
91  NS_LOG_DEBUG("Saving " << m_typeId << "::" << name);
92  TypeId tid = TypeId::LookupByName(m_typeId);
93  ns3::TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED;
94  for (std::size_t i = 0; i < tid.GetAttributeN(); i++)
95  {
96  struct TypeId::AttributeInformation tmp = tid.GetAttribute(i);
97  if (tmp.name == name)
98  {
99  supportLevel = tmp.supportLevel;
100  break;
101  }
102  }
103  if (supportLevel == TypeId::SupportLevel::OBSOLETE)
104  {
105  NS_LOG_WARN("Global attribute " << m_typeId << "::" << name
106  << " was not saved because it is OBSOLETE");
107  }
108  else if ((supportLevel == TypeId::SupportLevel::DEPRECATED) &&
109  (m_saveDeprecated == false))
110  {
111  NS_LOG_WARN("Global attribute " << m_typeId << "::" << name
112  << " was not saved because it is DEPRECATED");
113  }
114  else
115  {
116  *m_os << "default " << m_typeId << "::" << name << " \"" << defaultValue << "\""
117  << std::endl;
118  }
119  }
120 
121  std::string m_typeId;
122  std::ostream* m_os;
123  bool m_saveDeprecated;
124  };
125 
126  RawTextDefaultIterator iterator = RawTextDefaultIterator(m_os);
127  iterator.SetSaveDeprecated(m_saveDeprecated);
128  iterator.Iterate();
129 }
130 
131 void
133 {
134  NS_LOG_FUNCTION(this);
136  {
138  (*i)->GetValue(value);
139  NS_LOG_LOGIC("Saving " << (*i)->GetName());
140  *m_os << "global " << (*i)->GetName() << " \"" << value.Get() << "\"" << std::endl;
141  }
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION(this);
148 
149  class RawTextAttributeIterator : public AttributeIterator
150  {
151  public:
152  RawTextAttributeIterator(std::ostream* os)
153  : m_os(os)
154  {
155  }
156 
157  void SetSaveDeprecated(bool saveDeprecated)
158  {
159  m_saveDeprecated = saveDeprecated;
160  }
161 
162  private:
163  void DoVisitAttribute(Ptr<Object> object, std::string name) override
164  {
165  StringValue str;
166 
167  ns3::TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED;
168  TypeId tid = object->GetInstanceTypeId();
169 
170  for (std::size_t i = 0; i < tid.GetAttributeN(); i++)
171  {
172  struct TypeId::AttributeInformation tmp = tid.GetAttribute(i);
173  if (tmp.name == name)
174  {
175  supportLevel = tmp.supportLevel;
176  break;
177  }
178  }
179  if (supportLevel == TypeId::SupportLevel::OBSOLETE)
180  {
181  NS_LOG_WARN("Attribute " << GetCurrentPath()
182  << " was not saved because it is OBSOLETE");
183  }
184  else if ((supportLevel == TypeId::SupportLevel::DEPRECATED) &&
185  (m_saveDeprecated == false))
186  {
187  NS_LOG_WARN("Attribute " << GetCurrentPath()
188  << " was not saved because it is DEPRECATED");
189  }
190  else
191  {
192  object->GetAttribute(name, str);
193  NS_LOG_DEBUG("Saving " << GetCurrentPath());
194  *m_os << "value " << GetCurrentPath() << " \"" << str.Get() << "\"" << std::endl;
195  }
196  }
197 
198  std::ostream* m_os;
199  bool m_saveDeprecated;
200  };
201 
202  RawTextAttributeIterator iter = RawTextAttributeIterator(m_os);
203  iter.SetSaveDeprecated(m_saveDeprecated);
204  iter.Iterate();
205 }
206 
208  : m_is(nullptr)
209 {
210  NS_LOG_FUNCTION(this);
211 }
212 
214 {
215  NS_LOG_FUNCTION(this);
216  if (m_is != nullptr)
217  {
218  m_is->close();
219  delete m_is;
220  m_is = nullptr;
221  }
222 }
223 
224 void
225 RawTextConfigLoad::SetFilename(std::string filename)
226 {
227  NS_LOG_FUNCTION(this << filename);
228  m_is = new std::ifstream();
229  m_is->open(filename, std::ios::in);
230 }
231 
232 std::string
234 {
235  NS_LOG_FUNCTION(this << value);
236  std::string::size_type start = value.find('\"');
237  std::string::size_type end = value.find('\"', 1);
238  NS_ABORT_MSG_IF(start != 0, "Ill-formed attribute value: " << value);
239  NS_ABORT_MSG_IF(end != value.size() - 1, "Ill-formed attribute value: " << value);
240  return value.substr(start + 1, end - start - 1);
241 }
242 
243 void
245 {
246  NS_LOG_FUNCTION(this);
247  m_is->clear();
248  m_is->seekg(0);
249  std::string type;
250  std::string name;
251  std::string value;
252  for (std::string line; std::getline(*m_is, line);)
253  {
254  if (!ParseLine(line, type, name, value))
255  {
256  continue;
257  }
258 
259  NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
260  value = Strip(value);
261  if (type == "default")
262  {
264  }
265  name.clear();
266  type.clear();
267  value.clear();
268  }
269 }
270 
271 void
273 {
274  NS_LOG_FUNCTION(this);
275  m_is->clear();
276  m_is->seekg(0);
277  std::string type;
278  std::string name;
279  std::string value;
280  for (std::string line; std::getline(*m_is, line);)
281  {
282  if (!ParseLine(line, type, name, value))
283  {
284  continue;
285  }
286 
287  NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
288  value = Strip(value);
289  if (type == "global")
290  {
292  }
293  name.clear();
294  type.clear();
295  value.clear();
296  }
297 }
298 
299 void
301 {
302  NS_LOG_FUNCTION(this);
303  m_is->clear();
304  m_is->seekg(0);
305  std::string type;
306  std::string name;
307  std::string value;
308  for (std::string line; std::getline(*m_is, line);)
309  {
310  if (!ParseLine(line, type, name, value))
311  {
312  continue;
313  }
314 
315  NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
316  value = Strip(value);
317  if (type == "value")
318  {
319  Config::Set(name, StringValue(value));
320  }
321  name.clear();
322  type.clear();
323  value.clear();
324  }
325 }
326 
327 bool
328 RawTextConfigLoad::ParseLine(const std::string& line,
329  std::string& type,
330  std::string& name,
331  std::string& value)
332 {
333  NS_LOG_FUNCTION(this << line << type << name << value);
334 
335  // check for blank line
336  {
337  std::istringstream iss(line);
338  iss >> std::ws; // remove all blanks line
339  if (!iss.good()) // eofbit set if no non-blanks
340  {
341  return false;
342  }
343  }
344 
345  if (line.front() == '#')
346  {
347  return false; // comment line
348  }
349 
350  // for multiline values, append line to value if type and name not empty
351  if (type.empty() && name.empty())
352  {
353  std::istringstream iss(line);
354  iss >> type >> name >> std::ws;
355  std::getline(iss, value); // remaining line, includes embedded spaces
356  }
357  else
358  {
359  value.append(line);
360  }
361 
362  // two quotes in value signifies a completed (possibly multi-line)
363  // config-store entry, return True to signal load function to
364  // validate value (see Strip method) and set attribute
365  return std::count(value.begin(), value.end(), '"') == 2;
366 }
367 
368 } // 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.
void SetFilename(std::string filename) override
Set the file name.
void Attributes() override
Load or save the attributes values.
RawTextConfigLoad()
default constructor
virtual bool ParseLine(const std::string &line, std::string &type, std::string &name, std::string &value)
Parse (potentially multi-) line configs into type, name, and values.
void Global() override
Load or save the global values.
std::ifstream * m_is
Config store input stream.
std::string Strip(std::string value)
Strip out attribute value.
void Default() override
Load or save the default values.
~RawTextConfigLoad() override
destructor
std::ofstream * m_os
Config store output stream.
void Attributes() override
Load or save the attributes values.
void Global() override
Load or save the global values.
RawTextConfigSave()
default constructor
~RawTextConfigSave() override
destructor
void SetFilename(std::string filename) override
Set the file name.
void Default() override
Load or save the default values.
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
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 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_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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