ConfigFile.hpp
Go to the documentation of this file.
1 // ConfigFile.hpp
2 // Class for reading named values from configuration files
3 // Richard J. Wagner v2.1 24 May 2004 wagnerr@umich.edu
4 
5 // Copyright (c) 2004 Richard J. Wagner
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to
9 // deal in the Software without restriction, including without limitation the
10 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 // sell copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 // IN THE SOFTWARE.
24 
25 // Typical usage
26 // -------------
27 //
28 // Given a configuration file "settings.inp":
29 // atoms = 25
30 // length = 8.0 # nanometers
31 // name = Reece Surcher
32 //
33 // Named values are read in various ways, with or without default values:
34 // ConfigFile config( "settings.inp" );
35 // int atoms = config.read<int>( "atoms" );
36 // double length = config.read( "length", 10.0 );
37 // string author, title;
38 // config.readInto( author, "name" );
39 // config.readInto( title, "title", string("Untitled") );
40 //
41 // See file example.cpp for more examples.
42 //***************************************************************************
43 // Modified 04 February 2011 by
44 // Franz Ehrenhuber, Codronic GmbH
45 //
46 // It's now possible to query sections in config files
47 // Default sections are defined like [sectionname],
48 // but it is possible to use different tags
49 // Section related adding/removing of entries is implemented.
50 // Changes have to be saved.
51 //
52 // Examples:
53 // youbot::ConfigFile *cfgFile = new youbot::ConfigFile("youbot-manipulator", path);
54 // cfgFile->readInto( i1, "Joint_5", "UpperLimit_[encoderTicks]");
55 // if(cfgFile->keyExists("Joint_3", "CalibrationDirection"))
56 // {
57 // cout << "Key CalibrationDirection exists" << endl;
58 // }
59 // cfgFile->remove("Joint_1", "Test");
60 // cfgFile->add("Joint_1", "Test1", 77);
61 // cfgFile->save();
62 //***************************************************************************
63 
64 #ifndef CONFIGFILE_HPP
65 #define CONFIGFILE_HPP
66 
67 #include <string>
68 #include <map>
69 #include <vector>
70 #include <algorithm>
71 #include <fstream>
72 #include <sstream>
74 
75 using std::string;
76 
77 namespace youbot {
78 
83  protected:
84  string myKey;
85  vector<string> mySortVector;
86 
87  public:
88 
90  myKey = "";
91  };
92 
93  string getKey() {
94  if (myKey.empty()) return "";
95 
96  if (myKey.size() > 0) {
97  return myKey;
98  }
99 
100  return "";
101 
102 
103  }
104 
105  void setKey(const string& sKey) {
106  myKey = sKey;
107  }
108 
109  std::vector<string> getVector() const {
110  return mySortVector;
111  }
112 
113  void setVector(const std::vector<string>& vVector) {
114  mySortVector = vVector;
115  }
116 
118  };
119 
120  };
121 
125  class ConfigFile {
126  // Data
127  protected:
128  string myDelimiter; // separator between key and value
129  string myComment; // separator between value and comments
130  string mySectionStartTag; // tag marks the beginning of a section header
131  string mySectionEndTag; // tag marks the end of a section header
132  string mySentry; // optional string to signal end of file
133  string myFilepath; //Path to Configfile
134  SortTreeVector *mySortVectorObj; // Keeps vector for sorting contents and its relation to the Section Key
135 
136  std::map<string, string> myContents; // extracted keys and values
137  std::map<string, std::map<string, string> > mySectionRelatedContents; // A List of all sections with their extrated key/values
138 
139  std::vector<SortTreeVector> mySortVector; // keeps SortTreeVector objects for sorting on Sections an their contents
140 
141  typedef std::map<string, string>::iterator mapi;
142  typedef std::map<string, string>::const_iterator mapci;
143  typedef std::map<string, map<string, string> >::const_iterator mapciSect;
144 
145  // Methods
146  public:
147 
148  ConfigFile(string filename,
149  string filepath = "../config/",
150  string delimiter = "=",
151  string comment = "#",
152  string sectionStartTag = "[",
153  string sectionEndTag = "]",
154  string sentry = "EndConfigFile");
155  ConfigFile();
156 
158 
159  // Search for key and read value or optional default value
160  template<class T> T read(const string& key, const T& value)const;
161 
162  //Overload to read key from section lines
163  template<class T> T read(const string& key) const; // call as read<T>
164 
165  //Overload to read key from section lines
166  template<class T> T read(const string& sectionKey, const string& key); // call as read<T>
167 
168 
169  //Read key into ref variable
170  template<class T> bool readInto(T& var, const string& key) const;
171  //Overload to read key from section lines
172  template<class T> bool readInto(T& var, const string& sectionKey, const string& key);
173 
174  template<class T>
175  bool readInto(T& var, const string& key, const T& value) const;
176 
177  // Modify keys and values
178  template<class T> void add(string key, const T& value);
179 
180  // Modify keys and values beyond a sectionkey
181  template<class T> void add(string sectionKey, string key, const T& value);
182 
183 
184  //Remove key from config file with no sections
185  void remove(const string& key);
186  //Remove one key from specified section
187  void remove(const string& sectionKey, const string& key);
188 
189  //Save Changes to Configfile
190  //should be invoked after removing/adding keys
191  void save();
192 
193 
194 
195  // Check whether key exists in configuration
196  bool keyExists(const string& key) const;
197  // Overload to check key inside a section
198  bool keyExists(const string& sectionKey, const string& key);
199 
200  //Check for existing section
201  bool sectionExists(const string& sectionKey);
202 
203 
204 
205  // Check or change configuration syntax
206 
207  string getDelimiter() const {
208  return myDelimiter;
209  }
210 
211  string getComment() const {
212  return myComment;
213  }
214 
215  string getSentry() const {
216  return mySentry;
217  }
218 
219  string setDelimiter(const string& s) {
220  string old = myDelimiter;
221  myDelimiter = s;
222  return old;
223  }
224 
225  string setComment(const string& s) {
226  string old = myComment;
227  myComment = s;
228  return old;
229  }
230 
231  // Write or read configuration
232  friend std::ostream & operator<<(std::ostream& os, ConfigFile& cf);
233  friend std::istream & operator>>(std::istream& is, ConfigFile& cf);
234 
235  protected:
236  template<class T> static string T_as_string(const T& t);
237  template<class T> static T string_as_T(const string& s);
238  static void trim(string& s);
239 
240  };
241 
242  /* static */
243  template<class T>
244  string ConfigFile::T_as_string(const T& t) {
245  // Convert from a T to a string
246  // Type T must support << operator
247  std::ostringstream ost;
248  ost << t;
249  return ost.str();
250  }
251 
252  /* static */
253  template<class T>
254  T ConfigFile::string_as_T(const string& s) {
255  // Convert from a string to a T
256  // Type T must support >> operator
257  T t;
258  std::istringstream ist(s);
259  ist >> t;
260  return t;
261  }
262 
263  /* static */
264  template<>
265  inline string ConfigFile::string_as_T<string>(const string& s) {
266  // Convert from a string to a string
267  // In other words, do nothing
268  return s;
269  }
270 
271  /* static */
272  template<>
273  inline bool ConfigFile::string_as_T<bool>(const string& s) {
274  // Convert from a string to a bool
275  // Interpret "false", "F", "no", "n", "0" as false
276  // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
277  bool b = true;
278  string sup = s;
279  for (string::iterator p = sup.begin(); p != sup.end(); ++p)
280  *p = toupper(*p); // make string all caps
281  if (sup == string("FALSE") || sup == string("F") ||
282  sup == string("NO") || sup == string("N") ||
283  sup == string("0") || sup == string("NONE"))
284  b = false;
285  return b;
286  }
287 
288  template<class T>
289  T ConfigFile::read(const string& key) const {
290  mapci p = myContents.find(key);
291  if (p == myContents.end()) throw KeyNotFoundException(key);
292  return string_as_T<T > (p->second);
293  }
294 
295  template<class T>
296  T ConfigFile::read(const string& sectionKey, const string& key) {
297  // Read the value corresponding to key
298  mapciSect sp = mySectionRelatedContents.find(sectionKey);
299  if (sp == mySectionRelatedContents.end()) throw KeyNotFoundException(sectionKey);
300 
301  myContents = sp->second;
302  mapci p = myContents.find(key);
303  if (p == myContents.end()) throw KeyNotFoundException(key);
304  return string_as_T<T > (p->second);
305  }
306 
307  template<class T>
308  T ConfigFile::read(const string& key, const T& value) const {
309  // Return the value corresponding to key or given default value
310  // if key is not found
311  mapci p = myContents.find(key);
312  if (p == myContents.end()) return value;
313  return string_as_T<T > (p->second);
314  }
315 
316  template<class T>
317  bool ConfigFile::readInto(T& var, const string& key) const {
318  // Get the value corresponding to key and store in var
319  // Return true if key is found
320  // Otherwise leave var untouched
321 
322  mapci p = myContents.find(key);
323  bool found = (p != myContents.end());
324  if (found) {
325  var = string_as_T<T > (p->second);
326  } else {
327  throw KeyNotFoundException(key);
328  }
329  return found;
330  }
331 
332  template<class T>
333  bool ConfigFile::readInto(T& var, const string& sectionKey, const string& key) {
334  // Get the value corresponding to key and store in var
335  // Return true if key is found
336  // Otherwise leave var untouched
337 
338  mapciSect sp = mySectionRelatedContents.find(sectionKey);
339  if (sp == mySectionRelatedContents.end()) throw KeyNotFoundException(sectionKey);
340 
341 
342  myContents = sp->second;
343 
344  mapci p = myContents.find(key);
345  bool found = (p != myContents.end());
346  if (found) {
347  var = string_as_T<T > (p->second);
348  } else {
349  throw KeyNotFoundException(key);
350  }
351  return found;
352  }
353 
354  template<class T>
355  void ConfigFile::add(string key, const T& value) {
356  // Add a key with given value
357  string v = T_as_string(value);
358  trim(key);
359  trim(v);
360  //Check for dublicate keys
361  mapi p = myContents.find(key);
362  if (p != myContents.end()) {
363  return;
364  }
365  myContents[key] = v;
366  return;
367  }
368 
369  template<class T>
370  void ConfigFile::add(string sectionKey, string key, const T& value) {
371 
372 
373  // Add a key with given value
374  string v = T_as_string(value);
375  trim(key);
376  trim(v);
377 
378  mapciSect sp = mySectionRelatedContents.find(sectionKey);
379 
380  //Write SectionKey with values if no section found
381  if (sp == mySectionRelatedContents.end()) {
382  SortTreeVector vsort;
383  vector<string> vNewVal;
384  map<string, string> newMap;
385  newMap[key] = v;
386  vsort.setKey(sectionKey);
387  vNewVal.push_back(key);
388  vsort.setVector(vNewVal);
389  mySectionRelatedContents[sectionKey] = newMap;
390  mySortVector.push_back(vsort);
391  return;
392  }
393 
394  myContents = sp->second;
395 
396  //Check for dublicate keys
397  mapi p = myContents.find(key);
398  if (p != myContents.end()) {
399  return;
400  }
401 
402  myContents[key] = v;
403  mySectionRelatedContents[sectionKey] = myContents;
404 
405  for (unsigned int i = 0; i < mySortVector.size(); i++) {
406 
407  if (mySortVector[i].getKey() == sectionKey) {
408  vector<string> sortVec = mySortVector[i].getVector();
409  sortVec.push_back(key);
410  mySortVector[i].setVector(sortVec);
411 
412 
413  }
414  }
415 
416 
417  return;
418  }
419 
420 
421 } // namespace youbot
422 
423 #endif // CONFIGFILE_HPP
424 
425 // Release notes:
426 // v1.0 21 May 1999
427 // + First release
428 // + Template read() access only through non-member readConfigFile()
429 // + ConfigurationFileBool is only built-in helper class
430 //
431 // v2.0 3 May 2002
432 // + Shortened name from ConfigurationFile to ConfigFile
433 // + Implemented template member functions
434 // + Changed default comment separator from % to #
435 // + Enabled reading of multiple-line values
436 //
437 // v2.1 24 May 2004
438 // + Made template specializations inline to avoid compiler-dependent linkage
439 // + Allowed comments within multiple-line values
440 // + Enabled blank line termination for multiple-line values
441 // + Added optional sentry to detect end of configuration file
442 // + Rewrote messy trimWhitespace() function as elegant trim()
443 //
444 // v2.2 04 February 2011
445 // + Added Section support
446 // + Check for duplicate key in add-Method
447 // + Removed KeyNotFoundexception in remove-Method because it is
448 // more convenient not to interrupt if key does not exists.
449 
std::istream & operator>>(std::istream &is, ConfigFile &cf)
Definition: ConfigFile.cpp:138
void setKey(const string &sKey)
Definition: ConfigFile.hpp:105
vector< string > mySortVector
Definition: ConfigFile.hpp:85
std::ostream & operator<<(std::ostream &os, ConfigFile &cf)
Definition: ConfigFile.cpp:104
std::map< string, std::map< string, string > > mySectionRelatedContents
Definition: ConfigFile.hpp:137
T read(const string &key, const T &value) const
Definition: ConfigFile.hpp:308
static T string_as_T(const string &s)
Definition: ConfigFile.hpp:254
XmlRpcServer s
string getSentry() const
Definition: ConfigFile.hpp:215
Reads and writes a configuration file.
Definition: ConfigFile.hpp:125
std::vector< SortTreeVector > mySortVector
Definition: ConfigFile.hpp:139
string getComment() const
Definition: ConfigFile.hpp:211
std::map< string, string >::const_iterator mapci
Definition: ConfigFile.hpp:142
void add(string key, const T &value)
Definition: ConfigFile.hpp:355
Keep track of sortorder from original configfile.
Definition: ConfigFile.hpp:82
string setComment(const string &s)
Definition: ConfigFile.hpp:225
std::vector< string > getVector() const
Definition: ConfigFile.hpp:109
bool readInto(T &var, const string &key) const
Definition: ConfigFile.hpp:317
SortTreeVector * mySortVectorObj
Definition: ConfigFile.hpp:134
string getDelimiter() const
Definition: ConfigFile.hpp:207
Key in configuration file not found exception.
Definition: Exceptions.hpp:85
string setDelimiter(const string &s)
Definition: ConfigFile.hpp:219
std::map< string, string > myContents
Definition: ConfigFile.hpp:136
void setVector(const std::vector< string > &vVector)
Definition: ConfigFile.hpp:113
std::map< string, string >::iterator mapi
Definition: ConfigFile.hpp:141
static string T_as_string(const T &t)
Definition: ConfigFile.hpp:244
std::map< string, map< string, string > >::const_iterator mapciSect
Definition: ConfigFile.hpp:143


youbot_driver
Author(s): Jan Paulus
autogenerated on Mon Jun 10 2019 15:46:24