|
Fimbulwinter Project
Pre-Alpha
An Ragnarok Online Emulator
|
00001 /*==================================================================* 00002 * ___ _ _ _ _ _ * 00003 * / __(_)_ __ ___ | |__ _ _| |_ _(_)_ __ | |_ ___ _ __ * 00004 * / _\ | | '_ ` _ \| '_ \| | | | \ \ /\ / / | '_ \| __/ _ \ '__| * 00005 * / / | | | | | | | |_) | |_| | |\ V V /| | | | | || __/ | * 00006 * \/ |_|_| |_| |_|_.__/ \__,_|_| \_/\_/ |_|_| |_|\__\___|_| * 00007 * * 00008 * ------------------------------------------------------------------* 00009 * Emulator * 00010 * ------------------------------------------------------------------* 00011 * Licenced under GNU GPL v3 * 00012 * ----------------------------------------------------------------- * 00013 * Configuration Files Modules * 00014 * ==================================================================*/ 00015 00016 #pragma once 00017 00018 #include <string> 00019 #include <map> 00020 #include <iostream> 00021 #include <fstream> 00022 #include <sstream> 00023 00024 using std::string; 00025 00026 class config_file 00027 { 00028 protected: 00029 string delimiter_; 00030 string comment_; 00031 string sentry_; 00032 std::map<string,string> contents_; 00033 00034 typedef std::map<string,string>::iterator mapi; 00035 typedef std::map<string,string>::const_iterator mapci; 00036 00037 public: 00038 config_file(string filename, 00039 string delimiter = "=", 00040 string comment = "#", 00041 string sentry = "EndConfigFile"); 00042 config_file(); 00043 00044 template<class T> T read(const string& key) const; 00045 template<class T> T read(const string& key, const T& value) const; 00046 template<class T> bool read_into(T& var, const string& key) const; 00047 template<class T> 00048 bool read_into(T& var, const string& key, const T& value) const; 00049 00050 template<class T> void add(string key, const T& value); 00051 void remove(const string& key); 00052 00053 bool key_exists(const string& key) const; 00054 00055 string get_delimiter() const { return delimiter_; } 00056 string get_comment() const { return comment_; } 00057 string get_sentry() const { return sentry_; } 00058 string set_delimiter(const string& s) 00059 { string old = delimiter_; delimiter_ = s; return old; } 00060 string set_comment(const string& s) 00061 { string old = comment_; comment_ = s; return old; } 00062 00063 friend std::ostream& operator<<(std::ostream& os, const config_file& cf); 00064 friend std::istream& operator>>(std::istream& is, config_file& cf); 00065 00066 protected: 00067 template<class T> static string T_as_string(const T& t); 00068 template<class T> static T string_as_T(const string& s); 00069 00070 public: 00071 static void trim(string& s); 00072 00073 struct file_not_found 00074 { 00075 string filename; 00076 file_not_found(const string& filename_ = string()) 00077 : filename(filename_) {} 00078 }; 00079 struct key_not_found 00080 { 00081 string key; 00082 key_not_found(const string& key_ = string()) 00083 : key(key_) {} 00084 }; 00085 }; 00086 00087 template<class T> 00088 string config_file::T_as_string(const T& t) 00089 { 00090 std::ostringstream ost; 00091 ost << t; 00092 return ost.str(); 00093 } 00094 00095 template<class T> 00096 T config_file::string_as_T(const string& s) 00097 { 00098 T t; 00099 std::istringstream ist(s); 00100 ist >> t; 00101 return t; 00102 } 00103 00104 template<> 00105 inline string config_file::string_as_T<string>(const string& s) 00106 { 00107 return s; 00108 } 00109 00110 template<> 00111 inline char *config_file::string_as_T<char*>(const string& s) 00112 { 00113 return (char*)s.c_str(); 00114 } 00115 00116 template<> 00117 inline bool config_file::string_as_T<bool>(const string& s) 00118 { 00119 bool b = true; 00120 string sup = s; 00121 for(string::iterator p = sup.begin(); p != sup.end(); ++p) 00122 *p = toupper(*p); 00123 if(sup==string("FALSE") || sup==string("F") || 00124 sup==string("NO") || sup==string("N") || 00125 sup==string("0") || sup==string("NONE")) 00126 b = false; 00127 return b; 00128 } 00129 00130 00131 template<class T> 00132 T config_file::read(const string& key) const 00133 { 00134 mapci p = contents_.find(key); 00135 if(p == contents_.end()) throw key_not_found(key); 00136 return string_as_T<T>(p->second); 00137 } 00138 00139 00140 template<class T> 00141 T config_file::read(const string& key, const T& value) const 00142 { 00143 mapci p = contents_.find(key); 00144 if(p == contents_.end()) return value; 00145 return string_as_T<T>(p->second); 00146 } 00147 00148 00149 template<class T> 00150 bool config_file::read_into(T& var, const string& key) const 00151 { 00152 mapci p = contents_.find(key); 00153 bool found = (p != contents_.end()); 00154 if(found) var = string_as_T<T>(p->second); 00155 return found; 00156 } 00157 00158 00159 template<class T> 00160 bool config_file::read_into(T& var, const string& key, const T& value) const 00161 { 00162 mapci p = contents_.find(key); 00163 bool found = (p != contents_.end()); 00164 if(found) 00165 var = string_as_T<T>(p->second); 00166 else 00167 var = value; 00168 return found; 00169 } 00170 00171 00172 template<class T> 00173 void config_file::add(string key, const T& value) 00174 { 00175 string v = T_as_string(value); 00176 trim(key); 00177 trim(v); 00178 contents_[key] = v; 00179 return; 00180 }
1.7.6.1