Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/common/Parameterised.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file Parameterised.cpp
15
/// @author Daniel Krajzewicz
16
/// @date Sept 2002
17
///
18
// A super class for objects with additional parameters
19
/****************************************************************************/
20
#include <config.h>
21
#include <utils/common/MsgHandler.h>
22
#include <utils/common/StringUtils.h>
23
#include <utils/common/StringTokenizer.h>
24
#include <utils/iodevices/OutputDevice.h>
25
26
#include "Parameterised.h"
27
28
29
// ===========================================================================
30
// method definitions
31
// ===========================================================================
32
33
Parameterised::Parameterised() {}
34
35
36
Parameterised::Parameterised(const Parameterised::Map& mapArg) :
37
myMap(mapArg) {
38
}
39
40
41
Parameterised::~Parameterised() {}
42
43
44
void
45
Parameterised::setParameter(const std::string& key, const std::string& value) {
46
myMap[key] = value;
47
}
48
49
50
void
51
Parameterised::unsetParameter(const std::string& key) {
52
myMap.erase(key);
53
}
54
55
56
void
57
Parameterised::updateParameters(const Parameterised::Map& mapArg) {
58
for (const auto& keyValue : mapArg) {
59
setParameter(keyValue.first, keyValue.second);
60
}
61
}
62
63
64
void
65
Parameterised::mergeParameters(const Parameterised::Map& mapArg, const std::string separator, bool uniqueValues) {
66
for (const auto& keyValue : mapArg) {
67
if (hasParameter(keyValue.first)) {
68
bool append = true;
69
if (uniqueValues) {
70
if (getParameter(keyValue.first) == keyValue.second) {
71
append = false;
72
}
73
}
74
if (append) {
75
setParameter(keyValue.first, getParameter(keyValue.first) + separator + keyValue.second);
76
}
77
} else {
78
setParameter(keyValue.first, keyValue.second);
79
}
80
}
81
}
82
83
bool
84
Parameterised::hasParameter(const std::string& key) const {
85
return myMap.find(key) != myMap.end();
86
}
87
88
89
const std::string
90
Parameterised::getParameter(const std::string& key, const std::string defaultValue) const {
91
const auto i = myMap.find(key);
92
if (i != myMap.end()) {
93
return i->second;
94
}
95
return defaultValue;
96
}
97
98
99
double
100
Parameterised::getDouble(const std::string& key, const double defaultValue) const {
101
const auto i = myMap.find(key);
102
if (i != myMap.end()) {
103
try {
104
return StringUtils::toDouble(i->second);
105
} catch (NumberFormatException&) {
106
WRITE_WARNINGF(TL("Invalid conversion from string to double (%)"), i->second);
107
return defaultValue;
108
} catch (EmptyData&) {
109
WRITE_WARNING(TL("Invalid conversion from string to double (empty value)"));
110
return defaultValue;
111
}
112
}
113
return defaultValue;
114
}
115
116
117
void
118
Parameterised::clearParameter() {
119
myMap.clear();
120
}
121
122
123
const Parameterised::Map&
124
Parameterised::getParametersMap() const {
125
return myMap;
126
}
127
128
129
std::string
130
Parameterised::getParametersStr(const std::string kvsep, const std::string sep) const {
131
std::string result;
132
// Generate an string using configurable seperatrs, default: "key1=value1|key2=value2|...|keyN=valueN"
133
bool addSep = false;
134
for (const auto& keyValue : myMap) {
135
if (addSep) {
136
result += sep;
137
}
138
result += keyValue.first + kvsep + keyValue.second;
139
addSep = true;
140
}
141
return result;
142
}
143
144
145
void
146
Parameterised::setParameters(const Parameterised& params) {
147
myMap = params.getParametersMap();
148
}
149
150
151
void
152
Parameterised::setParameters(const std::vector<std::pair<std::string, std::string> >& params) {
153
myMap.clear();
154
for (const auto& keyValue : params) {
155
myMap[keyValue.first] = keyValue.second;
156
}
157
}
158
159
160
void
161
Parameterised::setParametersStr(const std::string& paramsString, const std::string kvsep, const std::string sep) {
162
// clear parameters
163
myMap.clear();
164
// separate value in a vector of string using | as separator
165
std::vector<std::string> parameters = StringTokenizer(paramsString, sep).getVector();
166
// iterate over all values
167
for (const auto& keyValue : parameters) {
168
// obtain key and value and save it in myParameters
169
std::vector<std::string> keyValueStr = StringTokenizer(keyValue, kvsep).getVector();
170
setParameter(keyValueStr.front(), keyValueStr.back());
171
}
172
}
173
174
175
void
176
Parameterised::writeParams(OutputDevice& device) const {
177
// iterate over all parameters and write it
178
for (const auto& keyValue : myMap) {
179
device.openTag(SUMO_TAG_PARAM);
180
device.writeAttr(SUMO_ATTR_KEY, StringUtils::escapeXML(keyValue.first));
181
device.writeAttr(SUMO_ATTR_VALUE, StringUtils::escapeXML(keyValue.second));
182
device.closeTag();
183
}
184
}
185
186
187
bool
188
Parameterised::areParametersValid(const std::string& value, bool report, const std::string kvsep, const std::string sep) {
189
std::vector<std::string> parameters = StringTokenizer(value, sep).getVector();
190
// first check if parsed parameters are valid
191
for (const auto& keyValueStr : parameters) {
192
// check if parameter is valid
193
if (!isParameterValid(keyValueStr, kvsep, sep)) {
194
// report depending of flag
195
if (report) {
196
WRITE_WARNINGF(TL("Invalid format of parameter (%)"), keyValueStr);
197
}
198
return false;
199
}
200
}
201
// all ok, then return true
202
return true;
203
}
204
205
206
bool
207
Parameterised::areAttributesValid(const std::string& value, bool report, const std::string kvsep, const std::string sep) {
208
std::vector<std::string> parameters = StringTokenizer(value, sep).getVector();
209
// first check if parsed parameters are valid
210
for (const auto& keyValueStr : parameters) {
211
// check if parameter is valid
212
if (isParameterValid(keyValueStr, kvsep, sep)) {
213
// separate key and value
214
const auto attr = StringTokenizer(value, kvsep).getVector().front();
215
// get first letter
216
const auto letter = StringTokenizer(value, kvsep).getVector().front().front();
217
// check key
218
if (!((letter >= 'a') && (letter <= 'z')) && !((letter >= 'A') && (letter <= 'Z'))) {
219
// report depending of flag
220
if (report) {
221
WRITE_WARNINGF(TL("Invalid format of attribute '%'. Attribute must start with a letter"), attr);
222
}
223
return false;
224
}
225
} else {
226
// report depending of flag
227
if (report) {
228
WRITE_WARNINGF(TL("Invalid format of attribute (%)"), keyValueStr);
229
}
230
return false;
231
}
232
}
233
// all ok, then return true
234
return true;
235
}
236
237
// ===========================================================================
238
// private
239
// ===========================================================================
240
241
bool
242
Parameterised::isParameterValid(const std::string& value, const std::string& kvsep, const std::string& sep) {
243
if (value.find(sep) != std::string::npos || value.find(kvsep) == std::string::npos) {
244
return false;
245
}
246
// separate key and value
247
std::vector<std::string> keyValueStr = StringTokenizer(value, kvsep).getVector();
248
// Check that keyValue size is exactly 2 (key, value)
249
if (keyValueStr.size() == 2) {
250
// check if key and value contains valid characters
251
if (SUMOXMLDefinitions::isValidParameterKey(keyValueStr.front()) == false) {
252
return false;
253
} else {
254
// key=value valid, then return true
255
return true;
256
}
257
} else {
258
// invalid format
259
return false;
260
}
261
}
262
263
/****************************************************************************/
264
265