Eclipse SUMO - Simulation of Urban MObility
Parameterised.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 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 /****************************************************************************/
18 // A super class for objects with additional parameters
19 /****************************************************************************/
20 #include <config.h>
25 
26 #include "Parameterised.h"
27 
28 
29 // ===========================================================================
30 // method definitions
31 // ===========================================================================
32 
34  myAttrType(ParameterisedAttrType::STRING) {
35 }
36 
37 
39  myAttrType(attrType) {
40 }
41 
42 
43 Parameterised::Parameterised(const std::map<std::string, std::string>& mapArg) :
44  myAttrType(ParameterisedAttrType::STRING),
45  myMap(mapArg) {
46 }
47 
48 
49 Parameterised::Parameterised(ParameterisedAttrType attrType, const std::map<std::string, std::string>& mapArg) :
50  myAttrType(attrType) {
51  // check if map has to be cleaned
53  // iterate over map
54  for (const auto& keyValue : mapArg) {
55  try {
56  // try to parse to do double, and if fails, write warning
57  StringUtils::toDouble(keyValue.second);
58  // insert keyValue in map
59  myMap.insert(keyValue);
60  } catch (NumberFormatException&) {
61  WRITE_WARNING("Invalid conversion from string to double (" + keyValue.second + ")");
62  }
63  }
64  } else {
65  // just update myMap
66  myMap = mapArg;
67  }
68 }
69 
70 
72 
73 
74 void
75 Parameterised::setParameter(const std::string& key, const std::string& value) {
77  try {
78  // try to parse to do double, and if fails, write warning
79  StringUtils::toDouble(value);
80  // insert in map
81  myMap[key] = value;
82  } catch (NumberFormatException&) {
83  WRITE_WARNING("Invalid conversion from string to double (" + value + ")");
84  }
85  } else {
86  myMap[key] = value;
87  }
88 }
89 
90 
91 void
92 Parameterised::unsetParameter(const std::string& key) {
93  myMap.erase(key);
94 }
95 
96 
97 void
98 Parameterised::updateParameters(const std::map<std::string, std::string>& mapArg) {
99  for (const auto& keyValue : mapArg) {
100  setParameter(keyValue.first, keyValue.second);
101  }
102 }
103 
104 
105 bool
106 Parameterised::knowsParameter(const std::string& key) const {
107  return myMap.find(key) != myMap.end();
108 }
109 
110 
111 const std::string
112 Parameterised::getParameter(const std::string& key, const std::string defaultValue) const {
113  const auto i = myMap.find(key);
114  if (i != myMap.end()) {
115  return i->second;
116  }
117  return defaultValue;
118 }
119 
120 
121 double
122 Parameterised::getDouble(const std::string& key, const double defaultValue) const {
123  const auto i = myMap.find(key);
124  if (i != myMap.end()) {
125  try {
126  return StringUtils::toDouble(i->second);
127  } catch (NumberFormatException&) {
128  WRITE_WARNING("Invalid conversion from string to double (" + i->second + ")");
129  return defaultValue;
130  } catch (EmptyData&) {
131  WRITE_WARNING("Invalid conversion from string to double (empty value)");
132  return defaultValue;
133  }
134  }
135  return defaultValue;
136 }
137 
138 
139 void
141  myMap.clear();
142 }
143 
144 
145 const std::map<std::string, std::string>&
147  return myMap;
148 }
149 
150 
151 std::string
152 Parameterised::getParametersStr(const std::string kvsep, const std::string sep) const {
153  std::string result;
154  // Generate an string using configurable seperatrs, default: "key1=value1|key2=value2|...|keyN=valueN"
155  bool addSep = false;
156  for (const auto& keyValue : myMap) {
157  if (addSep) {
158  result += sep;
159  }
160  result += keyValue.first + kvsep + keyValue.second;
161  addSep = true;
162  }
163  return result;
164 }
165 
166 
167 void
169  // first clear map
170  myMap.clear();
171  // set parameter
172  for (const auto& keyValue : params.getParametersMap()) {
173  setParameter(keyValue.first, keyValue.second);
174  }
175 }
176 
177 
178 void
179 Parameterised::setParametersMap(const std::map<std::string, std::string>& paramsMap) {
180  // first clear map
181  myMap.clear();
182  // set parameter
183  for (const auto& keyValue : paramsMap) {
184  setParameter(keyValue.first, keyValue.second);
185  }
186 }
187 
188 
189 void
190 Parameterised::setParametersStr(const std::string& paramsString, const std::string kvsep, const std::string sep) {
191  // clear parameters
192  myMap.clear();
193  // separate value in a vector of string using | as separator
194  std::vector<std::string> parameters = StringTokenizer(paramsString, sep).getVector();
195  // iterate over all values
196  for (const auto& keyValue : parameters) {
197  // obtain key and value and save it in myParameters
198  std::vector<std::string> keyValueStr = StringTokenizer(keyValue, kvsep).getVector();
199  setParameter(keyValueStr.front(), keyValueStr.back());
200  }
201 }
202 
203 
204 void
206  // iterate over all parameters and write it
207  for (const auto& keyValue : myMap) {
208  device.openTag(SUMO_TAG_PARAM);
209  device.writeAttr(SUMO_ATTR_KEY, StringUtils::escapeXML(keyValue.first));
210  device.writeAttr(SUMO_ATTR_VALUE, StringUtils::escapeXML(keyValue.second));
211  device.closeTag();
212  }
213 }
214 
215 
216 bool
217 Parameterised::areParametersValid(const std::string& value, bool report,
218  const ParameterisedAttrType attrType, const std::string kvsep, const std::string sep) {
219  std::vector<std::string> parameters = StringTokenizer(value, sep).getVector();
220  // first check if parsed parameters are valid
221  for (const auto& keyValueStr : parameters) {
222  // check if parameter is valid
223  if (!isParameterValid(keyValueStr, attrType, kvsep, sep)) {
224  // report depending of flag
225  if (report) {
226  WRITE_WARNING("Invalid format of parameter (" + keyValueStr + ")");
227  }
228  return false;
229  }
230  }
231  // all ok, then return true
232  return true;
233 }
234 
235 // ===========================================================================
236 // private
237 // ===========================================================================
238 
239 bool
240 Parameterised::isParameterValid(const std::string& value, ParameterisedAttrType attrType,
241  const std::string& kvsep, const std::string& sep) {
242  if (value.find(sep) != std::string::npos || value.find(kvsep) == std::string::npos) {
243  return false;
244  }
245  // separate key and value
246  std::vector<std::string> keyValueStr = StringTokenizer(value, kvsep).getVector();
247  // Check that keyValue size is exactly 2 (key, value)
248  if (keyValueStr.size() == 2) {
249  // check if key and value contains valid characters
250  if (SUMOXMLDefinitions::isValidParameterKey(keyValueStr.front()) == false) {
251  return false;
252  } else if (attrType == ParameterisedAttrType::DOUBLE) {
253  // check if can be parsed to double
254  try {
255  StringUtils::toDouble(keyValueStr.back());
256  return true;
257  } catch (NumberFormatException&) {
258  return false;
259  }
260  } else {
261  // key=value valid, then return true
262  return true;
263  }
264  } else {
265  // invalid format
266  return false;
267  }
268 }
269 
270 /****************************************************************************/
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_KEY
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
An upper class for objects with additional parameters.
Definition: Parameterised.h:39
ParameterisedAttrType
@brie enum for Parameterised type
Definition: Parameterised.h:43
@ DOUBLE
Parameterised only accept doubles.
static bool isParameterValid(const std::string &value, ParameterisedAttrType attrType, const std::string &kvsep, const std::string &sep)
check if given string can be parsed to a parameter of type "key=value"
void unsetParameter(const std::string &key)
Removes a parameter.
static bool areParametersValid(const std::string &value, bool report=false, ParameterisedAttrType attrType=ParameterisedAttrType::STRING, const std::string kvsep="=", const std::string sep="|")
check if given string can be parsed to a parameters map "key1=value1|key2=value2|....
double getDouble(const std::string &key, const double defaultValue) const
Returns the value for a given key converted to a double.
Parameterised()
Default constructor (for Strings)
void setParameters(const Parameterised &params)
set the inner key/value map in map<string, string> format
void setParametersStr(const std::string &paramsString, const std::string kvsep="=", const std::string sep="|")
set the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN"
~Parameterised()
Destructor.
void clearParameter()
Clears the parameter map.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
std::map< std::string, std::string > myMap
The key->value map.
ParameterisedAttrType myAttrType
parameterised type
void writeParams(OutputDevice &device) const
write Params in the given outputdevice
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
std::string getParametersStr(const std::string kvsep="=", const std::string sep="|") const
Returns the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN".
void updateParameters(const std::map< std::string, std::string > &mapArg)
Adds or updates all given parameters from the map.
void setParametersMap(const std::map< std::string, std::string > &paramsMap)
set the inner key/value map in map<string, string> format
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
static bool isValidParameterKey(const std::string &value)
whether the given string is a valid key for a parameter
std::vector< std::string > getVector()
return vector of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.