Image Component Library (ICL)
|
Utility class for creating and reading XML-based hierarchical configuration files. More...
#include <ConfigFile.h>
Classes | |
class | Data |
Data- type used for the []-operator of ConfigFile instances. More... | |
struct | Entry |
internal utility structure for contained data More... | |
struct | EntryNotFoundException |
Internal exception type, thrown if an entry was not found. More... | |
struct | InvalidTypeException |
Internal exception type, thrown if an entry type missmatch occurs. More... | |
struct | KeyRestriction |
Utility Type for restriction of type values. More... | |
struct | Maps |
internally used type map class More... | |
struct | UnregisteredTypeException |
thrown if unregistered types are used More... | |
Public Types | |
typedef std::map< std::string, Entry >::const_iterator | const_iterator |
iterator type to run through all entries (const only) | |
Public Member Functions | |
ConfigFile () | |
Default constructor creating an empty ConfigFile instance. | |
ConfigFile (const std::string &filename) throw (FileNotFoundException,InvalidFileFormatException,UnregisteredTypeException) | |
Creates a ConfigFile instance with given filename. | |
ConfigFile (pugi::xml_document *handle) throw (UnregisteredTypeException) | |
Creates a ConfigFile from given handle instance. | |
ConfigFile (std::istream &stream) throw (FileNotFoundException,InvalidFileFormatException,UnregisteredTypeException) | |
creates a ConfigFile instance from given istream. | |
void | load (const std::string &filename) throw (FileNotFoundException,InvalidFileFormatException,UnregisteredTypeException) |
loads the ConfigFile from given filename and updates internal filename variable | |
void | save (const std::string &filename) const |
Writes data to disk using given filename. | |
void | setPrefix (const std::string &defaultPrefix) const |
Sets up a default prefix automatically put before each given key. | |
const std::string & | getPrefix () const |
Returns given default prefix. | |
Data | operator[] (const std::string &id) |
main access function to datastore entries (unconst) | |
const Data | operator[] (const std::string &id) const throw (EntryNotFoundException) |
main access function to datastore entries (const) | |
std::vector< Data > | find (const std::string ®ex) |
returns all data entries, that match the given regex | |
const std::vector< Data > | find (const std::string ®ex) const |
returns all data entries, that match the given regex (const); | |
template<class T > | |
void | set (const std::string &id, const T &val) throw (UnregisteredTypeException) |
sets or updates a new data element to the ConfigFile | |
template<class T > | |
T | get (const std::string &idIn) const throw (EntryNotFoundException,InvalidTypeException,UnregisteredTypeException) |
returns a given value from the internal string based representation (un const) | |
template<class T > | |
T | get (const std::string &idIn, const T &def) const throw (InvalidTypeException,UnregisteredTypeException) |
returns a given value from the internal string based representation | |
void | listContents () const |
lists whole datastore contents | |
bool | contains (const std::string &id) const |
returns whether an entry with given ID is contained | |
void | setRestriction (const std::string &id, const KeyRestriction &r) throw (EntryNotFoundException) |
defined the range for given number-type-valued key | |
const KeyRestriction * | getRestriction (const std::string &id) const throw (EntryNotFoundException) |
returns predefined range for given id (or 0 if no range was defined for this key) | |
const_iterator | begin () const |
all-entry iterator begin | |
const_iterator | end () const |
all-entry iterator end | |
const std::vector< const Entry * > | getEntryList (bool relToPrefix=false) const |
returns all entries as vector<const Entry*> | |
void | clear () |
removes all contents (except config and title node) | |
const pugi::xml_document * | getHandle () const |
returns internal document handle (forward declared here) (const only) | |
Static Public Member Functions | |
template<class T > | |
static void | register_type (const std::string &id) |
static void | loadConfig (const std::string &filename) |
loads the global ConfigFile from given filename | |
static void | loadConfig (const ConfigFile &configFile) |
loads a ConfigFile object into the global config file (shallowly copied!) | |
static const ConfigFile & | getConfig () |
returns the global ConfigFile | |
template<class T > | |
static T | sget (const std::string &id) throw (EntryNotFoundException,InvalidTypeException) |
applies get on the static config instances | |
template<class T > | |
static T | sget (const std::string &id, const T &def) throw (InvalidTypeException) |
applies get on the static config instances (with default) | |
Private Member Functions | |
template<class T > | |
bool | check_type (const std::string &id) const throw (EntryNotFoundException,UnregisteredTypeException) |
internally used utitlity function (id must be given without prefix) | |
bool | check_type_internal (const std::string &id, const std::string &rttiTypeID) const throw (EntryNotFoundException,UnregisteredTypeException) |
internally used utitlity function | |
void | load_internal () |
internal utitlity function to parse existing XMLDocument | |
Entry & | get_entry_internal (const std::string &id) throw (EntryNotFoundException) |
internal utility function | |
const Entry & | get_entry_internal (const std::string &id) const throw (EntryNotFoundException) |
internal utility function | |
void | set_internal (const std::string &id, const std::string &val, const std::string &type) throw (UnregisteredTypeException) |
internal utility function | |
Static Private Member Functions | |
static Maps * | getMapsInstance () |
returns a singelton instance of type Maps | |
static Maps & | getMapsInstanceRef () |
returns a singelton instance of type Maps as reference | |
template<class T > | |
static const std::string & | get_type_name () throw (UnregisteredTypeException) |
internally used utitlity function | |
template<class T > | |
static const std::string & | get_rtti_type_id () |
internally used utitlity function | |
static bool | type_registered_by_rtti (const std::string &rttiID) |
internally used utitlity function | |
static void | add_to_doc (pugi::xml_document &h, const std::string &id, const std::string &type, const std::string &value, const KeyRestriction *restr=0) |
internally synchronized an add- or a set call | |
Private Attributes | |
SmartPtrBase < pugi::xml_document, XMLDocumentDelOp > | m_doc |
shallow copyable smart pointer of the document handle | |
std::string | m_sDefaultPrefix |
current string prefix contents | |
std::map< std::string, Entry > | m_entries |
DataStore contents. | |
Static Private Attributes | |
static ConfigFile | s_oConfig |
global ConfigFile instance | |
Friends | |
class | ConfigFileGUI |
ICLUtils_API std::ostream & | operator<< (std::ostream &, const ConfigFile &) |
ostream operator is allowed to access privat members |
Utility class for creating and reading XML-based hierarchical configuration files.
ConfigFile class can be used in object based as well as in static manner.
ConfigFile objects can e.g. be used, to locally read a configuration file or to create a configuration file. Besides a static singleton ConfigFile object accessible via ConfigFile::getConfig can be used as a global configuration for applications.
Furthermore a powerful runtime-editor called ConfigFileGUI is available in the ICLQt package.
ConfigFiles are XML-based (using ICL's XML environment for parsing and creating XML structure). The document is hierarchical as the following example demonstrates
<?xml version='1.0' encoding='ISO-8859-1'?> <config> <title>This is the new title</title> <section id="general" > <section id="params" > <data type="int" id="threshold" >7</data> <data type="double" id="value" >6.450000</data> <data type="string" id="filename" >./notHallo.txt</data> </section> </section> <section id="special" > <data type="char" id="hint" >a</data> <data type="char" id="no-hint" >b</data> </section> </config>
In addition to the syntax above, each data-tag can be set up with a range property or a value list. Currently data ranges are only used for int- and float- typed data elements. If a range property is defined like this
<data id="threshold" type="int" range="[0,255]">127</data>
the ConfigFileGUI editor will automatically create an integer slider with given range for this entry. (As mentioned above, this feature is also available for float-typed entries).
Value lists are only supported for string-typed entries! value lists must be defined like this:
<data id="grabber-type" type="string" values="[pwc,dc,file,unicap]">dc</data>
(Don't forget enclosing brackets). Value lists are translated to a combobox containing all given entries. It's self-evident. that the initial value must be within the value list (otherwise an error is shown, and the combo-box value is out of date until the combo-box is use for the first time. The same is true for ranged float- or int-entry restriction.
When accessing ConfigFile data members, each hierarchy level must be separated using the '.' character. So e.g. the entry 'filename' of the example above can be accessed using
ConfigFile config("myConfig.xml"); // myConfig.xml shall contain the contents above string fn = config["general.params.filename"];
Note, that config["general.params.filename"] can only be assigned to std::string instances as it's type is xmlfile type is 'string'. Here we use a special C++ technique, which overloads the implicit cast operator for the ConfigFile::Data class (with is returned by the operator[]) by using a template.
To avoid errors there's also a "get"-function which can be called with a default return value:
ConfigFile config("myConfig.xml"); string fn = config.get<string>("general.params.filename","defaultpath.xml");
In the same manner, ConfigFile entries can be generated: The example file above was generated with the following code (Note: the "config"-prefix is compulsory!)
ConfigFile a; a["config.general.params.threshold"] = 7; a["config.general.params.value"] = 6.45f; a["config.general.params.filename"] = std::string("./hallo.txt"); a["config.general.params.filename"] = std::string("./notHallo.txt"); a["config.special.hint"] = 'a'; a["config.special.no-hint"] = 'b'; a.save("config.xml");
Functions for data access and data definition are implemented as non-inline templates, which are instantiated for the following types:
additionally we need a fixed matrix type (e.g. color)
Internally data is stored in the parent classes (DataStore) hash maps to optimize data access. ConfigFile data key is the the '.'-concatenated identifier.
typedef std::map<std::string,Entry>::const_iterator icl::utils::ConfigFile::const_iterator |
iterator type to run through all entries (const only)
Default constructor creating an empty ConfigFile instance.
The empty ConfigFile has the following string representation:
<?xml version='1.0' encoding='ISO-8859-1'?> <config> <title>no title defined"</title> </config>
icl::utils::ConfigFile::ConfigFile | ( | const std::string & | filename | ) | throw (FileNotFoundException,InvalidFileFormatException,UnregisteredTypeException) |
Creates a ConfigFile instance with given filename.
filename | if filename is found and it contains a valid ConfigFile structure, it is read into the ConfigFile instance. Otherwise, filename is stored internally for later use if load(void) or save(void) is called. |
icl::utils::ConfigFile::ConfigFile | ( | pugi::xml_document * | handle | ) | throw (UnregisteredTypeException) |
Creates a ConfigFile from given handle instance.
Note: Ownership is passed to this ConfigFile instance here
icl::utils::ConfigFile::ConfigFile | ( | std::istream & | stream | ) | throw (FileNotFoundException,InvalidFileFormatException,UnregisteredTypeException) |
creates a ConfigFile instance from given istream.
The constructor will only read the stream until the first opening tag is closed
static void icl::utils::ConfigFile::add_to_doc | ( | pugi::xml_document & | h, |
const std::string & | id, | ||
const std::string & | type, | ||
const std::string & | value, | ||
const KeyRestriction * | restr = 0 |
||
) | [static, private] |
internally synchronized an add- or a set call
const_iterator icl::utils::ConfigFile::begin | ( | ) | const [inline] |
all-entry iterator begin
bool icl::utils::ConfigFile::check_type | ( | const std::string & | id | ) | const throw (EntryNotFoundException,UnregisteredTypeException) [inline, private] |
internally used utitlity function (id must be given without prefix)
bool icl::utils::ConfigFile::check_type_internal | ( | const std::string & | id, |
const std::string & | rttiTypeID | ||
) | const throw (EntryNotFoundException,UnregisteredTypeException) [private] |
internally used utitlity function
void icl::utils::ConfigFile::clear | ( | ) |
removes all contents (except config and title node)
bool icl::utils::ConfigFile::contains | ( | const std::string & | id | ) | const |
returns whether an entry with given ID is contained
const_iterator icl::utils::ConfigFile::end | ( | ) | const [inline] |
all-entry iterator end
std::vector<Data> icl::utils::ConfigFile::find | ( | const std::string & | regex | ) |
returns all data entries, that match the given regex
note, the current default prefix is not used here
const std::vector<Data> icl::utils::ConfigFile::find | ( | const std::string & | regex | ) | const [inline] |
returns all data entries, that match the given regex (const);
note, the current default prefix is not used here.
note2: const-concept not implemented properly
T icl::utils::ConfigFile::get | ( | const std::string & | idIn | ) | const throw (EntryNotFoundException,InvalidTypeException,UnregisteredTypeException) [inline] |
returns a given value from the internal string based representation (un const)
Internally, the string to T conversion is performed during this function call, so it might increase system performance to extract ConfigFile entries not in loops or something like that.
Three errors can occur:
T icl::utils::ConfigFile::get | ( | const std::string & | idIn, |
const T & | def | ||
) | const throw (InvalidTypeException,UnregisteredTypeException) [inline] |
returns a given value from the internal string based representation
Like the function above, except it uses a default value if given key cannot be found
Entry& icl::utils::ConfigFile::get_entry_internal | ( | const std::string & | id | ) | throw (EntryNotFoundException) [private] |
internal utility function
const Entry& icl::utils::ConfigFile::get_entry_internal | ( | const std::string & | id | ) | const throw (EntryNotFoundException) [private] |
internal utility function
static const std::string& icl::utils::ConfigFile::get_rtti_type_id | ( | ) | [inline, static, private] |
internally used utitlity function
static const std::string& icl::utils::ConfigFile::get_type_name | ( | ) | throw (UnregisteredTypeException) [inline, static, private] |
internally used utitlity function
static const ConfigFile& icl::utils::ConfigFile::getConfig | ( | ) | [inline, static] |
returns the global ConfigFile
const std::vector<const Entry*> icl::utils::ConfigFile::getEntryList | ( | bool | relToPrefix = false | ) | const [inline] |
returns all entries as vector<const Entry*>
const pugi::xml_document* icl::utils::ConfigFile::getHandle | ( | ) | const [inline] |
returns internal document handle (forward declared here) (const only)
this function is not available in un-const manner, to avoid that users change the document structure somehow, what would cause inconsistencies between the internal XMLDocument structure and the ConfigFile data-base
static Maps* icl::utils::ConfigFile::getMapsInstance | ( | ) | [static, private] |
returns a singelton instance of type Maps
static Maps& icl::utils::ConfigFile::getMapsInstanceRef | ( | ) | [inline, static, private] |
returns a singelton instance of type Maps as reference
const std::string& icl::utils::ConfigFile::getPrefix | ( | ) | const |
Returns given default prefix.
const KeyRestriction* icl::utils::ConfigFile::getRestriction | ( | const std::string & | id | ) | const throw (EntryNotFoundException) |
returns predefined range for given id (or 0 if no range was defined for this key)
This feature is only used by the config file GUI
void icl::utils::ConfigFile::listContents | ( | ) | const |
lists whole datastore contents
void icl::utils::ConfigFile::load | ( | const std::string & | filename | ) | throw (FileNotFoundException,InvalidFileFormatException,UnregisteredTypeException) |
loads the ConfigFile from given filename and updates internal filename variable
Warning: old data content is lost!
void icl::utils::ConfigFile::load_internal | ( | ) | [private] |
internal utitlity function to parse existing XMLDocument
static void icl::utils::ConfigFile::loadConfig | ( | const std::string & | filename | ) | [static] |
loads the global ConfigFile from given filename
static void icl::utils::ConfigFile::loadConfig | ( | const ConfigFile & | configFile | ) | [static] |
loads a ConfigFile object into the global config file (shallowly copied!)
Data icl::utils::ConfigFile::operator[] | ( | const std::string & | id | ) |
main access function to datastore entries (unconst)
const Data icl::utils::ConfigFile::operator[] | ( | const std::string & | id | ) | const throw (EntryNotFoundException) |
main access function to datastore entries (const)
As above, but only for reading ...
static void icl::utils::ConfigFile::register_type | ( | const std::string & | id | ) | [inline, static] |
the macro REGISTER_CONFIG_FILE_TYPE(T)
can be used to register new types to the data store. This macro is defined as ::icl::utils::ConfigFile::register_type<T>(T)
registers a new type in the data store parsing engine Note: only registered types can be loaded from an xml-file currently, the following types are registered automatically:
POD Types:
Other ICL Types:
void icl::utils::ConfigFile::save | ( | const std::string & | filename | ) | const |
Writes data to disk using given filename.
void icl::utils::ConfigFile::set | ( | const std::string & | id, |
const T & | val | ||
) | throw (UnregisteredTypeException) [inline] |
sets or updates a new data element to the ConfigFile
Warning: if not unique decidable, an explicit information about the value type T is compulsory.
e.g.
ConfigFile f; f.set("config.filename","myText.txt");
Causes an error because the template type T is resolved as const char* which is not supported yet. Better versions use an explicit template:
ConfigFile f; f.set<std::string>("config.filename","myText.txt");
or an explicit string argument:
ConfigFile f; f.set("config.filename",std::string("myText.txt"));
to avoid these errors.
Note: Integer constants are of type "int" by default, and floating point constants are of type "double" by default:
void icl::utils::ConfigFile::set_internal | ( | const std::string & | id, |
const std::string & | val, | ||
const std::string & | type | ||
) | throw (UnregisteredTypeException) [private] |
internal utility function
void icl::utils::ConfigFile::setPrefix | ( | const std::string & | defaultPrefix | ) | const |
Sets up a default prefix automatically put before each given key.
void icl::utils::ConfigFile::setRestriction | ( | const std::string & | id, |
const KeyRestriction & | r | ||
) | throw (EntryNotFoundException) |
defined the range for given number-type-valued key
This feature is used by the ConfigFileGUI to create appropriate slider ranges if requested
static T icl::utils::ConfigFile::sget | ( | const std::string & | id | ) | throw (EntryNotFoundException,InvalidTypeException) [inline, static] |
applies get on the static config instances
static T icl::utils::ConfigFile::sget | ( | const std::string & | id, |
const T & | def | ||
) | throw (InvalidTypeException) [inline, static] |
applies get on the static config instances (with default)
static bool icl::utils::ConfigFile::type_registered_by_rtti | ( | const std::string & | rttiID | ) | [inline, static, private] |
internally used utitlity function
friend class ConfigFileGUI [friend] |
ICLUtils_API std::ostream& operator<< | ( | std::ostream & | , |
const ConfigFile & | |||
) | [friend] |
ostream operator is allowed to access privat members
SmartPtrBase<pugi::xml_document,XMLDocumentDelOp> icl::utils::ConfigFile::m_doc [mutable, private] |
shallow copyable smart pointer of the document handle
std::map<std::string,Entry> icl::utils::ConfigFile::m_entries [private] |
DataStore contents.
std::string icl::utils::ConfigFile::m_sDefaultPrefix [mutable, private] |
current string prefix contents
ConfigFile icl::utils::ConfigFile::s_oConfig [static, private] |
global ConfigFile instance