00001 #ifndef __AppConfig__
00002 #define __AppConfig__
00003
00004 #include <exception>
00005 #include <string>
00006 #include <sstream>
00007 #include <map>
00008
00009 #include "SharedResource.h"
00010
00011
00012 class AppConfig : private SharedResource {
00013 public:
00014 class InvalidEntryException : public std::exception {
00015 public:
00016 virtual const char* what() const throw() {
00017 return "Section and/or attribute not found in .ini file.";
00018 }
00019 };
00020
00021 static AppConfig& instance();
00022
00023 const char* getFileName() const;
00024
00025
00026 template <class T> T get(const char* section, const char* attribute)
00027 {
00028 lock();
00029
00030 std::map<std::string, std::map<std::string, std::string>>::iterator iSection = _entries.find(section);
00031
00032 if (iSection == _entries.end()) {
00033 unlock();
00034 throw InvalidEntryException();
00035 }
00036
00037 std::map<std::string, std::string>::iterator iAttribute = iSection->second.find(attribute);
00038
00039 if (iAttribute == iSection->second.end()) {
00040 unlock();
00041 throw InvalidEntryException();
00042 }
00043
00044 if (typeid(T) == typeid(std::string)) {
00045 std::string result = iAttribute->second;
00046 std::string* ptr = &result;
00047
00048 unlock();
00049 return *(reinterpret_cast<T*>(ptr));
00050 }
00051 else {
00052 std::stringstream stream;
00053 stream << iAttribute->second;
00054
00055 T value;
00056 stream >> value;
00057
00058 unlock();
00059 return value;
00060 }
00061 }
00062
00063 template <class T> void set(const char* section, const char* attribute, T& value)
00064 {
00065 lock();
00066
00067 std::stringstream stream;
00068 stream << value;
00069
00070 std::map<std::string, std::map<std::string, std::string>>::iterator iSection = _entries.find(section);
00071
00072 if (iSection == _entries.end()) {
00073 std::map<std::string, std::string> newSection;
00074 newSection.insert(std::pair<std::string, std::string>(attribute, stream.str()));
00075
00076 _entries.insert(std::pair<std::string, std::map<std::string, std::string>>(section, newSection));
00077 }
00078 else {
00079 std::map<std::string, std::string>::iterator iAttribute = iSection->second.find(attribute);
00080
00081 if (iAttribute == iSection->second.end()) {
00082 iSection->second.insert(std::pair<std::string, std::string>(attribute, stream.str()));
00083 }
00084 else {
00085 iAttribute->second = stream.str();
00086 }
00087 }
00088
00089 _writeFile(_fileName.c_str());
00090 _readFile(_fileName.c_str());
00091
00092 unlock();
00093 }
00094
00095 template <class T> void set(const char* section, const char* attribute, T value)
00096 {
00097 lock();
00098
00099 std::stringstream stream;
00100 stream << value;
00101
00102 std::map<std::string, std::map<std::string, std::string>>::iterator iSection = _entries.find(section);
00103
00104 if (iSection == _entries.end()) {
00105 std::map<std::string, std::string> newSection;
00106 newSection.insert(std::pair<std::string, std::string>(attribute, stream.str()));
00107
00108 _entries.insert(std::pair<std::string, std::map<std::string, std::string>>(section, newSection));
00109 }
00110 else {
00111 std::map<std::string, std::string>::iterator iAttribute = iSection->second.find(attribute);
00112
00113 if (iAttribute == iSection->second.end()) {
00114 iSection->second.insert(std::pair<std::string, std::string>(attribute, stream.str()));
00115 }
00116 else {
00117 iAttribute->second = stream.str();
00118 }
00119 }
00120
00121 _writeFile(_fileName.c_str());
00122 _readFile(_fileName.c_str());
00123
00124 unlock();
00125 }
00126
00127
00128 private:
00129 AppConfig();
00130
00131 void _readFile(const char* fileName);
00132 void _writeFile(const char* fileName);
00133
00134 std::string _fileName;
00135 std::map<std::string, std::map<std::string, std::string>> _entries;
00136 };
00137
00138
00139
00140
00141 #endif