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