CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/Validation/RecoJets/src/ConfigFile.cc

Go to the documentation of this file.
00001 // ConfigFile.cpp
00002 
00003 #include "Validation/RecoJets/interface/ConfigFile.h"
00004 
00005 using std::string;
00006 
00007 ConfigFile::ConfigFile( std::string filename, std::string delimiter,
00008                         std::string comment, std::string sentry )
00009         : myDelimiter(delimiter), myComment(comment), mySentry(sentry)
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( std::string(1,'=') ), myComment( std::string(1,'#') )
00023 {
00024         // Construct a ConfigFile without a file; empty
00025 }
00026 
00027 
00028 void ConfigFile::remove( const std::string& key )
00029 {
00030         // Remove key and its value
00031         myContents.erase( myContents.find( key ) );
00032         return;
00033 }
00034 
00035 
00036 bool ConfigFile::keyExists( const std::string& key ) const
00037 {
00038         // Indicate whether key is found
00039         mapci p = myContents.find( key );
00040         return ( p != myContents.end() );
00041 }
00042 
00043 
00044 /* static */
00045 void ConfigFile::trim( std::string& s )
00046 {
00047         // Remove leading and trailing whitespace
00048         static const char whitespace[] = " \n\t\v\r\f";
00049         s.erase( 0, s.find_first_not_of(whitespace) );
00050         s.erase( s.find_last_not_of(whitespace) + 1U );
00051 }
00052 
00053 
00054 std::ostream& operator<<( std::ostream& os, const ConfigFile& cf )
00055 {
00056         // Save a ConfigFile to os
00057         for( ConfigFile::mapci p = cf.myContents.begin();
00058              p != cf.myContents.end();
00059                  ++p )
00060         {
00061                 os << p->first << " " << cf.myDelimiter << " ";
00062                 os << p->second << std::endl;
00063         }
00064         return os;
00065 }
00066 
00067 
00068 std::istream& operator>>( std::istream& is, ConfigFile& cf )
00069 {
00070         // Load a ConfigFile from is
00071         // Read in keys and values, keeping internal whitespace
00072         typedef std::string::size_type pos;
00073         const std::string& delim  = cf.myDelimiter;  // separator
00074         const std::string& comm   = cf.myComment;    // comment
00075         const std::string& sentry = cf.mySentry;     // end of file sentry
00076         const pos skip = delim.length();        // length of separator
00077         
00078         string nextline = "";  // might need to read ahead to see where value ends
00079         
00080         while( is || nextline.length() > 0 )
00081         {
00082                 // Read an entire line at a time
00083                 string line;
00084                 if( nextline.length() > 0 )
00085                 {
00086                         line = nextline;  // we read ahead; use it now
00087                         nextline = "";
00088                 }
00089                 else
00090                 {
00091                         std::getline( is, line );
00092                 }
00093                 
00094                 // Ignore comments
00095                 line = line.substr( 0, line.find(comm) );
00096                 
00097                 // Check for end of file sentry
00098                 if( sentry != "" && line.find(sentry) != std::string::npos ) return is;
00099                 
00100                 // Parse the line if it contains a delimiter
00101                 pos delimPos = line.find( delim );
00102                 if( delimPos < std::string::npos )
00103                 {
00104                         // Extract the key
00105                         string key = line.substr( 0, delimPos );
00106                         line.replace( 0, delimPos+skip, "" );
00107                         
00108                         // See if value continues on the next line
00109                         // Stop at blank line, next line with a key, end of stream,
00110                         // or end of file sentry
00111                         bool terminate = false;
00112                         while( !terminate && is )
00113                         {
00114                                 std::getline( is, nextline );
00115                                 terminate = true;
00116                                 
00117                                 string nlcopy = nextline;
00118                                 ConfigFile::trim(nlcopy);
00119                                 if( nlcopy == "" ) continue;
00120                                 
00121                                 nextline = nextline.substr( 0, nextline.find(comm) );
00122                                 if( nextline.find(delim) != std::string::npos )
00123                                         continue;
00124                                 if( sentry != "" && nextline.find(sentry) != std::string::npos )
00125                                         continue;
00126                                 
00127                                 nlcopy = nextline;
00128                                 ConfigFile::trim(nlcopy);
00129                                 if( nlcopy != "" ) line += "\n";
00130                                 line += nextline;
00131                                 terminate = false;
00132                         }
00133                         
00134                         // Store key and value
00135                         ConfigFile::trim(key);
00136                         ConfigFile::trim(line);
00137                         cf.myContents[key] = line;  // overwrites if key is repeated
00138                 }
00139         }
00140         
00141         return is;
00142 }