diff options
Diffstat (limited to 'src/CRSMConfig.cpp')
| -rw-r--r-- | src/CRSMConfig.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/CRSMConfig.cpp b/src/CRSMConfig.cpp new file mode 100644 index 0000000..25f8bd1 --- /dev/null +++ b/src/CRSMConfig.cpp @@ -0,0 +1,155 @@ +#include "CRSMConfig.hpp" + +#include <QFile> + +CRSMConfig::CRSMConfig() +{ + +} + +void CRSMConfig::addConfigValue(QString name, CRSMConfigValueBase* value) +{ + configValues[name] = value; +} + +void CRSMConfig::setConfigValue(const QString &name, const QString &value) +{ + CRSMConfigValueBase& configValue = getConfigValue(name); + configValue.setValue(value); +} + +void CRSMConfig::addConfigListEntry(const QString &name, const QString &value) +{ + CRSMConfigValueBase& configValue = getConfigValue(name); + if(configValue.type() != CRSMConfigValueType::List) + { + throw CRSMConfigException("Cannot add a list entry to a non-list-config value \"" + name.toStdString() + "\""); + } + ((CRSMConfigValueList*)&configValue)->append(value); +} + +void CRSMConfig::setConfigMapValue(const QString &name, const QString &key, const QString &value) +{ + CRSMConfigValueBase& configValue = getConfigValue(name); + if(configValue.type() != CRSMConfigValueType::Map) + { + throw CRSMConfigException("Cannot set a map value on a non-map-config value \"" + name.toStdString() + "\""); + } + ((CRSMConfigValueMap*)&configValue)->setKeyValue(key, value); +} + +CRSMConfigValueBase& CRSMConfig::getConfigValue(const QString& name) +{ + if(!configValues.contains(name)) + { + throw CRSMConfigException("Unknown config value \"" + name.toStdString() + "\""); + } + else + { + return *configValues[name]; + } +} + +QString CRSMConfig::read(const QString &fileName) +{ + QString ret = ""; + + QFile config(fileName); + if(!config.exists()) + { + if(write(fileName)) + { + return fileName + ": The config-file did not exist, a new one with default values has been created.\n"; + } + else + { + return fileName + ": The config-file did not exist, a new one could not be created.\n"; + } + } + else if(config.open(QIODevice::ReadOnly | QIODevice::Text)) + { + static QRegExp valueExp(R"(^([^=]+)=(.*)$)"); + static QRegExp listExp(R"(^([^=]+)\+=(.*)$)"); + static QRegExp mapExp(R"(^([^\[]+)\[([^\]]+)\]\s*=\s*(.*)$)"); + QString line; + for(size_t lineNr = 1; !config.atEnd(); ++lineNr) + { + try + { + line = config.readLine().trimmed(); + if(listExp.exactMatch(line)) + { + addConfigListEntry(listExp.cap(1).trimmed(), listExp.cap(2).trimmed()); + } + else if(mapExp.exactMatch(line)) + { + setConfigMapValue(mapExp.cap(1).trimmed(), mapExp.cap(2).trimmed(), mapExp.cap(3).trimmed()); + } + else if(valueExp.exactMatch(line)) + { + setConfigValue(valueExp.cap(1).trimmed(), valueExp.cap(2).trimmed()); + } + } + catch(CRSMConfigException e) + { + ret += fileName + ":" + QString::number(lineNr) + ": " + e.what() + "\n"; + } + } + } + else + { + return fileName + ": The config-file could not be read.\n"; + } + + return ret; +} + +bool CRSMConfig::write(const QString &fileName) +{ + QFile config(fileName); + if(config.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) + { + foreach(const QString& key, configValues.keys()) + { + CRSMConfigValueBase& value = *configValues[key]; + switch(value.type()) + { + case CRSMConfigValueType::Map: + { + const QMap<QString, QString> values = (dynamic_cast<CRSMConfigValueMap*>(&value))->getValues(); + foreach(const QString& mapKey, values.keys()) + { + config.write(QString(key + "[" + mapKey + "]" + " = " + values.value(mapKey) + "\n").toUtf8()); + } + break; + } + case CRSMConfigValueType::List: + foreach(const QString& val, (dynamic_cast<CRSMConfigValueList*>(&value))->getValues()) + { + config.write(QString(key + " += " + val + "\n").toUtf8()); + } + break; + default: + config.write(QString(key + " = " + value.value() + "\n").toUtf8()); + } + } + + return true; + } + else + { + return false; + } +} + +void CRSMConfig::operator()(CRSMConfig &&other) +{ + auto curConfigValues(configValues); + *this = other; + configValues = curConfigValues; +} + +void CRSMConfig::clear() +{ + (*this)(CRSMConfig()); +} |
