Main MRPT website > C++ reference
MRPT logo
CConfigFileBase.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file |
7  | Copyright (c) 2005-2013, MAPIR group, University of Malaga |
8  | Copyright (c) 2012-2013, University of Almeria |
9  | All rights reserved. |
10  | |
11  | Redistribution and use in source and binary forms, with or without |
12  | modification, are permitted provided that the following conditions are |
13  | met: |
14  | * Redistributions of source code must retain the above copyright |
15  | notice, this list of conditions and the following disclaimer. |
16  | * Redistributions in binary form must reproduce the above copyright |
17  | notice, this list of conditions and the following disclaimer in the |
18  | documentation and/or other materials provided with the distribution. |
19  | * Neither the name of the copyright holders nor the |
20  | names of its contributors may be used to endorse or promote products |
21  | derived from this software without specific prior written permission.|
22  | |
23  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
24  | 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
25  | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR|
26  | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
27  | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL|
28  | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR|
29  | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
30  | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
31  | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
32  | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
33  | POSSIBILITY OF SUCH DAMAGE. |
34  +---------------------------------------------------------------------------+ */
35 #ifndef CConfigFileBase_H
36 #define CConfigFileBase_H
37 
38 #include <mrpt/utils/utils_defs.h>
39 #include <mrpt/utils/TEnumType.h>
42 
43 /*---------------------------------------------------------------
44  Class
45  ---------------------------------------------------------------*/
46 namespace mrpt
47 {
48 namespace utils
49 {
50  /** 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...
51  * This is a virtual class, use only as a pointer to an implementation of one of the derived classes.
52  * \ingroup mrpt_base_grp
53  */
55  {
56  protected:
57  /** A virtual method to write a generic string.
58  */
59  virtual void writeString(const std::string &section,const std::string &name, const std::string &str) = 0;
60 
61  /** Write a generic string with optional padding and a comment field ("// ...") at the end of the line. */
62  void writeString(const std::string &section,const std::string &name, const std::string &str, const int name_padding_width, const int value_padding_width, const std::string &comment);
63 
64  /** A virtual method to read a generic string.
65  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
66  */
67  virtual std::string readString(
68  const std::string &section,
69  const std::string &name,
70  const std::string &defaultStr,
71  bool failIfNotFound = false) const = 0;
72 
73  public:
74  /** Virtual destructor...
75  */
76  virtual ~CConfigFileBase()
77  {
78  }
79 
80  /** Returns a list with all the section names.
81  */
82  virtual void getAllSections( vector_string &sections ) const = 0 ;
83 
84  /** Returs a list with all the keys into a section.
85  */
86  virtual void getAllKeys( const std::string section, vector_string &keys ) const = 0;
87 
88  /** Checks if a given section exists (name is case insensitive) */
89  bool sectionExists( const std::string &section_name) const;
90 
91  /** @name Save a configuration parameter. Optionally pads with spaces up to the desired width in number of characters (-1: no fill), and add a final comment field at the end of the line (a "// " prefix is automatically inserted).
92  * @{ */
93  void write(const std::string &section, const std::string &name, double value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
94  void write(const std::string &section, const std::string &name, float value , const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
95  void write(const std::string &section, const std::string &name, int value , const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
96  void write(const std::string &section, const std::string &name, uint32_t value , const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
97  void write(const std::string &section, const std::string &name, uint64_t value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
98  void write(const std::string &section, const std::string &name, const std::string &value , const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
99  void write(const std::string &section, const std::string &name, const std::vector<int> &value , const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
100  void write(const std::string &section, const std::string &name, const std::vector<unsigned int> &value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
101  void write(const std::string &section, const std::string &name, const std::vector<float> &value , const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
102  void write(const std::string &section, const std::string &name, const std::vector<double> &value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
103  void write(const std::string &section, const std::string &name, const std::vector<bool> &value , const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment = std::string() );
104  /** @} */
105 
106  /** Reads a configuration parameter of type "double"
107  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
108  */
109  double read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound = false) const;
110 
111  /** Reads a configuration parameter of type "float"
112  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
113  */
114  float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound = false) const;
115 
116  /** Reads a configuration parameter of type "bool", codified as "1"/"0" or "true"/"false" or "yes"/"no" for true/false, repectively.
117  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
118  */
119  bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound = false) const;
120 
121  /** Reads a configuration parameter of type "int"
122  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
123  */
124  int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound = false) const;
125 
126  /** 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"
127  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
128  */
129  uint64_t read_uint64_t(const std::string &section, const std::string &name, uint64_t defaultValue, bool failIfNotFound = false ) const;
130 
131  /** Reads a configuration parameter of type "string"
132  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
133  */
134  std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound = false) const;
135 
136  /** 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)
137  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
138  */
139  std::string read_string_first_word(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound = false) const;
140 
141  /** Reads a configuration parameter of type vector, stored in the file as a string: "[v1 v2 v3 ... ]", where spaces could also be commas.
142  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
143  */
144  template <class VECTOR_TYPE>
146  const std::string & section,
147  const std::string & name,
148  const VECTOR_TYPE & defaultValue,
149  VECTOR_TYPE & outValues,
150  bool failIfNotFound = false) const
151  {
152  std::string aux ( readString(section, name, "",failIfNotFound ) );
153  // Parse the text into a vector:
154  std::vector<std::string> tokens;
155  mrpt::system::tokenize( aux,"[], \t",tokens);
156 
157  if (tokens.size()==0)
158  {
159  outValues = defaultValue;
160  }
161  else
162  {
163  // Parse to numeric type:
164  const size_t N = tokens.size();
165  outValues.resize( N );
166  for (size_t i=0;i<N;i++)
167  {
168  std::stringstream ss(tokens[i]);
169  ss >> outValues[i];
170  }
171  }
172  }
173 
174 
175  /** Reads a configuration parameter as a matrix written in a matlab-like format - for example: "[2 3 4 ; 7 8 9]"
176  * This template method can be instantiated for matrices of the types: int, long, unsinged int, unsigned long, float, double, long double
177  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
178  */
179  template <class MATRIX_TYPE>
181  const std::string &section,
182  const std::string &name,
183  MATRIX_TYPE &outMatrix,
184  const MATRIX_TYPE &defaultMatrix = MATRIX_TYPE(),
185  bool failIfNotFound = false ) const
186  {
187  std::string aux = readString(section, name, "",failIfNotFound );
188  if (aux.empty())
189  outMatrix = defaultMatrix;
190  else
191  {
192  // Parse the text into a vector:
193  if (!outMatrix.fromMatlabStringFormat(aux))
194  THROW_EXCEPTION_CUSTOM_MSG1("Error parsing matrix: '%s'",aux.c_str())
195  }
196  }
197 
198  /** Reads an "enum" value, where the value in the config file can be either a numerical value or the symbolic name, for example:
199  * In the code:
200  * \code
201  * enum my_type_t { type_foo=0, type_bar };
202  * \endcode
203  * In the config file:
204  * \code
205  * [section]
206  * type = type_bar // Use the symbolic name, or
207  * type = 1 // use the numerical value (both lines will be equivalent)
208  * \endcode
209  * Which can be loaded with:
210  * \code
211  * cfgfile.read_enum<my_type_t>("section","type", type_foo );
212  * \endcode
213  *
214  * \note For an enum type to work with this template it is required that it defines a specialization of mrpt::utils::TEnumType
215  */
216  template <typename ENUMTYPE>
217  ENUMTYPE read_enum(const std::string &section, const std::string &name, const ENUMTYPE &defaultValue, bool failIfNotFound = false) const
218  {
219  MRPT_START
220  const std::string sVal = read_string_first_word(section,name,"",failIfNotFound);
221  if (sVal.empty()) return defaultValue;
222  // Text or numeric value?
223  if (::isdigit(sVal[0]))
224  { // Seems a number:
225  return static_cast<ENUMTYPE>(::atoi(&sVal[0]));
226  }
227  else
228  { // Name look-up:
229  try {
231  } catch (std::exception &)
232  {
233  THROW_EXCEPTION(format("Invalid value '%s' for enum type while reading key='%s'.",sVal.c_str(),name.c_str()))
234  }
235  }
236  MRPT_END
237  }
238 
239 
240  }; // End of class def.
241 
242  /** 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.
243  * The variableType must be the suffix of "read_XXX" functions, i.e. int, bool,...
244  */
245 #define MRPT_LOAD_CONFIG_VAR(variableName,variableType,configFileObject,sectionNameStr) \
246  { variableName = configFileObject.read_##variableType(sectionNameStr,#variableName,variableName); }
247 
248  /** Loads a float variable, stored as radians but entered in the INI-file as degrees:
249  */
250 #define MRPT_LOAD_CONFIG_VAR_DEGREES(variableName,configFileObject,sectionNameStr) \
251  { variableName = DEG2RAD( configFileObject.read_float(sectionNameStr,#variableName, RAD2DEG(variableName)) ); }
252 
253 #define MRPT_LOAD_CONFIG_VAR_CAST(variableName,variableType,variableTypeCast,configFileObject,sectionNameStr) \
254  { variableName = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,variableName)); }
255 
256 
257 #define MRPT_LOAD_HERE_CONFIG_VAR(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
258  targetVariable = configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,false);
259 
260 #define MRPT_LOAD_HERE_CONFIG_VAR_NO_DEFAULT(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
261  { try { \
262  targetVariable = configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,true); \
263  } catch (std::exception &) \
264  { \
265  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
266  } }\
267 
268 
269 #define MRPT_LOAD_CONFIG_VAR_NO_DEFAULT(variableName,variableType,configFileObject,sectionNameStr) \
270  { try { \
271  variableName = configFileObject.read_##variableType(sectionNameStr,#variableName,variableName,true); \
272  } catch (std::exception &) \
273  { \
274  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
275  } }\
276 
277 #define MRPT_LOAD_CONFIG_VAR_CAST_NO_DEFAULT(variableName,variableType,variableTypeCast,configFileObject,sectionNameStr) \
278  { try { \
279  variableName = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,variableName,true)); \
280  } catch (std::exception &) \
281  { \
282  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
283  } }\
284 
285 
286 #define MRPT_LOAD_HERE_CONFIG_VAR_CAST(variableName,variableType,variableTypeCast,targetVariable,configFileObject,sectionNameStr) \
287  targetVariable = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable));
288 
289 #define MRPT_LOAD_HERE_CONFIG_VAR_CAST_NO_DEFAULT(variableName,variableType,variableTypeCast,targetVariable,configFileObject,sectionNameStr) \
290  { try { \
291  targetVariable = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,true)); \
292  } catch (std::exception &) \
293  { \
294  THROW_EXCEPTION( format( "Value for '%s' not found in config file", static_cast<const char*>(#variableName ) )); \
295  } }\
296 
297 
298 #define MRPT_SAVE_CONFIG_VAR(variableName,configFileObject,sectionNameStr) \
299  { configFileObject.write(sectionNameStr,#variableName,variableName); }
300 
301 #define MRPT_SAVE_CONFIG_VAR_DEGREES(variableName,configFileObject,sectionNameStr) \
302  { configFileObject.write(sectionNameStr,#variableName, RAD2DEG(variableName)); }
303 
304 
305  } // End of namespace
306 } // end of namespace
307 #endif
static ENUMTYPE name2value(const std::string &name)
Gives the numerical name for a given enum text name.
Definition: TEnumType.h:61
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
#define THROW_EXCEPTION(msg)
std::vector< std::string > vector_string
A type for passing a vector of strings.
This class allows loading and storing values and vectors of different types from a configuration text...
virtual ~CConfigFileBase()
Virtual destructor...
void read_matrix(const std::string &section, const std::string &name, MATRIX_TYPE &outMatrix, const MATRIX_TYPE &defaultMatrix=MATRIX_TYPE(), bool failIfNotFound=false) const
Reads a configuration parameter as a matrix written in a matlab-like format - for example: "[2 3 4 ; ...
#define MRPT_END
void read_vector(const std::string &section, const std::string &name, const VECTOR_TYPE &defaultValue, VECTOR_TYPE &outValues, bool failIfNotFound=false) const
Reads a configuration parameter of type vector, stored in the file as a string: "[v1 v2 v3 ...
ENUMTYPE read_enum(const std::string &section, const std::string &name, const ENUMTYPE &defaultValue, bool failIfNotFound=false) const
Reads an "enum" value, where the value in the config file can be either a numerical value or the symb...
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void BASE_IMPEXP tokenize(const std::string &inString, const std::string &inDelimiters, std::deque< std::string > &outTokens) MRPT_NO_THROWS
Tokenizes a string according to a set of delimiting characters.
#define THROW_EXCEPTION_CUSTOM_MSG1(msg, param1)



Page generated by Doxygen 1.8.14 for MRPT 1.0.2 SVN: at lun oct 28 00:52:41 CET 2019 Hosted on:
SourceForge.net Logo