wsdlpull
1.23
|
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 }