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  {
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 && !m_saveDeprecated)
109  {
110  NS_LOG_WARN("Global attribute " << m_typeId << "::" << name
111  << " was not saved because it is DEPRECATED");
112  }
113  else
114  {
115  *m_os << "default " << m_typeId << "::" << name << " \"" << defaultValue << "\""
116  << std::endl;
117  }
118  }
119 
120  std::string m_typeId;
121  std::ostream* m_os;
122  bool m_saveDeprecated;
123  };
124 
125  RawTextDefaultIterator iterator = RawTextDefaultIterator(m_os);
126  iterator.SetSaveDeprecated(m_saveDeprecated);
127  iterator.Iterate();
128 }
129 
130 void
132 {
133  NS_LOG_FUNCTION(this);
134  for (auto i = GlobalValue::Begin(); i != GlobalValue::End(); ++i)
135  {
136  StringValue value;
137  (*i)->GetValue(value);
138  NS_LOG_LOGIC("Saving " << (*i)->GetName());
139  *m_os << "global " << (*i)->GetName() << " \"" << value.Get() << "\"" << std::endl;
140  }
141 }
142 
143 void
145 {
146  NS_LOG_FUNCTION(this);
147 
148  class RawTextAttributeIterator : public AttributeIterator
149  {
150  public:
151  RawTextAttributeIterator(std::ostream* os)
152  : m_os(os)
153  {
154  }
155 
156  void SetSaveDeprecated(bool saveDeprecated)
157  {
158  m_saveDeprecated = saveDeprecated;
159  }
160 
161  private:
162  void DoVisitAttribute(Ptr<Object> object, std::string name) override
163  {
164  StringValue str;
165 
166  ns3::TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED;
167  TypeId tid = object->GetInstanceTypeId();
168 
169  for (std::size_t i = 0; i < tid.GetAttributeN(); i++)
170  {
172  if (tmp.name == name)
173  {
174  supportLevel = tmp.supportLevel;
175  break;
176  }
177  }
178  if (supportLevel == TypeId::SupportLevel::OBSOLETE)
179  {
180  NS_LOG_WARN("Attribute " << GetCurrentPath()
181  << " was not saved because it is OBSOLETE");
182  }
183  else if (supportLevel == TypeId::SupportLevel::DEPRECATED && !m_saveDeprecated)
184  {
185  NS_LOG_WARN("Attribute " << GetCurrentPath()
186  << " was not saved because it is DEPRECATED");
187  }
188  else
189  {
190  object->GetAttribute(name, str);
191  NS_LOG_DEBUG("Saving " << GetCurrentPath());
192  *m_os << "value " << GetCurrentPath() << " \"" << str.Get() << "\"" << std::endl;
193  }
194  }
195 
196  std::ostream* m_os;
197  bool m_saveDeprecated;
198  };
199 
200  RawTextAttributeIterator iter = RawTextAttributeIterator(m_os);
201  iter.SetSaveDeprecated(m_saveDeprecated);
202  iter.Iterate();
203 }
204 
206  : m_is(nullptr)
207 {
208  NS_LOG_FUNCTION(this);
209 }
210 
212 {
213  NS_LOG_FUNCTION(this);
214  if (m_is != nullptr)
215  {
216  m_is->close();
217  delete m_is;
218  m_is = nullptr;
219  }
220 }
221 
222 void
223 RawTextConfigLoad::SetFilename(std::string filename)
224 {
225  NS_LOG_FUNCTION(this << filename);
226  m_is = new std::ifstream();
227  m_is->open(filename, std::ios::in);
228 }
229 
230 std::string
231 RawTextConfigLoad::Strip(std::string value)
232 {
233  NS_LOG_FUNCTION(this << value);
234  std::string::size_type start = value.find('\"');
235  std::string::size_type end = value.find('\"', 1);
236  NS_ABORT_MSG_IF(start != 0, "Ill-formed attribute value: " << value);
237  NS_ABORT_MSG_IF(end != value.size() - 1, "Ill-formed attribute value: " << value);
238  return value.substr(start + 1, end - start - 1);
239 }
240 
241 void
243 {
244  NS_LOG_FUNCTION(this);
245  m_is->clear();
246  m_is->seekg(0);
247  std::string type;
248  std::string name;
249  std::string value;
250  for (std::string line; std::getline(*m_is, line);)
251  {
252  if (!ParseLine(line, type, name, value))
253  {
254  continue;
255  }
256 
257  NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
258  value = Strip(value);
259  if (type == "default")
260  {
261  Config::SetDefault(name, StringValue(value));
262  }
263  name.clear();
264  type.clear();
265  value.clear();
266  }
267 }
268 
269 void
271 {
272  NS_LOG_FUNCTION(this);
273  m_is->clear();
274  m_is->seekg(0);
275  std::string type;
276  std::string name;
277  std::string value;
278  for (std::string line; std::getline(*m_is, line);)
279  {
280  if (!ParseLine(line, type, name, value))
281  {
282  continue;
283  }
284 
285  NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
286  value = Strip(value);
287  if (type == "global")
288  {
289  Config::SetGlobal(name, StringValue(value));
290  }
291  name.clear();
292  type.clear();
293  value.clear();
294  }
295 }
296 
297 void
299 {
300  NS_LOG_FUNCTION(this);
301  m_is->clear();
302  m_is->seekg(0);
303  std::string type;
304  std::string name;
305  std::string value;
306  for (std::string line; std::getline(*m_is, line);)
307  {
308  if (!ParseLine(line, type, name, value))
309  {
310  continue;
311  }
312 
313  NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
314  value = Strip(value);
315  if (type == "value")
316  {
317  Config::Set(name, StringValue(value));
318  }
319  name.clear();
320  type.clear();
321  value.clear();
322  }
323 }
324 
325 bool
326 RawTextConfigLoad::ParseLine(const std::string& line,
327  std::string& type,
328  std::string& name,
329  std::string& value)
330 {
331  NS_LOG_FUNCTION(this << line << type << name << value);
332 
333  // check for blank line
334  {
335  std::istringstream iss(line);
336  iss >> std::ws; // remove all blanks line
337  if (!iss.good()) // eofbit set if no non-blanks
338  {
339  return false;
340  }
341  }
342 
343  if (line.front() == '#')
344  {
345  return false; // comment line
346  }
347 
348  // for multiline values, append line to value if type and name not empty
349  if (type.empty() && name.empty())
350  {
351  std::istringstream iss(line);
352  iss >> type >> name >> std::ws;
353  std::getline(iss, value); // remaining line, includes embedded spaces
354  }
355  else
356  {
357  value.append(line);
358  }
359 
360  // two quotes in value signifies a completed (possibly multi-line)
361  // config-store entry, return True to signal load function to
362  // validate value (see Strip method) and set attribute
363  return std::count(value.begin(), value.end(), '"') == 2;
364 }
365 
366 } // 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
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:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
std::size_t GetAttributeN() const
Get the number of attributes.
Definition: type-id.cc:1100
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition: type-id.cc:1108
SupportLevel
The level of support or deprecation for attributes or trace sources.
Definition: type-id.h:73
void SetGlobal(std::string name, const AttributeValue &value)
Definition: config.cc:936
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:876
#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.
Attribute implementation.
Definition: type-id.h:81
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition: type-id.h:97
std::string name
Attribute name.
Definition: type-id.h:83