damaris-backends/core/backend_config_reader.h
2014-06-26 11:10:51 +00:00

120 lines
4.6 KiB
C++

/* **************************************************************************
Author: Stefan Reutter
Created: August 2013
****************************************************************************/
#ifndef DAMARIS_backend_config_reader_h
#define DAMARIS_backend_config_reader_h
#include <glib.h>
#include <stdexcept>
namespace DAMARIS
{
/**
* \defgroup BackendConfigReader Backend Config Reader
* \ingroup machines
*
* Allows reading in a backend configuration file implemented as a Glib Key-Value file
*/
/*@{*/
/**
* Exception class for the config file.
*/
class BackendConfigException : public std::runtime_error
{
public:
explicit BackendConfigException(const std::string& msg) throw() : std::runtime_error(msg) {};
explicit BackendConfigException(const char* msg) throw() : std::runtime_error(msg) {};
virtual ~BackendConfigException() throw() {};
};
/**
* Class for reading a backend configuration file. Must be constructed with a c string providing the relative path to the config file.
*
* BackendConfigReader will first look in the XDG user config folder for the file, then in all system config folders. If no
* config file is found in any of these locations, a BackendConfigException will be thrown.
*
* Example:
* \code
* DAMARIS::BackendConfigReader cfgReader("/damaris/backend.conf");
* std::cout << cfgReader.getInteger("ADC", "id") << "\n";
* \endcode
*
*/
class BackendConfigReader
{
public:
/**
* \param configPath C String containing the relative path to the config file
*/
BackendConfigReader(const gchar *configPath);
~BackendConfigReader() { g_key_file_free(_keyFile); }; // I hope this is exception safe
/* -------------------------------------------------------------------- */
/* The following functions are encapsulating the underlying GKeyFile functionality */
inline gboolean getBoolean(const gchar *groupName, const gchar *key) {GError* err = NULL; bool ret = g_key_file_get_boolean(_keyFile, groupName, key, &err); if (err) {g_error("GLib Error code %i, message: %s", err->code, err->message);} return ret;};
inline gdouble getDouble(const gchar *groupName, const gchar *key) {GError* err = NULL; double ret = g_key_file_get_double(_keyFile, groupName, key, &err); if (err) {g_error("GLib Error code %i, message: %s", err->code, err->message);} return ret;};
inline gint getInteger(const gchar *groupName, const gchar *key) {GError* err = NULL; int ret = g_key_file_get_integer(_keyFile, groupName, key, &err); if (err) {g_error("GLib Error code %i, message: %s", err->code, err->message);} return ret;};
inline gchar* getValue(const gchar *groupName, const gchar *key) {GError* err = NULL; gchar* ret = g_key_file_get_value(_keyFile, groupName, key, &err); if (err) {g_error("GLib Error code %i, message: %s", err->code, err->message);} return ret;};
inline gchar* getString(const gchar *groupName, const gchar *key) {GError* err = NULL; gchar* ret = g_key_file_get_string(_keyFile, groupName, key, &err); if (err) {g_error("GLib Error code %i, message: %s", err->code, err->message);} return ret;};
/**
* This allows you to pass a function pointer to BackendConfigReader in order to call one of the functions on GKeyFile that are not driectly provided.
*
* Because a function pointer needs to know the full signature, the function pointer must reflect this.
*
* Example usage:
* \code
* gchar* groupName; // initialized
* gchar* key; // initialized
* gint64 (*f)(GKeyFile*, const gchar *, const gchar *, GError*) = &g_key_file_get_int64;
* gint64 value = getSomething<gint64> (f, groupName, key);
* \endcode
*/
template<typename returnType>
returnType getSomething(returnType (*func)(GKeyFile*, const gchar *, const gchar *, GError*), const gchar *groupName, const gchar *key)
{
GError* err = NULL;
returnType ret = func(_keyFile, groupName, key, &err);
if (err) {g_error("GLib Error code %i, message: %s", err->code, err->message);}
return ret;
}
/* -------------------------------------------------------------------- */
private:
/**
* Attempt to load the defined relative config path.
*
* First, attempt to load the file from the user config dir. If that fails, attempt to load from the system config dir. If that fails as well, exit the program.
*/
void loadConfig();
/**
* Load a specific config file. Returns true on success, false on file not found. Throws an error otherwise.
*/
bool loadConfigFile(const gchar *keyFileName, GKeyFileFlags flags, GError *error);
/**
* (Relative) Path to the damaris backend config
*/
const gchar *_damarisConfigPath;
GKeyFile *_keyFile;
};
/*@}*/
} // namespace DAMARIS
#endif // include guard