Image Component Library (ICL)
ConfigFile.h
Go to the documentation of this file.
1 /********************************************************************
2 ** Image Component Library (ICL) **
3 ** **
4 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld **
5 ** Neuroinformatics Group **
6 ** Website: www.iclcv.org and **
7 ** http://opensource.cit-ec.de/projects/icl **
8 ** **
9 ** File : ICLUtils/src/ICLUtils/ConfigFile.h **
10 ** Module : ICLUtils **
11 ** Authors: Christof Elbrechter **
12 ** **
13 ** **
14 ** GNU LESSER GENERAL PUBLIC LICENSE **
15 ** This file may be used under the terms of the GNU Lesser General **
16 ** Public License version 3.0 as published by the **
17 ** **
18 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
19 ** included in the packaging of this file. Please review the **
20 ** following information to ensure the license requirements will **
21 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt **
22 ** **
23 ** The development of this software was supported by the **
24 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. **
25 ** The Excellence Cluster EXC 277 is a grant of the Deutsche **
26 ** Forschungsgemeinschaft (DFG) in the context of the German **
27 ** Excellence Initiative. **
28 ** **
29 ********************************************************************/
30 
31 #pragma once
32 
33 #include <ICLUtils/CompatMacros.h>
34 #include <ICLUtils/StringUtils.h>
35 #include <ICLUtils/Exception.h>
36 #include <ICLUtils/Lockable.h>
37 #include <ICLUtils/SmartPtr.h>
38 #include <map>
39 #include <typeinfo>
40 
42 namespace pugi{
43  class xml_document;
44 }
48 namespace icl{
49  namespace utils{
51  struct ICLUtils_API XMLDocumentDelOp{ static void delete_func(pugi::xml_document *h); };
54 
172 
173  public:
174  friend class ConfigFileGUI;
175 
178  EntryNotFoundException(const std::string &entryName):
179  ICLException("Entry " + entryName+" could not be found!"){}
180  virtual ~EntryNotFoundException() throw(){}
181  };
182 
185  InvalidTypeException(const std::string &entryName, const std::string &typeName):
186  ICLException("Invalid type " + typeName + " (entry " + entryName + ")"){};
187  virtual ~InvalidTypeException() throw() {}
188  };
189 
192  UnregisteredTypeException(const std::string &rttiID):
193  ICLException("type with RTTI ID " + rttiID + " is not registered"){}
195  };
196 
197  private:
198 
200  struct Maps{
202  std::map<std::string,std::string> typeMap;
203 
205  std::map<std::string,std::string> typeMapReverse;
206  };
207 
209  static Maps *getMapsInstance();
210 
212  static Maps &getMapsInstanceRef() { return *getMapsInstance(); }
213 #if 0
214  static std::map<std::string,std::string> s_typeMap;
215  static std::map<std::string,std::string> s_typeMapReverse;
216 #endif
217 
219  template<class T>
220  static const std::string &get_type_name() {
221  static const std::string &rttiID = get_rtti_type_id<T>();
222  if(!type_registered_by_rtti(rttiID)) throw UnregisteredTypeException(rttiID);
223  static const std::string &name = getMapsInstanceRef().typeMap[rttiID];
224  return name;
225  }
226 
228  template<class T>
229  static inline const std::string &get_rtti_type_id(){
230  static std::string NAME = typeid(T).name();
231  return NAME;
232  }
233 
235  template<class T>
236  inline bool check_type(const std::string &id) const {
237  return check_type_internal(id,get_rtti_type_id<T>());
238  }
239 
241  bool check_type_internal(const std::string &id, const std::string &rttiTypeID) const
242  ;
243 
245  static bool type_registered_by_rtti(const std::string &rttiID){
246  Maps &maps = getMapsInstanceRef();
247  return (maps.typeMap.find(rttiID) != maps.typeMap.end());
248  }
249 
250  public:
251 
254 #define REGISTER_CONFIG_FILE_TYPE(T) ::icl::utils::ConfigFile::register_type<T>(#T)
255 
258 
284  template<class T>
285  static void register_type(const std::string &id){
286  Maps &maps = getMapsInstanceRef();
287  std::string rtti = get_rtti_type_id<T>();
288  maps.typeMap[rtti] = id;
289  maps.typeMapReverse[id] = rtti;
290 #if 0
291  s_typeMap[get_rtti_type_id<T>()] = id;
292  s_typeMapReverse[id] = get_rtti_type_id<T>();
293 #endif
294  }
295 
297 
305  ConfigFile();
306 
308 
311  ConfigFile(const std::string &filename);
312 
314 
315  ConfigFile(pugi::xml_document *handle);
316 
318 
320  ConfigFile(std::istream &stream);
321 
323 
324  void load(const std::string &filename);
325 
327  void save(const std::string &filename) const;
328 
330  void setPrefix(const std::string &defaultPrefix) const;
331 
333  const std::string &getPrefix() const;
334 
336 
337  class Data{
338  std::string id;
340 
342  Data(const std::string &id, ConfigFile &cf);
343  public:
344 
346  friend class ConfigFile;
347 
349 
351  template<class T>
352  operator T() const {
353  return cf->get<T>(id);
354  }
355 
357 
358  template<class T>
359  T as() const {
360  return cf->get<T>(id);
361  }
362 
364 
365  Data &operator=(const Data &d){
366  cf = d.cf;
367  id = d.id;
368  return *this;
369  }
370 
372 
377  template<class T>
378  Data &operator=(const T &t) {
379  cf->set(id,t);
380  return *this;
381  }
382  };
383 
384 
386  /* This function can be used for reading as well as for writing ConfigFile entries
387  the returned utitlity structure of type Data defers creation of a new
388  ConfigFile entry until actually a value is assigned to it.
389  **/
390  Data operator [](const std::string &id);
391 
393 
394  const Data operator[](const std::string &id) const ;
395 
397 
398  std::vector<Data> find(const std::string &regex);
399 
401 
403  const std::vector<Data> find(const std::string &regex) const{
404  return const_cast<ConfigFile*>(this)->find(regex);
405  }
406 
408 
434  template<class T>
435  void set(const std::string &id, const T &val) {
436  set_internal(id,str(val),get_rtti_type_id<T>());
437  }
438 
440 
450  template<class T>
451  inline T get(const std::string &idIn) const {
452  if(!contains(idIn)) throw EntryNotFoundException(m_sDefaultPrefix+idIn);
453  if(!check_type<T>(idIn)) throw InvalidTypeException(m_sDefaultPrefix+idIn,get_type_name<T>());
454  return parse<T>(m_entries.find(m_sDefaultPrefix+idIn)->second.value);
455  }
456 
458 
460  template<class T>
461  inline T get(const std::string &idIn,const T &def) const {
462  if(!contains(idIn)) return def;
463  if(!check_type<T>(idIn)) throw InvalidTypeException(m_sDefaultPrefix+idIn,get_type_name<T>());
464  return parse<T>(m_entries.find(m_sDefaultPrefix+idIn)->second.value);
465  }
466 
468  static void loadConfig(const std::string &filename);
469 
471  static void loadConfig(const ConfigFile &configFile);
472 
474  static const ConfigFile &getConfig(){ return s_oConfig; }
475 
477  template<class T>
478  static inline T sget(const std::string &id) {
479  return getConfig().get<T>(id);
480  }
481 
483  template<class T>
484  static inline T sget(const std::string &id,const T &def) {
485  return getConfig().get<T>(id,def);
486  }
487 
489  void listContents() const;
490 
492  bool contains(const std::string &id) const;
493 
495 
497  inline KeyRestriction():
498  hasRange(false),hasValues(false){}
499  inline KeyRestriction(double min, double max):
500  hasRange(true),hasValues(false){
501  this->min = min;
502  this->max = max;
503  }
504  inline KeyRestriction(const std::string &values):
505  values(values),hasRange(false),hasValues(true){}
506  ICLUtils_API std::string toString() const;
507 
508  double min,max;
509  std::string values;
510 
511  bool hasRange;
512  bool hasValues;
513  };
514 
516 
518  void setRestriction(const std::string &id, const KeyRestriction &r) ;
519 
521 
522  const KeyRestriction *getRestriction(const std::string &id) const ;
523 
525  struct Entry{
526  std::string id;
527  std::string value;
528  std::string rttiType;
530 
532  const std::string &getTypeName() const { return getMapsInstanceRef().typeMap[rttiType]; }
533 
535  std::string getRelID() const {
536  const std::string &pfx = parent->getPrefix();
537  if(!pfx.length()) return id;
538  else return id.substr(pfx.length());
539  }
540  ConfigFile *parent; // parent ConfigFile (used to obtain current prefix)
541  };
542 
544  typedef std::map<std::string,Entry>::const_iterator const_iterator;
545 
547  const_iterator begin() const{ return m_entries.begin(); }
548 
550  const_iterator end() const{ return m_entries.end(); }
551 
553  const std::vector<const Entry*> getEntryList(bool relToPrefix=false) const{
554  std::vector<const Entry*> v;
555  for(const_iterator it =begin();it != end(); ++it){
556  v.push_back(&it->second);
557  }
558  return v;
559  }
560 
562  void clear();
563 
565 
568  const pugi::xml_document *getHandle() const { return m_doc.get(); }
569 
570  private:
571 
573  void load_internal();
574 
576  Entry &get_entry_internal(const std::string &id) ;
577 
579  const Entry &get_entry_internal(const std::string &id) const ;
580 
582  void set_internal(const std::string &id, const std::string &val, const std::string &type) ;
583 
585  static void add_to_doc(pugi::xml_document &h,const std::string &id,const std::string &type,
586  const std::string &value,const KeyRestriction *restr=0);
587 
590 
593 
594 
596  mutable std::string m_sDefaultPrefix;
597 
598 
600  std::map<std::string,Entry> m_entries;
601 
603  friend ICLUtils_API std::ostream &operator<<(std::ostream&, const ConfigFile&);
604  };
605 
606 
608  ICLUtils_API std::ostream &operator<<(std::ostream &s, const ConfigFile &cf);
609 
611  template<> inline ConfigFile::Data &ConfigFile::Data::operator=(char * const &t)
612  {
613  return ConfigFile::Data::operator=(std::string(t));
614  }
615  template<> inline ConfigFile::Data &ConfigFile::Data::operator=(const char * const &t)
616  {
617  return ConfigFile::Data::operator=(std::string(t));
618  }
621  } // namespace utils
622 }
623 
624 
625 
double min
Definition: ConfigFile.h:508
SmartPtrBase< pugi::xml_document, XMLDocumentDelOp > m_doc
shallow copyable smart pointer of the document handle
Definition: ConfigFile.h:589
std::string value
entries value as string
Definition: ConfigFile.h:527
T get(const std::string &idIn) const
returns a given value from the internal string based representation (un const)
Definition: ConfigFile.h:451
Utility Type for restriction of type values.
Definition: ConfigFile.h:496
ICLQt_API void save(const core::ImgBase &image, const std::string &filename)
write an image to HD
undocument this line if you encounter any issues!
Definition: Any.h:37
internal utility structure for contained data
Definition: ConfigFile.h:525
internally used type map class
Definition: ConfigFile.h:200
ConfigFile * cf
parent config file
Definition: ConfigFile.h:339
bool check_type(const std::string &id) const
internally used utitlity function (id must be given without prefix)
Definition: ConfigFile.h:236
Utility class for creating and reading XML-based hierarchical configuration files.
Definition: ConfigFile.h:171
UnregisteredTypeException(const std::string &rttiID)
Definition: ConfigFile.h:192
#define ICLUtils_API
this macros are important for creating dll's
Definition: CompatMacros.h:171
Data & operator=(const T &t)
mutlti class assignment operator
Definition: ConfigFile.h:378
~UnregisteredTypeException()
Definition: ConfigFile.h:194
std::string m_sDefaultPrefix
current string prefix contents
Definition: ConfigFile.h:596
ICLQt_API core::Img< T > load(const std::string &filename)
load an image file read file (affinity for floats)
std::string getRelID() const
returns this entries id relatively to the parent ConfigFiles prefix
Definition: ConfigFile.h:535
static T sget(const std::string &id)
applies get on the static config instances
Definition: ConfigFile.h:478
static ConfigFile s_oConfig
global ConfigFile instance
Definition: ConfigFile.h:592
Internal exception type, thrown if an entry type missmatch occurs.
Definition: ConfigFile.h:184
Data- type used for the []-operator of ConfigFile instances.
Definition: ConfigFile.h:337
Data & operator=(const Data &d)
special assignment for data instances
Definition: ConfigFile.h:365
void set(const std::string &id, const T &val)
sets or updates a new data element to the ConfigFile
Definition: ConfigFile.h:435
bool hasRange
Definition: ConfigFile.h:511
const_iterator end() const
all-entry iterator end
Definition: ConfigFile.h:550
KeyRestriction(double min, double max)
Definition: ConfigFile.h:499
static const ConfigFile & getConfig()
returns the global ConfigFile
Definition: ConfigFile.h:474
Internal exception type, thrown if an entry was not found.
Definition: ConfigFile.h:177
std::string rttiType
entries rtti type ID
Definition: ConfigFile.h:528
const std::vector< Data > find(const std::string &regex) const
returns all data entries, that match the given regex (const);
Definition: ConfigFile.h:403
std::string values
Definition: ConfigFile.h:509
ICLUtils_API std::ostream & operator<<(std::ostream &s, const ConfigFile &cf)
Default ostream operator to put a ConfigFile into a stream.
InvalidTypeException(const std::string &entryName, const std::string &typeName)
Definition: ConfigFile.h:185
T get(const std::string &idIn, const T &def) const
returns a given value from the internal string based representation
Definition: ConfigFile.h:461
ConfigFile * parent
Definition: ConfigFile.h:540
std::string str(const T &t)
convert a data type into a string using an std::ostringstream instance
Definition: StringUtils.h:136
std::map< std::string, std::string > typeMapReverse
reverse ordered map here, key is written type, and value is rtti-type
Definition: ConfigFile.h:205
std::string id
entries key (config.foo.bar....)
Definition: ConfigFile.h:526
static Maps & getMapsInstanceRef()
returns a singelton instance of type Maps as reference
Definition: ConfigFile.h:212
KeyRestriction(const std::string &values)
Definition: ConfigFile.h:504
static void register_type(const std::string &id)
registers a new type in the data store parsing engine
Definition: ConfigFile.h:285
static T sget(const std::string &id, const T &def)
applies get on the static config instances (with default)
Definition: ConfigFile.h:484
T as() const
explicit cast into given type
Definition: ConfigFile.h:359
virtual ~InvalidTypeException()
Definition: ConfigFile.h:187
const std::vector< const Entry * > getEntryList(bool relToPrefix=false) const
returns all entries as vector<const Entry*>
Definition: ConfigFile.h:553
std::map< std::string, Entry >::const_iterator const_iterator
iterator type to run through all entries (const only)
Definition: ConfigFile.h:544
static const std::string & get_rtti_type_id()
internally used utitlity function
Definition: ConfigFile.h:229
bool hasValues
Definition: ConfigFile.h:512
Base class for Exception handling in the ICL.
Definition: Exception.h:42
Interface for objects, that can be locked using an internal mutex.
Definition: Lockable.h:41
KeyRestriction()
Definition: ConfigFile.h:497
static const std::string & get_type_name()
internally used utitlity function
Definition: ConfigFile.h:220
SmartPtr< KeyRestriction > restr
Definition: ConfigFile.h:529
std::string id
internal id (config.foo.bar)
Definition: ConfigFile.h:338
static bool type_registered_by_rtti(const std::string &rttiID)
internally used utitlity function
Definition: ConfigFile.h:245
const std::string & getTypeName() const
optional restriction pointer
Definition: ConfigFile.h:532
std::map< std::string, Entry > m_entries
DataStore contents.
Definition: ConfigFile.h:600
thrown if unregistered types are used
Definition: ConfigFile.h:191
std::map< std::string, std::string > typeMap
key: rttiType (e.g. i), value: written type (e.g. int)
Definition: ConfigFile.h:202
const pugi::xml_document * getHandle() const
returns internal document handle (forward declared here) (const only)
Definition: ConfigFile.h:568
const_iterator begin() const
all-entry iterator begin
Definition: ConfigFile.h:547
EntryNotFoundException(const std::string &entryName)
Definition: ConfigFile.h:178
virtual ~EntryNotFoundException()
Definition: ConfigFile.h:180
Specialization of the SmartPtrBase class for Pointers.
Definition: SmartPtr.h:75