Go to the documentation of this file.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 
00065 
00066 public:
00067         ConfigFile( string filename,
00068                     string delimiter = "=",
00069                     string comment = "#",
00070                                 string sentry = "EndConfigFile" );
00071         ConfigFile();
00072         
00073         
00074         template<class T> T read( const string& key ) const;  
00075         template<class T> T read( const string& key, const T& value ) const;
00076         template<class T> bool readInto( T& var, const string& key ) const;
00077         template<class T>
00078         bool readInto( T& var, const string& key, const T& value ) const;
00079         
00080         
00081         template<class T> void add( string key, const T& value );
00082         void remove( const string& key );
00083         
00084         
00085         bool keyExists( const string& key ) const;
00086         
00087         
00088         string getDelimiter() const { return myDelimiter; }
00089         string getComment() const { return myComment; }
00090         string getSentry() const { return mySentry; }
00091         string setDelimiter( const string& s )
00092                 { string old = myDelimiter;  myDelimiter = s;  return old; }  
00093         string setComment( const string& s )
00094                 { string old = myComment;  myComment = s;  return old; }
00095         
00096         
00097         friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf );
00098         friend std::istream& operator>>( std::istream& is, ConfigFile& cf );
00099         
00100 protected:
00101         template<class T> static string T_as_string( const T& t );
00102         template<class T> static T string_as_T( const string& s );
00103         static void trim( string& s );
00104 
00105 
00106 
00107 public:
00108         struct file_not_found {
00109                 string filename;
00110                 file_not_found( const string& filename_ = string() )
00111                         : filename(filename_) {} };
00112         struct key_not_found {  
00113                 string key;
00114                 key_not_found( const string& key_ = string() )
00115                         : key(key_) {} };
00116 };
00117 
00118 
00119 
00120 template<class T>
00121 string ConfigFile::T_as_string( const T& t )
00122 {
00123         
00124         
00125         std::ostringstream ost;
00126         ost << t;
00127         return ost.str();
00128 }
00129 
00130 
00131 
00132 template<class T>
00133 T ConfigFile::string_as_T( const string& s )
00134 {
00135         
00136         
00137         T t;
00138         std::istringstream ist(s);
00139         ist >> t;
00140         return t;
00141 }
00142 
00143 
00144 
00145 template<>
00146 inline string ConfigFile::string_as_T<string>( const string& s )
00147 {
00148         
00149         
00150         return s;
00151 }
00152 
00153 
00154 
00155 template<>
00156 inline bool ConfigFile::string_as_T<bool>( const string& s )
00157 {
00158         
00159         
00160         
00161         bool b = true;
00162         string sup = s;
00163         for( string::iterator p = sup.begin(); p != sup.end(); ++p )
00164                 *p = toupper(*p);  
00165         if( sup==string("FALSE") || sup==string("F") ||
00166             sup==string("NO") || sup==string("N") ||
00167             sup==string("0") || sup==string("NONE") )
00168                 b = false;
00169         return b;
00170 }
00171 
00172 
00173 template<class T>
00174 T ConfigFile::read( const string& key ) const
00175 {
00176         
00177         mapci p = myContents.find(key);
00178         if( p == myContents.end() ) throw key_not_found(key);
00179         return string_as_T<T>( p->second );
00180 }
00181 
00182 
00183 template<class T>
00184 T ConfigFile::read( const string& key, const T& value ) const
00185 {
00186         
00187         
00188         mapci p = myContents.find(key);
00189         if( p == myContents.end() ) return value;
00190         return string_as_T<T>( p->second );
00191 }
00192 
00193 
00194 template<class T>
00195 bool ConfigFile::readInto( T& var, const string& key ) const
00196 {
00197         
00198         
00199         
00200         mapci p = myContents.find(key);
00201         bool found = ( p != myContents.end() );
00202         if( found ) var = string_as_T<T>( p->second );
00203         return found;
00204 }
00205 
00206 
00207 template<class T>
00208 bool ConfigFile::readInto( T& var, const string& key, const T& value ) const
00209 {
00210         
00211         
00212         
00213         mapci p = myContents.find(key);
00214         bool found = ( p != myContents.end() );
00215         if( found )
00216                 var = string_as_T<T>( p->second );
00217         else
00218                 var = value;
00219         return found;
00220 }
00221 
00222 
00223 template<class T>
00224 void ConfigFile::add( string key, const T& value )
00225 {
00226         
00227         string v = T_as_string( value );
00228         trim(key);
00229         trim(v);
00230         myContents[key] = v;
00231         return;
00232 }
00233 
00234 #endif  // CONFIGFILE_H
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253