Main MRPT website > C++ reference for MRPT 1.5.7
CConfigFileBase.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef CConfigFileBase_H
10 #define CConfigFileBase_H
11 
12 #include <mrpt/utils/utils_defs.h>
14 #include <sstream>
15 #include <iomanip>
16 
17 namespace mrpt
18 {
19 namespace utils
20 {
21  // Frwd. decl:
22  template <typename ENUMTYPE> struct TEnumType;
23  class CConfigFilePrefixer;
24 
25  extern int BASE_IMPEXP MRPT_SAVE_NAME_PADDING, MRPT_SAVE_VALUE_PADDING; //!< Default padding sizes for macros MRPT_SAVE_CONFIG_VAR_COMMENT(), etc.
26 
27  /** 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...
28  * This is a virtual class, use only as a pointer to an implementation of one of the derived classes.
29  *
30  * See: \ref config_file_format
31  * \ingroup mrpt_base_grp
32  */
34  {
35  friend class CConfigFilePrefixer;
36  protected:
37  /** A virtual method to write a generic string.
38  */
39  virtual void writeString(const std::string &section,const std::string &name, const std::string &str) = 0;
40 
41  /** Write a generic string with optional padding and a comment field ("// ...") at the end of the line. */
42  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);
43 
44  /** A virtual method to read a generic string.
45  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned. */
46  virtual std::string readString(const std::string &section,const std::string &name,const std::string &defaultStr,bool failIfNotFound = false) const = 0;
47 
48  public:
49  virtual ~CConfigFileBase(); //!< dtor
50 
51  /** Returns a list with all the section names. */
52  virtual void getAllSections( vector_string &sections ) const = 0 ;
53 
54  /** Returs a list with all the keys into a section */
55  virtual void getAllKeys( const std::string &section, vector_string &keys ) const = 0;
56 
57  /** Checks if a given section exists (name is case insensitive) */
58  bool sectionExists( const std::string &section_name) const;
59 
60  /** @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).
61  * @{ */
62  template <typename data_t>
63  void write(const std::string &section, const std::string &name, const data_t &value, const int name_padding_width = -1, const int value_padding_width = -1, const std::string &comment = std::string())
64  {
65  std::stringstream ss; ss.flags(ss.flags() | std::ios::boolalpha);
66  ss << value;
67  writeString(section, name, ss.str(), name_padding_width, value_padding_width, comment);
68  }
69  template <typename data_t>
70  void write(const std::string &section, const std::string &name, const std::vector<data_t> &value, const int name_padding_width = -1, const int value_padding_width = -1, const std::string &comment = std::string())
71  {
72  std::stringstream ss; ss.flags(ss.flags() | std::ios::boolalpha);
73  for (typename std::vector<data_t>::const_iterator it=value.begin();it!=value.end();++it) ss << *it << " ";
74  writeString(section, name, ss.str(), name_padding_width, value_padding_width, comment);
75  }
76  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() );
77  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() );
78  /** @} */
79 
80  /** @name Read a configuration parameter, launching exception if key name is not found and `failIfNotFound`=true
81  * @{ */
82  double read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound = false) const;
83  float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound = false) const;
84  bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound = false) const;
85  int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound = false) const;
86  uint64_t read_uint64_t(const std::string &section, const std::string &name, uint64_t defaultValue, bool failIfNotFound = false ) const;
87  std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound = false) const;
88  /** 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) */
89  std::string read_string_first_word(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound = false) const;
90  /** Reads a configuration parameter of type vector, stored in the file as a string: "[v1 v2 v3 ... ]", where spaces could also be commas. \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned. */
91  template <class VECTOR_TYPE>
93  const std::string & section,
94  const std::string & name,
95  const VECTOR_TYPE & defaultValue,
96  VECTOR_TYPE & outValues,
97  bool failIfNotFound = false) const
98  {
99  std::string aux ( readString(section, name, "",failIfNotFound ) );
100  // Parse the text into a vector:
101  std::vector<std::string> tokens;
102  mrpt::system::tokenize( aux,"[], \t",tokens);
103 
104  if (tokens.size()==0)
105  {
106  outValues = defaultValue;
107  }
108  else
109  {
110  // Parse to numeric type:
111  const size_t N = tokens.size();
112  outValues.resize( N );
113  for (size_t i=0;i<N;i++)
114  {
115  std::stringstream ss(tokens[i]);
116  ss >> outValues[i];
117  }
118  }
119  }
120 
121  /** Reads a configuration parameter as a matrix written in a matlab-like format - for example: "[2 3 4 ; 7 8 9]".
122  * This template method can be instantiated for matrices of the types: int, long, unsinged int, unsigned long, float, double, long double
123  * \exception std::exception If the key name is not found and "failIfNotFound" is true. Otherwise the "defaultValue" is returned.
124  */
125  template <class MATRIX_TYPE>
127  const std::string &section,
128  const std::string &name,
129  MATRIX_TYPE &outMatrix,
130  const MATRIX_TYPE &defaultMatrix = MATRIX_TYPE(),
131  bool failIfNotFound = false ) const
132  {
133  std::string aux = readString(section, name, "",failIfNotFound );
134  if (aux.empty())
135  outMatrix = defaultMatrix;
136  else
137  {
138  // Parse the text into a vector:
139  if (!outMatrix.fromMatlabStringFormat(aux))
140  THROW_EXCEPTION_FMT("Error parsing matrix: '%s'",aux.c_str())
141  }
142  }
143 
144  /** Reads an "enum" value, where the value in the config file can be either a numerical value or the symbolic name, for example:
145  * In the code:
146  * \code
147  * enum my_type_t { type_foo=0, type_bar };
148  * \endcode
149  * In the config file:
150  * \code
151  * [section]
152  * type = type_bar // Use the symbolic name, or
153  * type = 1 // use the numerical value (both lines will be equivalent)
154  * \endcode
155  * Which can be loaded with:
156  * \code
157  * cfgfile.read_enum<my_type_t>("section","type", type_foo );
158  * \endcode
159  *
160  * \note For an enum type to work with this template it is required that it defines a specialization of mrpt::utils::TEnumType
161  */
162  template <typename ENUMTYPE>
163  ENUMTYPE read_enum(const std::string &section, const std::string &name, const ENUMTYPE &defaultValue, bool failIfNotFound = false) const
164  {
165  MRPT_START
166  const std::string sVal = read_string_first_word(section,name,"",failIfNotFound);
167  if (sVal.empty()) return defaultValue;
168  // Text or numeric value?
169  if (::isdigit(sVal[0]))
170  { // Seems a number:
171  return static_cast<ENUMTYPE>(::atoi(&sVal[0]));
172  }
173  else
174  { // Name look-up:
175  try {
177  } catch (std::exception &)
178  {
179  THROW_EXCEPTION_FMT("Invalid value '%s' for enum type while reading key='%s'.",sVal.c_str(),name.c_str())
180  }
181  }
182  MRPT_END
183  }
184  /** @} */
185  }; // End of class def.
186 
187  /** 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.
188  * The variableType must be the suffix of "read_XXX" functions, i.e. int, bool,...
189  */
190 #define MRPT_LOAD_CONFIG_VAR(variableName,variableType,configFileObject,sectionNameStr) \
191  { variableName = configFileObject.read_##variableType(sectionNameStr,#variableName,variableName); }
192 
193  /** Shortcut for MRPT_LOAD_CONFIG_VAR() for config file object named `c` and section string named `s` */
194 #define MRPT_LOAD_CONFIG_VAR_CS(variableName,variableType) MRPT_LOAD_CONFIG_VAR(variableName,variableType,c,s)
195 
196  /** Loads a double variable, stored as radians but entered in the INI-file as degrees */
197 #define MRPT_LOAD_CONFIG_VAR_DEGREES(variableName,configFileObject,sectionNameStr) \
198  { variableName = mrpt::utils::DEG2RAD( configFileObject.read_double(sectionNameStr,#variableName, mrpt::utils::RAD2DEG(variableName)) ); }
199 
200  /** Loads a double, required, variable, stored as radians but entered in the INI-file as degrees */
201 #define MRPT_LOAD_CONFIG_VAR_DEGREES_NO_DEFAULT(variableName,configFileObject,sectionNameStr) \
202  { variableName = mrpt::utils::DEG2RAD( configFileObject.read_double(sectionNameStr,#variableName, mrpt::utils::RAD2DEG(variableName),true) ); }
203 
204 #define MRPT_LOAD_CONFIG_VAR_CAST(variableName,variableType,variableTypeCast,configFileObject,sectionNameStr) \
205  { variableName = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,variableName)); }
206 
207 
208 #define MRPT_LOAD_HERE_CONFIG_VAR(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
209  targetVariable = configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,false);
210 
211 #define MRPT_LOAD_HERE_CONFIG_VAR_NO_DEFAULT(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
212  { try { \
213  targetVariable = configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,true); \
214  } catch (std::exception &) { \
215  THROW_EXCEPTION( mrpt::format( "Value for '%s' not found in config file in section '%s'", static_cast<const char*>(#variableName ), std::string(sectionNameStr).c_str() )); \
216  } }
217 
218 #define MRPT_LOAD_HERE_CONFIG_VAR_DEGREES(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
219  targetVariable = mrpt::utils::DEG2RAD( configFileObject.read_##variableType(sectionNameStr,#variableName,mrpt::utils::RAD2DEG(targetVariable),false));
220 
221 #define MRPT_LOAD_HERE_CONFIG_VAR_DEGREES_NO_DEFAULT(variableName,variableType,targetVariable,configFileObject,sectionNameStr) \
222  { try { \
223  targetVariable = mrpt::utils::DEG2RAD( configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,true)); \
224  } catch (std::exception &) { \
225  THROW_EXCEPTION( mrpt::format( "Value for '%s' not found in config file in section '%s'", static_cast<const char*>(#variableName ), std::string(sectionNameStr).c_str() )); \
226  } }
227 
228 
229 #define MRPT_LOAD_CONFIG_VAR_NO_DEFAULT(variableName,variableType,configFileObject,sectionNameStr) \
230  { try { \
231  variableName = configFileObject.read_##variableType(sectionNameStr,#variableName,variableName,true); \
232  } catch (std::exception &) \
233  { \
234  THROW_EXCEPTION( mrpt::format( "Value for '%s' not found in config file in section '%s'", static_cast<const char*>(#variableName ), std::string(sectionNameStr).c_str() )); \
235  } }\
236 
237  /** Shortcut for MRPT_LOAD_CONFIG_VAR_NO_DEFAULT() for REQUIRED variables config file object named `c` and section string named `s` */
238 #define MRPT_LOAD_CONFIG_VAR_REQUIRED_CS(variableName,variableType) MRPT_LOAD_CONFIG_VAR_NO_DEFAULT(variableName,variableType,c,s)
239 
240 #define MRPT_LOAD_CONFIG_VAR_CAST_NO_DEFAULT(variableName,variableType,variableTypeCast,configFileObject,sectionNameStr) \
241  { try { \
242  variableName = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,variableName,true)); \
243  } catch (std::exception &) \
244  { \
245  THROW_EXCEPTION( mrpt::format( "Value for '%s' not found in config file in section '%s'", static_cast<const char*>(#variableName ), std::string(sectionNameStr).c_str() )); \
246  } }\
247 
248 
249 #define MRPT_LOAD_HERE_CONFIG_VAR_CAST(variableName,variableType,variableTypeCast,targetVariable,configFileObject,sectionNameStr) \
250  targetVariable = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable));
251 
252 #define MRPT_LOAD_HERE_CONFIG_VAR_CAST_NO_DEFAULT(variableName,variableType,variableTypeCast,targetVariable,configFileObject,sectionNameStr) \
253  { try { \
254  targetVariable = static_cast<variableTypeCast>(configFileObject.read_##variableType(sectionNameStr,#variableName,targetVariable,true)); \
255  } catch (std::exception &) \
256  { \
257  THROW_EXCEPTION( mrpt::format( "Value for '%s' not found in config file in section '%s'", static_cast<const char*>(#variableName ), std::string(sectionNameStr).c_str() )); \
258  } }\
259 
260 
261 #define MRPT_SAVE_CONFIG_VAR(variableName,configFileObject,sectionNameStr) \
262  { configFileObject.write(sectionNameStr,#variableName,variableName); }
263 
264 #define MRPT_SAVE_CONFIG_VAR_DEGREES(variableName,configFileObject,sectionNameStr) \
265  { configFileObject.write(sectionNameStr,#variableName, mrpt::utils::RAD2DEG(variableName)); }
266 
267 #define MRPT_SAVE_CONFIG_VAR_COMMENT(variableName,__comment) \
268  { c.write(s,#variableName,variableName,mrpt::utils::MRPT_SAVE_NAME_PADDING, mrpt::utils::MRPT_SAVE_VALUE_PADDING,__comment); }
269 #define MRPT_SAVE_CONFIG_VAR_DEGREES_COMMENT(__entryName,__variable,__comment) \
270  { c.write(s,__entryName,mrpt::utils::RAD2DEG(__variable),mrpt::utils::MRPT_SAVE_NAME_PADDING, mrpt::utils::MRPT_SAVE_VALUE_PADDING,__comment); }
271 
272  } // End of namespace
273 } // end of namespace
274 #endif
int BASE_IMPEXP MRPT_SAVE_VALUE_PADDING
Default padding sizes for macros MRPT_SAVE_CONFIG_VAR_COMMENT(), etc.
static ENUMTYPE name2value(const std::string &name)
Gives the numerical name for a given enum text name.
Definition: TEnumType.h:35
A wrapper for other CConfigFileBase-based objects that prefixes a given token to every key and/or sec...
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
const Scalar * const_iterator
Definition: eigen_plugins.h:24
This class allows loading and storing values and vectors of different types from a configuration text...
std::vector< std::string > vector_string
A type for passing a vector of strings.
Definition: types_simple.h:30
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
A helper class that can convert an enum value into its textual representation, and viceversa...
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 ...
GLsizei const GLchar ** string
Definition: glext.h:3919
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
unsigned __int64 uint64_t
Definition: rptypes.h:52
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void write(const std::string &section, const std::string &name, const data_t &value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment=std::string())
GLuint const GLchar * name
Definition: glext.h:3891
GLsizei const GLfloat * value
Definition: glext.h:3929
void BASE_IMPEXP tokenize(const std::string &inString, const std::string &inDelimiters, std::deque< std::string > &outTokens, bool skipBlankTokens=true) MRPT_NO_THROWS
Tokenizes a string according to a set of delimiting characters.
void write(const std::string &section, const std::string &name, const std::vector< data_t > &value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment=std::string())
int BASE_IMPEXP MRPT_SAVE_NAME_PADDING



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019