summaryrefslogtreecommitdiffstats
path: root/src/Core
diff options
context:
space:
mode:
Diffstat (limited to 'src/Core')
-rw-r--r--src/Core/ConfigEntry.cpp94
-rw-r--r--src/Core/ConfigEntry.h75
-rw-r--r--src/Core/ConfigManager.cpp40
-rw-r--r--src/Core/ConfigManager.h13
-rw-r--r--src/Core/Configurable.h4
-rw-r--r--src/Core/LogManager.cpp68
-rw-r--r--src/Core/LogManager.h3
7 files changed, 157 insertions, 140 deletions
diff --git a/src/Core/ConfigEntry.cpp b/src/Core/ConfigEntry.cpp
index 04ed08f..ec716b6 100644
--- a/src/Core/ConfigEntry.cpp
+++ b/src/Core/ConfigEntry.cpp
@@ -22,43 +22,85 @@
namespace Mad {
namespace Core {
-String& ConfigEntry::Entry::operator[] (std::size_t i) {
- try {
- return value.at(i);
- }
- catch(std::out_of_range &e) {
- zero = String();
- return zero;
- }
+void ConfigEntry::addChild(const String &key, boost::shared_ptr<ConfigEntry> entry) {
+ String lowerKey(key);
+ lowerKey.toLower();
+
+ EntryMap::iterator child = children.find(lowerKey);
+
+ if(child == children.end())
+ child = children.insert(std::make_pair(lowerKey, EntryVector())).first;
+
+ child->second.push_back(entry);
}
-const String& ConfigEntry::Entry::operator[] (std::size_t i) const {
- try {
- return value.at(i);
- }
- catch(std::out_of_range &e) {
- return constZero;
+const ConfigEntry* ConfigEntry::getEntry(const String &key) const {
+ String childKey(key);
+ childKey.toLower();
+
+ int32_t dotIndex = key.indexOf('.');
+ if(dotIndex >= 0) {
+ childKey.remove(dotIndex);
}
-}
-ConfigEntry::Entry& ConfigEntry::operator[] (std::size_t i) {
- try {
- return entries.at(i);
+ EntryMap::const_iterator child = children.find(childKey);
+ if(child == children.end()) {
+ return 0;
}
- catch(std::out_of_range &e) {
- zero = Entry();
- return zero;
+ else {
+ if(dotIndex >= 0) {
+ return child->second.back()->getEntry(key.substr(dotIndex+1));
+ }
+ else {
+ return child->second.back().get();
+ }
}
}
-const ConfigEntry::Entry& ConfigEntry::operator[] (std::size_t i) const {
- try {
- return entries.at(i);
+std::vector<const ConfigEntry*> ConfigEntry::getEntries(const String &key) const {
+ String childKey(key);
+ childKey.toLower();
+
+ int32_t dotIndex = key.indexOf('.');
+ if(dotIndex >= 0) {
+ childKey.remove(dotIndex);
}
- catch(std::out_of_range &e) {
- return constZero;
+
+ EntryMap::const_iterator child = children.find(childKey);
+ if(child == children.end()) {
+ return std::vector<const ConfigEntry*>();
+ }
+ else {
+ if(dotIndex >= 0) {
+ return child->second.back()->getEntries(key.substr(dotIndex+1));
+ }
+ else {
+ std::vector<const ConfigEntry*> ret;
+
+ for(EntryVector::const_iterator entry = child->second.begin(); entry != child->second.end(); ++entry) {
+ ret.push_back(entry->get());
+ }
+
+ return ret;
+ }
}
}
+std::vector<String> ConfigEntry::getAll(const String &key) const {
+ const ConfigEntry *entry = getEntry(key);
+ if(!entry)
+ return std::vector<String>();
+ else
+ return entry->getValues();
+}
+
+String ConfigEntry::get(const String &key, const String &defaultValue) const {
+ const ConfigEntry *entry = getEntry(key);
+ if(!entry)
+ return defaultValue;
+ else
+ return entry->getValue(defaultValue);
+}
+
}
}
diff --git a/src/Core/ConfigEntry.h b/src/Core/ConfigEntry.h
index 26e77d2..1724267 100644
--- a/src/Core/ConfigEntry.h
+++ b/src/Core/ConfigEntry.h
@@ -23,63 +23,60 @@
#include "export.h"
#include "String.h"
-
-#include <stdexcept>
+#include <map>
#include <vector>
+#include <boost/shared_ptr.hpp>
namespace Mad {
namespace Core {
-class MAD_CORE_EXPORT ConfigEntry {
- public:
- class MAD_CORE_EXPORT Entry {
- private:
- String key;
- std::vector<String> value;
-
- String zero, constZero;
+class ConfigManager;
- public:
- Entry() {}
- Entry(const std::vector<String> &args) {
- if(args.empty())
- return;
-
- key = args.front();
+class MAD_CORE_EXPORT ConfigEntry {
+ private:
+ friend class ConfigManager;
- value.assign(args.begin()+1, args.end());
- }
+ typedef std::vector<boost::shared_ptr<ConfigEntry> > EntryVector;
+ typedef std::map<String, EntryVector> EntryMap;
- bool isEmpty() const {
- return key.isEmpty();
- }
+ ConfigEntry *parent;
- String &getKey() {return key;}
- const String &getKey() const {return key;}
+ std::vector<String> values;
+ EntryMap children;
- std::size_t getSize() const {return value.size();}
+ protected:
+ ConfigEntry() : parent(0) {}
- String& operator[] (std::size_t i);
- const String& operator[] (std::size_t i) const;
- };
+ public:
+ ConfigEntry(ConfigEntry *parent0, const std::vector<String> &values0)
+ : parent(parent0), values(values0) {}
- private:
- std::vector<Entry> entries;
- Entry zero, constZero;
+ void addChild(const String &key, boost::shared_ptr<ConfigEntry> entry);
- public:
- std::size_t getSize() const {return entries.size();}
+ const ConfigEntry* getParent() const {
+ return parent;
+ }
- Entry& operator[] (std::size_t i);
- const Entry& operator[] (std::size_t i) const;
+ ConfigEntry* getParent() {
+ return parent;
+ }
- void push(const Entry &entry) {
- entries.push_back(entry);
+ const std::vector<String>& getValues() const {
+ return values;
}
- void pop() {
- entries.pop_back();
+ String getValue(const String &defaultValue = String()) const {
+ if(values.empty())
+ return defaultValue;
+ else
+ return values.front();
}
+
+ const ConfigEntry* getEntry(const String &key) const;
+ std::vector<const ConfigEntry*> getEntries(const String &key) const;
+
+ std::vector<String> getAll(const String &key) const;
+ String get(const String &key, const String &defaultValue = String()) const;
};
}
diff --git a/src/Core/ConfigManager.cpp b/src/Core/ConfigManager.cpp
index fdbc93f..1cb4aa0 100644
--- a/src/Core/ConfigManager.cpp
+++ b/src/Core/ConfigManager.cpp
@@ -38,28 +38,16 @@ bool ConfigManager::Compare::operator() (const Configurable *c1, const Configura
return c1 < c2;
}
-
-void ConfigManager::handleConfigEntry(const ConfigEntry &entry) {
- bool handled = false;
-
- for(std::set<Configurable*, Compare>::iterator c = configurables.begin(); c != configurables.end(); ++c) {
- if((*c)->handleConfigEntry(entry, handled))
- handled = true;
- }
-
- if(!handled)
- application->logf(Logger::LOG_WARNING, "Invalid config option '%s'.", entry[entry.getSize()-1].getKey().toLocale().c_str());
-}
-
bool ConfigManager::loadFile(const std::string &filename) {
- if(finished)
+ if(configured)
return false;
std::ifstream file(filename.c_str());
- ConfigEntry entry;
+ ConfigEntry *currentEntry = this;
+ ConfigEntry *lastEntry = this;
String line, input;
UChar delim;
- std::vector<String> splitLine, lastConfigLine;
+ std::vector<String> splitLine;
if(!file.good())
return false;
@@ -90,11 +78,9 @@ bool ConfigManager::loadFile(const std::string &filename) {
}
if(!splitLine.empty()) {
- entry.push(splitLine);
- handleConfigEntry(entry);
- entry.pop();
-
- lastConfigLine = splitLine;
+ boost::shared_ptr<ConfigEntry> entry(new ConfigEntry(currentEntry, std::vector<String>(splitLine.begin()+1, splitLine.end())));
+ currentEntry->addChild(splitLine.front(), entry);
+ lastEntry = entry.get();
}
switch(delim) {
@@ -102,10 +88,10 @@ bool ConfigManager::loadFile(const std::string &filename) {
input.remove();
break;
case '{':
- entry.push(lastConfigLine);
+ currentEntry = lastEntry;
break;
case '}':
- entry.pop();
+ lastEntry = currentEntry = currentEntry->getParent();
}
line.remove();
@@ -116,14 +102,14 @@ bool ConfigManager::loadFile(const std::string &filename) {
return true;
}
-void ConfigManager::finish() {
- if(finished)
+void ConfigManager::configure() {
+ if(configured)
return;
for(std::set<Configurable*, Compare>::iterator c = configurables.begin(); c != configurables.end(); ++c)
- (*c)->configFinished();
+ (*c)->configure();
- finished = true;
+ configured = true;
}
}
diff --git a/src/Core/ConfigManager.h b/src/Core/ConfigManager.h
index 10b378d..2c11de9 100644
--- a/src/Core/ConfigManager.h
+++ b/src/Core/ConfigManager.h
@@ -22,6 +22,8 @@
#include "export.h"
+#include "ConfigEntry.h"
+
#include <memory>
#include <set>
#include <string>
@@ -30,10 +32,9 @@ namespace Mad {
namespace Core {
class Application;
-class ConfigEntry;
class Configurable;
-class MAD_CORE_EXPORT ConfigManager {
+class MAD_CORE_EXPORT ConfigManager : public ConfigEntry {
private:
struct MAD_CORE_EXPORT Compare {
bool operator() (const Configurable *c1, const Configurable *c2);
@@ -44,15 +45,13 @@ class MAD_CORE_EXPORT ConfigManager {
Application *application;
std::set<Configurable*, Compare> configurables;
- bool finished;
-
- ConfigManager(Application *application0) : application(application0), finished(false) {}
+ bool configured;
- void handleConfigEntry(const ConfigEntry &entry);
+ ConfigManager(Application *application0) : application(application0), configured(false) {}
public:
bool loadFile(const std::string &filename);
- void finish();
+ void configure();
void registerConfigurable(Configurable *c) {
configurables.insert(c);
diff --git a/src/Core/Configurable.h b/src/Core/Configurable.h
index c526379..1c41220 100644
--- a/src/Core/Configurable.h
+++ b/src/Core/Configurable.h
@@ -23,7 +23,6 @@
namespace Mad {
namespace Core {
-class ConfigEntry;
class ConfigManager;
class Configurable {
@@ -37,8 +36,7 @@ class Configurable {
Configurable() {}
- virtual bool handleConfigEntry(const ConfigEntry& /*entry*/, bool /*handled*/) {return false;}
- virtual void configFinished() {}
+ virtual void configure() = 0;
};
}
diff --git a/src/Core/LogManager.cpp b/src/Core/LogManager.cpp
index 7282009..955ac76 100644
--- a/src/Core/LogManager.cpp
+++ b/src/Core/LogManager.cpp
@@ -53,17 +53,17 @@ LogManager::MessageLevel LogManager::parseLevel(const String &str) throw (Except
if(str.isEmpty())
return Logger::LOG_DEFAULT;
- if(str.caseCompare(DEBUG_LEVEL, 0) == 0)
+ if(str.matches(DEBUG_LEVEL))
return Logger::LOG_DEBUG;
- else if(str.caseCompare(VERBOSE_LEVEL, 0) == 0)
+ else if(str.matches(VERBOSE_LEVEL))
return Logger::LOG_VERBOSE;
- else if(str.caseCompare(DEFAULT_LEVEL, 0) == 0)
+ else if(str.matches(DEFAULT_LEVEL))
return Logger::LOG_DEFAULT;
- else if(str.caseCompare(WARNING_LEVEL, 0) == 0)
+ else if(str.matches(WARNING_LEVEL))
return Logger::LOG_WARNING;
- else if(str.caseCompare(ERROR_LEVEL, 0) == 0)
+ else if(str.matches(ERROR_LEVEL))
return Logger::LOG_ERROR;
- else if(str.caseCompare(CRITICAL_LEVEL, 0) == 0)
+ else if(str.matches(CRITICAL_LEVEL))
return Logger::LOG_CRITICAL;
else
throw Exception(Exception::INVALID_INPUT);
@@ -79,41 +79,37 @@ LogManager::~LogManager() {
}
-bool LogManager::handleConfigEntry(const ConfigEntry &entry, bool handled) {
- if(entry[0].getKey().matches("Log")) {
- if(entry[0][0].matches("Console")) {
- if(entry[1].isEmpty()) {
- registerLogger(consoleLogger);
- return true;
- }
- else if(entry[1].getKey().matches("Level")) {
- if(entry[2].isEmpty()) {
- try {
- if(entry[1][0].matches("remote"))
- consoleLogger->setRemoteLevel(parseLevel(entry[1][1]));
- else
- consoleLogger->setLevel(parseLevel(entry[1][0]));
- }
- catch(Core::Exception e) {
- application->logf(Logger::LOG_WARNING, "Unknown log level '%s'.", entry[1][0].toLocale().c_str());
- }
-
- return true;
- }
- }
+void LogManager::configure() {
+ std::vector<const ConfigEntry*> entries = application->getConfigManager()->getEntries("Log");
+
+ for(std::vector<const ConfigEntry*>::iterator entry = entries.begin(); entry != entries.end(); ++entry) {
+ const std::vector<String> &values = (*entry)->getValues();
+
+ if(values.empty() || !values.front().matches("Console"))
+ continue;
+
+ registerLogger(consoleLogger);
+
+ bool remote = false;
+ for(std::vector<String>::const_iterator value = values.begin()+1; value != values.end(); ++value) {
+ if(value->matches("remote"))
+ remote = true;
}
- else if(entry[1].isEmpty()) {
- if(!handled) {
- application->logf(Logger::LOG_WARNING, "Unknown logger '%s'.", entry[0][0].toLocale().c_str());
- return true;
+
+ String level = (*entry)->get("Level");
+ if(!level.isEmpty()) {
+ try {
+ if(remote)
+ consoleLogger->setRemoteLevel(parseLevel(level));
+ else
+ consoleLogger->setLevel(parseLevel(level));
+ }
+ catch(Core::Exception e) {
+ application->logf(Logger::LOG_WARNING, "Unknown log level '%s'.", level.toLocale().c_str());
}
}
}
- return false;
-}
-
-void LogManager::configFinished() {
if(loggers.empty())
registerLogger(consoleLogger);
diff --git a/src/Core/LogManager.h b/src/Core/LogManager.h
index a1f3d7d..5de38a9 100644
--- a/src/Core/LogManager.h
+++ b/src/Core/LogManager.h
@@ -96,8 +96,7 @@ class MAD_CORE_EXPORT LogManager : public Configurable {
~LogManager();
protected:
- virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled);
- virtual void configFinished();
+ virtual void configure();
public:
static MessageLevel parseLevel(const String &str) throw (Exception);