lbm_reference
ConfBlock.h
Go to the documentation of this file.
1 //! \file ConfBlock.h
2 //! Declaration of the ConfBlock class
3 
4 //! \date Jan 17, 2009
5 //! \author Florian Rathgeber
6 
7 #ifndef CONFBLOCK_H_
8 #define CONFBLOCK_H_
9 
10 #include <cstring>
11 #include <string>
12 #include <map>
13 #include <stdexcept>
14 #include <boost/lexical_cast.hpp>
15 
16 //! Common namespace for all classes related to parsing of configuration files
17 
18 namespace confparser {
19 
20 //! Exception class for non-existing parameters
21 
22 //! Is capable of providing information about the parameter tried to retrieve
23 //! and the block tried to retrieve from
24 
25 class ParameterNotFound : public std::invalid_argument {
26 
27 public:
28 
29  // ============================ //
30  // Constructors and destructors //
31  // ============================ //
32 
33  //! Default constructor
34 
35  //! Sets no specific information
36 
38  : std::invalid_argument( "Tried to retrieve non-existing parameter" ),
39  paramName_( "" ) {}
40 
41  //! Constructor
42 
43  //! Sets information about parameter name tried to retrieve as well as block
44  //! name tried to retrieve from
45 
46  ParameterNotFound( const std::string paramName ) throw()
47  : std::invalid_argument( "Tried to retrieve non-existing parameter "
48  + paramName ),
49  paramName_( paramName ) {}
50 
51  //! Destructor
52 
53  virtual ~ParameterNotFound() throw() {}
54 
55  // ======= //
56  // Getters //
57  // ======= //
58 
59  //! Returns the parameter name
60 
61  //! \return Name of the parameter that was tried to retrieve
62 
63  const char* getParamName() const throw() { return paramName_.c_str(); }
64 
65 private:
66 
67  // ============ //
68  // Data members //
69  // ============ //
70 
71  //! Parameter name tried to retrieve
72 
73  const std::string paramName_;
74 
75 };
76 
77 //! Data structure corresponding to one block in the hierarchical configuration
78 //! file
79 
80 class ConfBlock {
81 
82  //! Declare ConfParser as friend class to give it access to internals
83 
84  friend class ConfParser;
85 
86 public:
87 
88  //! Iterator type for the children of the block
89 
90  typedef std::multimap< std::string, ConfBlock >::iterator childIter;
91  typedef std::map< std::string, std::string >::iterator propIter;
92  typedef std::pair< childIter, childIter > childIterPair;
93 
94  // ============================ //
95  // Constructors and destructors //
96  // ============================ //
97 
98  //! Default constructor to create a new (empty) block
99 
100  //! Parameters and children will be empty
101 
103 
104  //! Destructor
105 
106  //! Does nothing
107 
108  virtual ~ConfBlock() {}
109 
110  // ======= //
111  // Getters //
112  // ======= //
113 
114  //! Check whether the block is empty
115 
116  //! \return \em true if block is empty, i.e. children and parameters are
117  //! empty, \em false otherwise
118 
119  bool empty() {
120  return props_.empty() && children_.empty();
121  }
122 
123  //! Find a block with given name among the children
124 
125  //! \param[in] blockName Name of the block to retrieve
126  //! \return Pointer to searched for block, \em NULL if none was found
127 
128  ConfBlock* find( std::string blockName ) {
129  childIter it = children_.find( blockName );
130  if ( it == children_.end() ) return NULL;
131  return &(it->second);
132  }
133 
134  //! Find all blocks with given name among the children
135 
136  //! \param[in] blockName Name of the blocks to retrieve
137  //! \return Pair of iterators into the children pointing to the first and
138  //! after the last block found, are the same if none was found. Blocks
139  //! can be retrieved by ->second property of the iterator.
140 
141  std::pair< childIter, childIter > findAll( std::string blockName ) {
142  return children_.equal_range( blockName );
143  }
144 
145  //! Retrieve parameter as certain type
146 
147  //! \param[in] key Parameter name to retrieve
148  //! \tparam T Type to retrieve parameter in
149  //! \return Parameter specified by \em key as type \em T
150 
151  template < typename T >
152  T getParam( std::string key ) throw ( std::invalid_argument ) {
153  std::map< std::string, std::string >::iterator it = props_.find( key );
154  if ( it == props_.end() )
155  throw ParameterNotFound( key );
156  try {
157  return boost::lexical_cast<T>( it->second );
158  } catch( boost::bad_lexical_cast& e ) {
159  throw std::invalid_argument( "Bad value given for key '" + key + "': could not convert" );
160  }
161  }
162 
163  //! Retrieve parameter as certain type
164 
165  //! \param[in] key Parameter name to retrieve
166  //! \param[out] value Variable to store value in
167  //! \tparam T Type to retrieve parameter in
168  //! \return \e true if parameter was found, \e false if not
169  //! \note Will not throw an exception, instead return value must be checked
170 
171  template < typename T >
172  bool getParam( std::string key, T& value ) throw ( std::invalid_argument ) {
173  propIter it = props_.find( key );
174  if ( it == props_.end() ) return false;
175  try {
176  value = boost::lexical_cast<T>( it->second );
177  } catch( boost::bad_lexical_cast& e ) {
178  throw std::invalid_argument( "Bad value given for key '" + key + "': could not convert" );
179  }
180  return true;
181  }
182 
183  // ======= //
184  // Setters //
185  // ======= //
186 
187  //! Add a child with given name to children of current block
188 
189  //! \param[in] blockName Block name of child to add
190  //! \return Reference to newly added child
191 
192  ConfBlock& addChild( std::string blockName ) {
193  childIter bit = children_.insert( std::make_pair( blockName, ConfBlock() ) );
194  return bit->second;
195  }
196 
197  //! Remove all children with given name
198 
199  //! \param[in] blockName Block name of children to remove
200  //! \return Number of blocks removed, 0 if none of the given name were found
201 
202  int removeChildren( std::string blockName ) {
203  return children_.erase( blockName );
204  }
205 
206  //! Add a key value pair
207 
208  //! \param[in] key Parameter name to add
209  //! \param[in] value Parameter value to add
210  //! \return \e true if a new key value pair was actually created, \e false if
211  //! the key already existed
212 
213  bool addParam( std::string key, std::string value ) {
214  std::pair<propIter,bool> p = props_.insert( std::make_pair( key, value ) );
215  return p.second;
216  }
217 
218  //! Set parameter
219 
220  //! \param[in] key Parameter name to set
221  //! \param[in] value Parameter value to set
222  //! \tparam T Type of the parameter to set (will be converted to string)
223  //! \return \e true if the parameter was actually set, \e false if it does
224  //! not exist
225 
226  template < typename T >
227  bool setParam( std::string key, T value ) {
228  propIter it = props_.find( key );
229  if ( it == props_.end() ) return false;
230  it->second = boost::lexical_cast<std::string>( value );
231  return true;
232  }
233 
234  //! Remove parameter with a given key
235 
236  //! \param[in] key Parameter key to remove
237  //! \return \e true if the key / value pair was removed, \e false if it was
238  //! not found
239 
240  bool removeParam( std::string key ) {
241  return props_.erase( key );
242  }
243 
244  //! Write out a configuration file of this block's subtree
245 
246  //! \param[in] fileName Name of the configuration file to write out
247 
248  void writeConfigFile( std::string fileName );
249 
250 protected:
251 
252  // ========================== //
253  // Protected helper functions //
254  // ========================== //
255 
256  //! Recursive helper function to write the configuration of a subtree to a
257  //! file
258 
259  //! \param[in] fileHandle Stream to write to
260  //! \param[in] indent Level of indentation for the current block
261 
262  void writeConfigFileRec( std::ofstream &fileHandle, std::string indent );
263 
264  // ============ //
265  // Data members //
266  // ============ //
267 
268  //! Map containing parameter key / value pairs defined in this block
269 
270  std::map< std::string, std::string > props_;
271 
272  //! Multimap containing the children
273 
274  std::multimap< std::string, ConfBlock > children_;
275 
276 };
277 
278 } // namespace confparser
279 
280 #endif /* CONFBLOCK_H_ */