A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
raw-text-config.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@cutebugs.net>
7 */
8
9#include "raw-text-config.h"
10
12#include "attribute-iterator.h"
13
14#include "ns3/config.h"
15#include "ns3/global-value.h"
16#include "ns3/log.h"
17#include "ns3/string.h"
18
19#include <algorithm>
20#include <functional>
21#include <istream>
22#include <sstream>
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("RawTextConfig");
28
30 : m_os(nullptr)
31{
32 NS_LOG_FUNCTION(this);
33}
34
36{
37 NS_LOG_FUNCTION(this);
38 if (m_os != nullptr)
39 {
40 m_os->close();
41 }
42 delete m_os;
43 m_os = nullptr;
44}
45
46void
47RawTextConfigSave::SetFilename(std::string filename)
48{
49 NS_LOG_FUNCTION(this << filename);
50 m_os = new std::ofstream();
51 m_os->open(filename, std::ios::out);
52}
53
54void
56{
57 NS_LOG_FUNCTION(this);
58
59 class RawTextDefaultIterator : public AttributeDefaultIterator
60 {
61 public:
62 RawTextDefaultIterator(std::ostream* os)
63 {
64 m_os = os;
65 }
66
67 private:
68 void StartVisitTypeId(std::string name) override
69 {
70 m_typeId = name;
71 }
72
73 void DoVisitAttribute(std::string name, std::string defaultValue) override
74 {
75 NS_LOG_DEBUG("Saving " << m_typeId << "::" << name);
76 TypeId tid = TypeId::LookupByName(m_typeId);
77 ns3::TypeId::SupportLevel supportLevel = TypeId::SupportLevel::SUPPORTED;
78 std::string originalInitialValue;
79 std::string valueTypeName;
80 for (std::size_t i = 0; i < tid.GetAttributeN(); i++)
81 {
83 if (tmp.name == name)
84 {
85 supportLevel = tmp.supportLevel;
86 originalInitialValue = tmp.originalInitialValue->SerializeToString(tmp.checker);
87 valueTypeName = tmp.checker->GetValueTypeName();
88 break;
89 }
90 }
91 if (valueTypeName == "ns3::CallbackValue")
92 {
93 NS_LOG_WARN("Global attribute " << m_typeId << "::" << name
94 << " was not saved because it is a CallbackValue");
95 return;
96 }
97 if (supportLevel == TypeId::SupportLevel::OBSOLETE)
98 {
99 NS_LOG_WARN("Global attribute " << m_typeId << "::" << name
100 << " was not saved because it is OBSOLETE");
101 return;
102 }
103 if (supportLevel == TypeId::SupportLevel::DEPRECATED &&
104 defaultValue == originalInitialValue)
105 {
106 NS_LOG_WARN("Global attribute "
107 << m_typeId << "::" << name
108 << " was not saved because it is DEPRECATED and its value has not "
109 "changed from the original initial value");
110 return;
111 }
112 *m_os << "default " << m_typeId << "::" << name << " \"" << defaultValue << "\""
113 << std::endl;
114 }
115
116 std::string m_typeId;
117 std::ostream* m_os;
118 };
119
120 RawTextDefaultIterator iterator = RawTextDefaultIterator(m_os);
121 iterator.Iterate();
122}
123
124void
126{
127 NS_LOG_FUNCTION(this);
128 for (auto i = GlobalValue::Begin(); i != GlobalValue::End(); ++i)
129 {
130 StringValue value;
131 (*i)->GetValue(value);
132 NS_LOG_LOGIC("Saving " << (*i)->GetName());
133 *m_os << "global " << (*i)->GetName() << " \"" << value.Get() << "\"" << std::endl;
134 }
135}
136
137void
139{
140 NS_LOG_FUNCTION(this);
141
142 class RawTextAttributeIterator : public AttributeIterator
143 {
144 public:
145 RawTextAttributeIterator(std::ostream* os)
146 : m_os(os)
147 {
148 }
149
150 private:
151 void DoVisitAttribute(Ptr<Object> object, std::string name) override
152 {
153 StringValue str;
154 TypeId tid = object->GetInstanceTypeId();
155
156 auto [found, inTid, attr] = TypeId::FindAttribute(tid, name);
157
158 if (found)
159 {
160 if (attr.checker && attr.checker->GetValueTypeName() == "ns3::CallbackValue")
161 {
162 NS_LOG_WARN("Attribute " << GetCurrentPath()
163 << " was not saved because it is a CallbackValue");
164 return;
165 }
166 auto supportLevel = attr.supportLevel;
167 if (supportLevel == TypeId::SupportLevel::OBSOLETE)
168 {
169 NS_LOG_WARN("Attribute " << GetCurrentPath()
170 << " was not saved because it is OBSOLETE");
171 return;
172 }
173
174 std::string originalInitialValue =
175 attr.originalInitialValue->SerializeToString(attr.checker);
176 object->GetAttribute(name, str, true);
177
178 if (supportLevel == TypeId::SupportLevel::DEPRECATED &&
179 str.Get() == originalInitialValue)
180 {
181 NS_LOG_WARN("Attribute "
182 << GetCurrentPath()
183 << " was not saved because it is DEPRECATED and its value has not "
184 "changed from the original initial value");
185 return;
186 }
187 NS_LOG_DEBUG("Saving " << GetCurrentPath());
188 *m_os << "value " << GetCurrentPath() << " \"" << str.Get() << "\"" << std::endl;
189 }
190 }
191
192 std::ostream* m_os;
193 };
194
195 RawTextAttributeIterator iter = RawTextAttributeIterator(m_os);
196 iter.Iterate();
197}
198
200 : m_is(nullptr)
201{
202 NS_LOG_FUNCTION(this);
203}
204
206{
207 NS_LOG_FUNCTION(this);
208 if (m_is != nullptr)
209 {
210 m_is->close();
211 delete m_is;
212 m_is = nullptr;
213 }
214}
215
216void
218{
219 NS_LOG_FUNCTION(this << filename);
220 m_is = new std::ifstream();
221 m_is->open(filename, std::ios::in);
222}
223
224std::string
225RawTextConfigLoad::Strip(std::string value)
226{
227 NS_LOG_FUNCTION(this << value);
228 std::string::size_type start = value.find('\"');
229 std::string::size_type end = value.find('\"', 1);
230 NS_ABORT_MSG_IF(start != 0, "Ill-formed attribute value: " << value);
231 NS_ABORT_MSG_IF(end != value.size() - 1, "Ill-formed attribute value: " << value);
232 return value.substr(start + 1, end - start - 1);
233}
234
235void
237{
238 NS_LOG_FUNCTION(this);
239 m_is->clear();
240 m_is->seekg(0);
241 std::string type;
242 std::string name;
243 std::string value;
244 for (std::string line; std::getline(*m_is, line);)
245 {
246 if (!ParseLine(line, type, name, value))
247 {
248 continue;
249 }
250
251 NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
252 value = Strip(value);
253 if (type == "default")
254 {
255 Config::SetDefault(name, StringValue(value));
256 }
257 name.clear();
258 type.clear();
259 value.clear();
260 }
261}
262
263void
265{
266 NS_LOG_FUNCTION(this);
267 m_is->clear();
268 m_is->seekg(0);
269 std::string type;
270 std::string name;
271 std::string value;
272 for (std::string line; std::getline(*m_is, line);)
273 {
274 if (!ParseLine(line, type, name, value))
275 {
276 continue;
277 }
278
279 NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
280 value = Strip(value);
281 if (type == "global")
282 {
283 Config::SetGlobal(name, StringValue(value));
284 }
285 name.clear();
286 type.clear();
287 value.clear();
288 }
289}
290
291void
293{
294 NS_LOG_FUNCTION(this);
295 m_is->clear();
296 m_is->seekg(0);
297 std::string type;
298 std::string name;
299 std::string value;
300 for (std::string line; std::getline(*m_is, line);)
301 {
302 if (!ParseLine(line, type, name, value))
303 {
304 continue;
305 }
306
307 NS_LOG_DEBUG("type=" << type << ", name=" << name << ", value=" << value);
308 value = Strip(value);
309 if (type == "value")
310 {
311 Config::Set(name, StringValue(value));
312 }
313 name.clear();
314 type.clear();
315 value.clear();
316 }
317}
318
319bool
320RawTextConfigLoad::ParseLine(const std::string& line,
321 std::string& type,
322 std::string& name,
323 std::string& value)
324{
325 NS_LOG_FUNCTION(this << line << type << name << value);
326
327 // check for blank line
328 {
329 std::istringstream iss(line);
330 iss >> std::ws; // remove all blanks line
331 if (!iss.good()) // eofbit set if no non-blanks
332 {
333 return false;
334 }
335 }
336
337 if (line.front() == '#')
338 {
339 return false; // comment line
340 }
341
342 // for multiline values, append line to value if type and name not empty
343 if (type.empty() && name.empty())
344 {
345 std::istringstream iss(line);
346 iss >> type >> name >> std::ws;
347 std::getline(iss, value); // remaining line, includes embedded spaces
348 }
349 else
350 {
351 value.append(line);
352 }
353
354 // two quotes in value signifies a completed (possibly multi-line)
355 // config-store entry, return True to signal load function to
356 // validate value (see Strip method) and set attribute
357 return std::count(value.begin(), value.end(), '"') == 2;
358}
359
360} // 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.
static Iterator Begin()
The Begin iterator.
static Iterator End()
The End iterator.
Smart pointer class similar to boost::intrusive_ptr.
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:45
a unique identifier for an interface.
Definition type-id.h:48
std::size_t GetAttributeN() const
Get the number of attributes.
Definition type-id.cc:1170
TypeId::AttributeInformation GetAttribute(std::size_t i) const
Get Attribute information by index.
Definition type-id.cc:1178
SupportLevel
The level of support or deprecation for attributes or trace sources.
Definition type-id.h:62
void SetGlobal(std::string name, const AttributeValue &value)
Definition config.cc:929
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void Set(std::string path, const AttributeValue &value)
Definition config.cc:869
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:250
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Attribute implementation.
Definition type-id.h:70
Ptr< const AttributeValue > originalInitialValue
Default initial value.
Definition type-id.h:78
TypeId::SupportLevel supportLevel
Support level/deprecation.
Definition type-id.h:86
std::string name
Attribute name.
Definition type-id.h:72
Ptr< const AttributeChecker > checker
Checker object.
Definition type-id.h:84