ConfigFile.cpp

Go to the documentation of this file.
00001 // ConfigFile.cpp
00002 
00003 #include "ConfigFile.h"
00004 
00005 using std::string;
00006 
00007 ConfigFile::ConfigFile( string filename, bool isList,string delimiter,
00008                         string comment, string sentry )
00009   : myDelimiter(delimiter), myComment(comment), mySentry(sentry),file(filename),listmode(isList)
00010 {
00011         // Construct a ConfigFile, getting keys and values from given file
00012         
00013         std::ifstream in( filename.c_str() );
00014         
00015         if( !in ) throw file_not_found( filename ); 
00016         
00017         in >> (*this);
00018 }
00019 
00020 
00021 ConfigFile::ConfigFile()
00022   : myDelimiter( string(1,'=') ), myComment( string(2,'#') ),listmode(false)
00023 {
00024         // Construct a ConfigFile without a file; empty
00025 }
00026 
00027 // Construct the ConfigFile from a given file if its present
00028 void ConfigFile::load(string filename,bool isList)
00029 {
00030  file=filename;
00031  listmode=isList;
00032  std::ifstream in( filename.c_str() );
00033  if( in ) 
00034    in>>(*this);
00035  in.close(); 
00036 }
00037 
00038 // Save the ConfigFile into a given file
00039 void ConfigFile::save()
00040 {
00041  std::ofstream out( file.c_str() );
00042  if( !out ) throw file_not_found( file ); 
00043  out<<(*this); 
00044  out.close();
00045 }
00046 
00047 void ConfigFile::remove( const string& key )
00048 {
00049         // Remove key and its value
00050         myContents.erase( myContents.find( key ) );
00051         return;
00052 }
00053 
00054 
00055 bool ConfigFile::keyExists( const string& key ) const
00056 {
00057         // Indicate whether key is found
00058         mapci p = myContents.find( key );
00059         return ( p != myContents.end() );
00060 }
00061 
00062 
00063 /* static */
00064 void ConfigFile::trim( string& s )
00065 {
00066         // Remove leading and trailing whitespace
00067         static const char whitespace[] = " \n\t\v\r\f";
00068         s.erase( 0, s.find_first_not_of(whitespace) );
00069         s.erase( s.find_last_not_of(whitespace) + 1U );
00070 }
00071 
00072 
00073 std::ostream& operator<<( std::ostream& os, const ConfigFile& cf )
00074 {
00075         // Save a ConfigFile to os
00076         for( ConfigFile::mapci p = cf.myContents.begin();
00077              p != cf.myContents.end();
00078                  ++p )
00079         {
00080                 os << p->first << " " ;
00081                 if(!cf.listmode)
00082                   {
00083                     os<<cf.myDelimiter << " ";
00084                     os << p->second ;
00085                   } 
00086                 os<<std::endl;
00087         }
00088         return os;
00089 }
00090 
00091 
00092 std::istream& operator>>( std::istream& is, ConfigFile& cf )
00093 {
00094         // Load a ConfigFile from is
00095         // Read in keys and values, keeping internal whitespace
00096         typedef string::size_type pos;
00097         const string& delim  = cf.myDelimiter;  // separator
00098         const string& comm   = cf.myComment;    // comment
00099         const string& sentry = cf.mySentry;     // end of file sentry
00100         const pos skip = delim.length();        // length of separator
00101         
00102         string nextline = "";  // might need to read ahead to see where value ends
00103         
00104         while( is || nextline.length() > 0 )
00105         {
00106                 // Read an entire line at a time
00107                 string line;
00108                 if( nextline.length() > 0 )
00109                 {
00110                         line = nextline;  // we read ahead; use it now
00111                         nextline = "";
00112                 }
00113                 else
00114                 {
00115                         std::getline( is, line );
00116                 }
00117                 
00118                 // Ignore comments
00119                 line = line.substr( 0, line.find(comm) );
00120                 
00121                 // Check for end of file sentry
00122                 if( sentry != "" && line.find(sentry) != string::npos ) return is;
00123                 
00124                 // Parse the line if it contains a delimiter
00125                 pos delimPos = line.find( delim );
00126                 if( delimPos < string::npos )
00127                 {
00128                         // Extract the key
00129                         string key = line.substr( 0, delimPos );
00130                         line.replace( 0, delimPos+skip, "" );
00131                         
00132                         // See if value continues on the next line
00133                         // Stop at blank line, next line with a key, end of stream,
00134                         // or end of file sentry
00135                         bool terminate = false;
00136                         while( !terminate && is )
00137                         {
00138                                 std::getline( is, nextline );
00139                                 terminate = true;
00140                                 
00141                                 string nlcopy = nextline;
00142                                 ConfigFile::trim(nlcopy);
00143                                 if( nlcopy == "" ) continue;
00144                                 
00145                                 nextline = nextline.substr( 0, nextline.find(comm) );
00146                                 if( nextline.find(delim) != string::npos )
00147                                         continue;
00148                                 if( sentry != "" && nextline.find(sentry) != string::npos )
00149                                         continue;
00150                                 
00151                                 nlcopy = nextline;
00152                                 ConfigFile::trim(nlcopy);
00153                                 if( nlcopy != "" ) line += "\n";
00154                                 line += nextline;
00155                                 terminate = false;
00156                         }
00157                         
00158                         // Store key and value
00159                         ConfigFile::trim(key);
00160                         ConfigFile::trim(line);
00161                         cf.myContents[key] = line;  // overwrites if key is repeated
00162                 }
00163                 else if(cf.listmode)
00164                 {
00165                   ConfigFile::trim(line);
00166                   cf.myContents[line]=" ";
00167                 }
00168         }
00169         
00170         return is;
00171 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by  doxygen 1.6.2