00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef CONFIGFILE_H
00044 #define CONFIGFILE_H
00045
00046 #include <string>
00047 #include <map>
00048 #include <iostream>
00049 #include <fstream>
00050 #include <sstream>
00051
00052 using std::string;
00053
00054 class ConfigFile {
00055
00056 protected:
00057 string myDelimiter;
00058 string myComment;
00059 string mySentry;
00060 std::map<string,string> myContents;
00061
00062 typedef std::map<string,string>::iterator mapi;
00063 typedef std::map<string,string>::const_iterator mapci;
00064 std::string file;
00065 bool listmode;
00066
00067
00068 public:
00069 ConfigFile( string filename,
00070 bool isList=false,
00071 string delimiter = "=",
00072 string comment = "##",
00073 string sentry = "EndConfigFile"
00074 );
00075 ConfigFile();
00076
00077
00078 template<class T> T read( const string& key ) const;
00079 template<class T> T read( const string& key, const T& value ) const;
00080 template<class T> bool readInto( T& var, const string& key ) const;
00081 template<class T>
00082 bool readInto( T& var, const string& key, const T& value ) const;
00083
00084
00085 template<class T> void add( string key, const T& value ,bool store=false);
00086 template<class T> void add( const T& key ,bool store=false);
00087 void remove( const string& key );
00088 template<class T>void remove( const T& key );
00089
00090
00091 bool keyExists( const string& key ) const;
00092 template<class T> bool keyExists(const T & key) const;
00093
00094
00095 string getDelimiter() const { return myDelimiter; }
00096 string getComment() const { return myComment; }
00097 string getSentry() const { return mySentry; }
00098 string setDelimiter( const string& s )
00099 { string old = myDelimiter; myDelimiter = s; return old; }
00100 string setComment( const string& s )
00101 { string old = myComment; myComment = s; return old; }
00102
00103
00104 friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf );
00105 friend std::istream& operator>>( std::istream& is, ConfigFile& cf );
00106
00107 void load(string filename,bool isList=false);
00108 void save();
00109
00110 protected:
00111 template<class T> static string T_as_string( const T& t );
00112 template<class T> static T string_as_T( const string& s );
00113 static void trim( string& s );
00114
00115
00116
00117 public:
00118 struct file_not_found {
00119 string filename;
00120 file_not_found( const string& filename_ = string() )
00121 : filename(filename_) {} };
00122 struct key_not_found {
00123 string key;
00124 key_not_found( const string& key_ = string() )
00125 : key(key_) {} };
00126 };
00127
00128
00129
00130 template<class T>
00131 string ConfigFile::T_as_string( const T& t )
00132 {
00133
00134
00135 std::ostringstream ost;
00136 ost << t;
00137 return ost.str();
00138 }
00139
00140
00141
00142 template<class T>
00143 T ConfigFile::string_as_T( const string& s )
00144 {
00145
00146
00147 T t;
00148 std::istringstream ist(s);
00149 ist >> t;
00150 return t;
00151 }
00152
00153
00154
00155 template<>
00156 inline string ConfigFile::string_as_T<string>( const string& s )
00157 {
00158
00159
00160 return s;
00161 }
00162
00163
00164
00165 template<>
00166 inline bool ConfigFile::string_as_T<bool>( const string& s )
00167 {
00168
00169
00170
00171 bool b = true;
00172 string sup = s;
00173 for( string::iterator p = sup.begin(); p != sup.end(); ++p )
00174 *p = toupper(*p);
00175 if( sup==string("FALSE") || sup==string("F") ||
00176 sup==string("NO") || sup==string("N") ||
00177 sup==string("0") || sup==string("NONE") )
00178 b = false;
00179 return b;
00180 }
00181
00182
00183 template<class T>
00184 T ConfigFile::read( const string& key ) const
00185 {
00186
00187 mapci p = myContents.find(key);
00188 if( p == myContents.end() ) throw key_not_found(key);
00189 return string_as_T<T>( p->second );
00190 }
00191
00192
00193 template<class T>
00194 T ConfigFile::read( const string& key, const T& value ) const
00195 {
00196
00197
00198 mapci p = myContents.find(key);
00199 if( p == myContents.end() ) return value;
00200 return string_as_T<T>( p->second );
00201 }
00202
00203
00204 template<class T>
00205 bool ConfigFile::readInto( T& var, const string& key ) const
00206 {
00207
00208
00209
00210 mapci p = myContents.find(key);
00211 bool found = ( p != myContents.end() );
00212 if( found ) var = string_as_T<T>( p->second );
00213 return found;
00214 }
00215
00216
00217 template<class T>
00218 bool ConfigFile::readInto( T& var, const string& key, const T& value ) const
00219 {
00220
00221
00222
00223 mapci p = myContents.find(key);
00224 bool found = ( p != myContents.end() );
00225 if( found )
00226 var = string_as_T<T>( p->second );
00227 else
00228 var = value;
00229 return found;
00230 }
00231
00232
00233 template<class T>
00234 void ConfigFile::add( string key, const T& value ,bool store)
00235 {
00236
00237 string v = T_as_string( value );
00238 trim(key);
00239 trim(v);
00240 myContents[key] = v;
00241 if (store)
00242 {
00243
00244 std::ofstream os(file.c_str(),std::ios::app);
00245 os << key << " " << myDelimiter << " ";
00246 os << v << std::endl;
00247 os.close();
00248 }
00249 return;
00250 }
00251
00252 template<class T>
00253 void ConfigFile::add( const T& key ,bool store)
00254 {
00255 if(keyExists(key))
00256 return;
00257 string v = T_as_string( key );
00258 trim(v);
00259 myContents[v] = " ";
00260 if(store)
00261 {
00262 std::ofstream os(file.c_str(),std::ios::app);
00263 os << v << std::endl;
00264 os.close();
00265 }
00266
00267 }
00268
00269 template<class T>
00270 void ConfigFile::remove( const T& key )
00271 {
00272 if(keyExists(key))
00273 return;
00274 string v = T_as_string( key );
00275 trim(v);
00276 myContents.erase( myContents.find( v ) );
00277 save();
00278
00279 }
00280 template<class T>
00281 bool ConfigFile::keyExists(const T & key) const
00282 {
00283
00284 string v = T_as_string( key );
00285 mapci p = myContents.find( v );
00286 return ( p != myContents.end() );
00287
00288 }
00289 #endif // CONFIGFILE_H
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308