Main MRPT website > C++ reference
MRPT logo
CConfigFileBase.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 #ifndef CConfigFileBase_H
29 #define CConfigFileBase_H
30 
31 #include <mrpt/utils/utils_defs.h>
32 #include <mrpt/utils/TEnumType.h>
35 
36 /*---------------------------------------------------------------
37  Class
38  ---------------------------------------------------------------*/
39 namespace mrpt
40 {
41 namespace utils
42 {
43  /** This class allows loading and storing values and vectors of different types from a configuration text, which can be implemented as a ".ini" file, a memory-stored string, etc...
44  * This is a virtual class, use only as a pointer to an implementation of one of the derived classes.
45  * \ingroup mrpt_base_grp
46  */
48  {
49  protected:
50  /** A virtual method to write a generic string.
51  */
52  virtual void writeString(const std::string &section,const std::string &name, const std::string &str) = 0;
53 
54  /** A virtual method to read a generic string.
55  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
56  */
57  virtual std::string readString(
58  const std::string &section,
59  const std::string &name,
60  const std::string &defaultStr,
61  bool failIfNotFound = false) const = 0;
62 
63  public:
64  /** Virtual destructor...
65  */
66  virtual ~CConfigFileBase()
67  {
68  }
69 
70  /** Returns a list with all the section names.
71  */
72  virtual void getAllSections( vector_string &sections ) const = 0 ;
73 
74  /** Returs a list with all the keys into a section.
75  */
76  virtual void getAllKeys( const std::string section, vector_string &keys ) const = 0;
77 
78  /** Checks if a given section exists (name is case insensitive) */
79  bool sectionExists( const std::string &section_name) const;
80 
81  /** Save a configuration parameter of type "double"
82  */
83  void write(const std::string &section, const std::string &name, double value);
84 
85  /** Save a configuration parameter of type "float"
86  */
87  void write(const std::string &section, const std::string &name, float value);
88 
89  /** Save a configuration parameter of type "int"
90  */
91  void write(const std::string &section, const std::string &name, int value);
92 
93  /** Save a configuration parameter of type "unsigned int"
94  */
95  void write(const std::string &section, const std::string &name, unsigned int value);
96 
97 #if MRPT_WORD_SIZE>32
98  /** Save a configuration parameter of type "size_t"
99  */
100  void write(const std::string &section, const std::string &name, size_t value);
101 #endif
102 
103  /** Save a configuration parameter of type "string"
104  */
105  void write(const std::string &section, const std::string &name, const std::string &value);
106 
107  /** Save a configuration parameter of type "std::vector<int>"
108  */
109  void write(const std::string &section, const std::string &name, const std::vector<int> &value);
110 
111  /** Save a configuration parameter of type "std::vector<unsigned int>"
112  */
113  void write(const std::string &section, const std::string &name, const std::vector<unsigned int> &value);
114 
115  /** Save a configuration parameter of type "std::vector<float>"
116  */
117  void write(const std::string &section, const std::string &name, const std::vector<float> &value);
118 
119  /** Save a configuration parameter of type "std::vector<double>"
120  */
121  void write(const std::string &section, const std::string &name, const std::vector<double> &value);
122 
123  /** Save a configuration parameter of type "std::vector<bool>"
124  */
125  void write(const std::string &section, const std::string &name, const std::vector<bool> &value);
126 
127  /** Reads a configuration parameter of type "double"
128  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
129  */
130  double read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound = false) const;
131 
132  /** Reads a configuration parameter of type "float"
133  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
134  */
135  float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound = false) const;
136 
137  /** Reads a configuration parameter of type "bool", codified as "1"/"0" or "true"/"false" or "yes"/"no" for true/false, repectively.
138  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
139  */
140  bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound = false) const;
141 
142  /** Reads a configuration parameter of type "int"
143  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
144  */
145  int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound = false) const;
146 
147  /** Reads a configuration parameter of type "uint64_t": As in all other methods, the numeric value can be in decimal or hexadecimal with the prefix "0x"
148  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
149  */
150  uint64_t read_uint64_t(const std::string &section, const std::string &name, uint64_t defaultValue, bool failIfNotFound = false ) const;
151 
152  /** Reads a configuration parameter of type "string"
153  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
154  */
155  std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound = false) const;
156 
157  /** Reads a configuration parameter of type "string", and keeps only the first word (this can be used to eliminate possible comments at the end of the line)
158  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
159  */
160  std::string read_string_first_word(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound = false) const;
161 
162  /** Reads a configuration parameter of type vector, stored in the file as a string: "[v1 v2 v3 ... ]", where spaces could also be commas.
163  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
164  */
165  template <class VECTOR_TYPE>
166  void read_vector(
167  const std::string & section,
168  const std::string & name,
169  const VECTOR_TYPE & defaultValue,
170  VECTOR_TYPE & outValues,
171  bool failIfNotFound = false) const
172  {
173  std::string aux ( readString(section, name, "",failIfNotFound ) );
174  // Parse the text into a vector:
175  std::vector<std::string> tokens;
176  mrpt::system::tokenize( aux,"[], \t",tokens);
177 
178  if (tokens.size()==0)
179  {
180  outValues = defaultValue;
181  }
182  else
183  {
184  // Parse to numeric type:
185  const size_t N = tokens.size();
186  outValues.resize( N );
187  for (size_t i=0;i<N;i++)
188  {
189  std::stringstream ss(tokens[i]);
190  ss >> outValues[i];
191  }
192  }
193  }
194 
195 
196  /** Reads a configuration parameter as a matrix written in a matlab-like format - for example: "[2 3 4 ; 7 8 9]"
197  * This template method can be instantiated for matrices of the types: int, long, unsinged int, unsigned long, float, double, long double
198  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
199  */
200  template <class MATRIX_TYPE>
201  void read_matrix(
202  const std::string &section,
203  const std::string &name,
204  MATRIX_TYPE &outMatrix,
205  const MATRIX_TYPE &defaultMatrix = MATRIX_TYPE(),
206  bool failIfNotFound = false ) const
207  {
208  std::string aux = readString(section, name, "",failIfNotFound );
209  if (aux.empty())
210  outMatrix = defaultMatrix;
211  else
212  {
213  // Parse the text into a vector:
214  if (!outMatrix.fromMatlabStringFormat(aux))
215  THROW_EXCEPTION_CUSTOM_MSG1("Error parsing matrix: '%s'",aux.c_str())
216  }
217  }
218 
219  /** Reads an "enum" value, where the value in the config file can be either a numerical value or the symbolic name, for example:
220  * In the code:
221  * \code
222  * enum my_type_t { type_foo=0, type_bar };
223  * \endcode
224  * In the config file:
225  * \code
226  * [section]
227  * type = type_bar // Use the symbolic name, or
228  * type = 1 // use the numerical value (both lines will be equivalent)
229  * \endcode
230  * Which can be loaded with:
231  * \code
232  * cfgfile.read_enum<my_type_t>("section","type", type_foo );
233  * \endcode
234  *
235  * \note For an enum type to work with this template it is required that it defines a specialization of mrpt::utils::TEnumType
236  */
237  template <typename ENUMTYPE>
238  ENUMTYPE read_enum(const std::string &section, const std::string &name, const ENUMTYPE &defaultValue, bool failIfNotFound = false) const
239  {
240  MRPT_START
241  const std::string sVal = read_string_first_word(section,name,"",failIfNotFound);
242  if (sVal.empty()) return defaultValue;
243  // Text or numeric value?
244  if (::isdigit(sVal[0]))
245  { // Seems a number:
246  return static_cast<ENUMTYPE>(::atoi(&sVal[0]));
247  }
248  else
249  { // Name look-up:
250  try {
252  } catch (std::exception &)
253  {
254  THROW_EXCEPTION(format("Invalid value '%s' for enum type while reading key='%s'.",sVal.c_str(),name.c_str()))
255  }
256  }
257  MRPT_END
258  }
259 
260 
261  }; // End of class def.
262 
263  /** An useful macro for loading variables stored in a INI-like file under a key with the same name that the variable, and assigning the variable the current value if not found in the config file.
264  * The variableType must be the suffix of "read_XXX" functions, i.e. int, bool,...
265  */
266 #define MRPT_LOAD_CONFIG_VAR(variableName,variableType,configFileObject,sectionNameStr) \
267  { variableName = configFileObject.read_##variableType(sectionNameStr,#variableName,variableName); }
268 
269  /** Loads a float variable, stored as radians but entered in the INI-file as degrees:
270  */
271 #define MRPT_LOAD_CONFIG_VAR_DEGREES(variableName,configFileObject,sectionNameStr) \
272  { variableName = DEG2RAD( configFileObject.read_float(sectionNameStr,#variableName, RAD2DEG(variableName)) ); }
273 
274 #define MRPT_LOAD_CONFIG_VAR_CAST(variableName,variableType,variableTypeCast,configFileObject,sectionNameStr) \
275  { variableName = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,variableName)); }
276 
277 
278 #define MRPT_LOAD_HERE_CONFIG_VAR(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
279  targetVariable = configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,false);
280 
281 #define MRPT_LOAD_HERE_CONFIG_VAR_NO_DEFAULT(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
282  { try { \
283  targetVariable = configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,true); \
284  } catch (std::exception &) \
285  { \
286  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
287  } }\
288 
289 
290 #define MRPT_LOAD_CONFIG_VAR_NO_DEFAULT(variableName,variableType,configFileObject,sectionNameStr) \
291  { try { \
292  variableName = configFileObject.read_##variableType(sectionNameStr,#variableName,variableName,true); \
293  } catch (std::exception &) \
294  { \
295  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
296  } }\
297 
298 #define MRPT_LOAD_CONFIG_VAR_CAST_NO_DEFAULT(variableName,variableType,variableTypeCast,configFileObject,sectionNameStr) \
299  { try { \
300  variableName = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,variableName,true)); \
301  } catch (std::exception &) \
302  { \
303  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
304  } }\
305 
306 
307 #define MRPT_LOAD_HERE_CONFIG_VAR_CAST(variableName,variableType,variableTypeCast,targetVariable,configFileObject,sectionNameStr) \
308  targetVariable = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable));
309 
310 #define MRPT_LOAD_HERE_CONFIG_VAR_CAST_NO_DEFAULT(variableName,variableType,variableTypeCast,targetVariable,configFileObject,sectionNameStr) \
311  { try { \
312  targetVariable = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,true)); \
313  } catch (std::exception &) \
314  { \
315  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
316  } }\
317 
318 
319 #define MRPT_SAVE_CONFIG_VAR(variableName,configFileObject,sectionNameStr) \
320  { configFileObject.write(sectionNameStr,#variableName,variableName); }
321 
322 #define MRPT_SAVE_CONFIG_VAR_DEGREES(variableName,configFileObject,sectionNameStr) \
323  { configFileObject.write(sectionNameStr,#variableName, RAD2DEG(variableName)); }
324 
325 
326  } // End of namespace
327 } // end of namespace
328 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013