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