charon-core  0.3.1
ParameterFile.cpp
Go to the documentation of this file.
1 /* This file is part of Charon.
2 
3  Charon is free software: you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as published by
5  the Free Software Foundation, either version 3 of the License, or
6  (at your option) any later version.
7 
8  Charon 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 Lesser General Public License for more details.
12 
13  You should have received a copy of the GNU Lesser General Public License
14  along with Charon. If not, see <http://www.gnu.org/licenses/>.
15  */
29 #include <set>
30 
31 ParameterFile::IoError::IoError(const std::string& msg) :
32  std::runtime_error(msg.c_str()) {
33 }
34 
35 ParameterFile::Unset::Unset(const std::string& msg) :
36  std::invalid_argument(msg) {
37 }
38 
40  _noFoundWarnings(false), _convertSlashes(true), _delimiter(';') {
41 }
42 
43 ParameterFile::ParameterFile(std::string fileName) :
44  _noFoundWarnings(false), _convertSlashes(true), _delimiter(';') {
45  load(fileName);
46 }
47 
49 }
50 
51 void ParameterFile::setDelimiter(char delimiter) {
52  _delimiter = delimiter;
53 }
54 
55 void ParameterFile::setConvertSlashes(bool convertSlashes) {
56  _convertSlashes = convertSlashes;
57 }
58 
59 void ParameterFile::_set(std::string parameter, std::string value) {
60  if (isSet(parameter))
61  _setParams["[mod] " + parameter] = value;
62  else {
63  _setParams[" " + parameter] = value;
64  _parameterLines.push_back(parameter);
65  }
66  _toLower(parameter);
67  _params[parameter] = value;
68 }
69 
71  _parameterLines.clear();
72  _params.clear();
73  _setParams.clear();
74 }
75 
77  _setParams.clear();
78 }
79 
80 void ParameterFile::setNotFoundWarningsOn(bool noFoundWarnings) {
81  _noFoundWarnings = noFoundWarnings;
82 }
83 
84 bool ParameterFile::save(std::string fileName) const {
85  std::ofstream file(fileName.c_str(), std::ios::trunc);
86  if (file.bad()) {
88  "Parameter file \"" + fileName + "\" could not be saved. "
89  "(file.bad())");
90  } else {
91  toStream(file);
92  file.close();
93  return true;
94  }
95 }
96 
97 bool ParameterFile::load(std::string fileName) {
98  if (!FileTool::exists(fileName))
100  "Parameter file \"" + fileName + "\": "
101  "does not exist.");
102  std::ifstream file;
103  file.open(fileName.c_str());
104  if (file.fail()) {
106  "Parameter file \"" + fileName + "\" could not be opened. "
107  "(file.fail())");
108  } else {
109  clear();
110  fromStream(file);
111  file.close();
112  return true;
113  }
114 }
115 
116 std::vector<std::string> ParameterFile::getKeyList(std::string beginsWith) const {
117  std::vector<std::string> result;
118  _toLower(beginsWith);
119 
120  // use parameterLines to preserve order and case
121  std::vector<std::string>::const_iterator iter;
122  std::string key, keyL;
123  for (iter=_parameterLines.begin(); iter!=_parameterLines.end(); iter++) {
124  if (iter->empty()) {
125  continue;
126  }
127  key = keyL = *iter;
128  _toLower(keyL);
129  if (beginsWith.empty() ||
130  ((keyL.length() >= beginsWith.length()) &&
131  (keyL.substr(0,beginsWith.length()) == beginsWith))) {
132  result.push_back(key);
133  }
134  }
135  return result;
136 }
137 
138 std::vector<std::string> ParameterFile::getEveryParameter(
139  const std::string & param) const {
140  std::vector<std::string> result;
141 
142  // use parameterLines to preserve order
143  std::vector<std::string>::const_iterator it;
144 
145  for (it = _parameterLines.begin(); it != _parameterLines.end(); it++) {
146  std::string key = *it;
147  size_t pos = key.find_first_of('.');
148  if (key.length() >= pos + param.length() && (key.substr(pos + 1,
149  param.length()) == param))
150  result.push_back(key);
151  }
152  return result;
153 }
154 
156  std::map<std::string, std::string>::const_iterator i = _setParams.begin();
157  int p = 0;
158  unsigned int maxSize = 0;
159  while (i != _setParams.end()) {
160  std::string key = i->first;
161  if (key.size() > maxSize)
162  maxSize = (unsigned int) key.size();
163  ++i;
164  }
165 
166  i = _setParams.begin();
167  while (i != _setParams.end()) {
168  std::string key = i->first;
169  std::string value = i->second;
170  std::string fillUp;
171  if ((p++ % 2) != 0) {
172  fillUp = std::string(maxSize - key.size(), ' ');
173  sout << key << " " << fillUp << " " << value << std::endl;
174  } else {
175  fillUp = std::string(maxSize - key.size(), '-');
176  sout << key << " " << fillUp << "> " << value << std::endl;
177  }
178  ++i;
179  }
180 }
181 
182 void ParameterFile::toStream(std::ostream& strm) const {
183  std::vector<std::string>::const_iterator i;
184  for (i = _parameterLines.begin(); i != _parameterLines.end(); i++) {
185  std::string key = *i;
186  if (key != "") {
187  std::string value = get<std::string> (key);
188  strm << key << "\t\t" << value << std::endl;
189  } else
190  strm << std::endl;
191  }
192 }
193 
194 void ParameterFile::fromStream(std::istream& strm) {
195  std::set<std::string> processedKeys;
196  while (strm.good()) {
197  std::string key, line, value;
198  if (strm.peek() == '\n')
199  _parameterLines.push_back(""); //preserve empty lines
200  strm >> key;
201  key = StringTool::trim(key);
202  if (!key.empty()) {
203  if (key.substr(0, 1) != "#") {
204  value = "";
205  bool cont = true;
206  while (cont) {
207  // allow empty strings as parameter value
208  getline(strm, line);
209  line = StringTool::trim(line);
210  if (line.empty()) {
211  // stop continuing
212  cont = false;
213  }
214  else {
215  // strip comments (after input)
216  size_t cPos = line.find("#");
217  line = StringTool::trim(line.substr(0, cPos));
218  // handle line breaks (ending with '\')
219  const char& test = line.at(line.length()-1);
220  if ((cont = (test == '\\'))) {
221  line = line.substr(0, line.length()-1);
222  }
223  value += line;
224  }
225  }
226  if (processedKeys.find(key) != processedKeys.end()) {
227  sout << "(WW) fromStream: "
228  << "Duplicate Key in Parameter File: "
229  << key << std::endl;
230  }
231  _set(key,value);
232  processedKeys.insert(key);
233  } else {
234  //ignore whole line (when comment line)
235  getline(strm, line);
236  }
237  }
238  }
239 }
240 
241 void ParameterFile::erase(std::string parameter) {
242  if (!isSet(parameter))
243  throw ParameterFile::Unset("Parameter " + parameter + " not set");
244 
245  // Add delete information into log list
246  _setParams["[del] " + parameter] = get<std::string>(parameter);
247 
248  // delete parameter from parameter store and parameterLines
249  _toLower(parameter);
250  _params.erase(parameter);
251 
252  std::vector<std::string>::iterator pos = _parameterLines.begin();
253  std::string cur;
254  while (pos != _parameterLines.end()) {
255  cur = *pos;
256  _toLower(cur);
257  if (cur == parameter)
258  break;
259  pos++;
260  }
261  _parameterLines.erase(pos);
262 }
263 
std::map< std::string, std::string > _params
maps parameters to their respective values
Definition: ParameterFile.h:92
std::string charon_core_DLL_PUBLIC trim(const std::string &s, const std::string &t=" \t\r\n")
Remove (whitespace) characters from head and tail of a string.
Definition: StringTool.cpp:41
void showSetParams() const
Print a list of all set parameters to sout.
SplitStream sout
Dummy instance for usage in other files (for interface too).
void erase(std::string parameter)
Delete a parameter from the parameter list.
void _toLower(std::string &input) const
Get the lowercase version of a string.
void setDelimiter(char delimiter)
Change property delimiter.
Exception thrown when trying to access unset parameters.
bool charon_core_DLL_PUBLIC exists(const std::string &file)
Check if file exists.
Definition: FileTool.cpp:154
void clear()
Clear parameter list.
std::map< std::string, std::string > _setParams
stores modified and new parameters in a seperate map (see showSetParams())
Definition: ParameterFile.h:96
void resetSetParams()
Clear list of modifications.
bool _convertSlashes
convert linux to windows slashes and vice versa (depends on define CHARON_LINUX/CHARON_WINDOWS in Str...
std::vector< std::string > getKeyList(std::string beginsWith="") const
Look for parameters beginning with a given string.
std::vector< std::string > _parameterLines
this vector keeps a copy of all parameters in order to preserve their ordering in the actual file it ...
Definition: ParameterFile.h:89
char _delimiter
delimiter for lists of values (default is ';')
Unset(const std::string &msg)
constuctor using given error message
I/O error exception thrown by ParameterFile instances.
bool isSet(std::string parameter) const
Check if a givem parameter has already been set.
void setConvertSlashes(bool convertSlashes)
Change property convertSlashes.
Implementation of the template class ParameterFile.
bool _noFoundWarnings
warn if parameter was not found
void _set(std::string parameter, std::string value)
Store a string value to the parameter list.
void fromStream(std::istream &strm)
Restore parameters reading from the given stream.
bool save(std::string fileName) const
Save parameters and values to a plain text file.
ParameterFile()
Default constructor.
void toStream(std::ostream &strm) const
Save parameters in the same order as they where inserted.
void setNotFoundWarningsOn(bool noFoundWarnings)
Set property noFoundWarnings.
~ParameterFile()
Default destructor.
charon_DEPRECATED std::vector< std::string > getEveryParameter(const std::string &param) const
Look for parameters ignoring the instance name.
IoError(const std::string &msg)
constuctor using given error message
bool load(std::string fileName)
Load parameters from the given file.