LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
ConfigFile.cc
Go to the documentation of this file.
1 
3 
4 namespace lsst {
5 namespace meas {
6 namespace algorithms {
7 namespace shapelet {
8 
10  _delimiter("="), _comment("#"), _include("+"), _sentry("EndConfigFile")
11 {
12  // Construct an empty ConfigFile
13 }
14 
16  const std::string fileName, const std::string delimiter,
17  const std::string comment, const std::string inc, const std::string sentry ) :
18  _delimiter(delimiter), _comment(comment), _include(inc), _sentry(sentry)
19 {
20  // Construct a ConfigFile, getting keys and values from given file
21 
22  std::ifstream in( fileName.c_str() );
23 
24  if( !in ) {
25 #ifdef NOTHROW
26  std::cerr<<"File not found: "<<fileName<<std::endl;
27  exit(1);
28 #else
29  throw FileNotFoundError(fileName);
30 #endif
31  }
32 
33  in >> (*this);
34 }
35 
37  const std::string fileName, const std::string delimiter,
38  const std::string comment, const std::string inc, const std::string sentry )
39 {
40  // Construct a ConfigFile, getting keys and values from given file
41 
42  // the old values
43  std::string delimiter1 = _delimiter;
44  std::string comment1 = _comment;
45  std::string inc1 = _include;
46  std::string sentry1 = _sentry;
47 
48  if (delimiter != "") _delimiter = delimiter;
49  if (comment != "") _comment = comment;
50  if (inc != "") _include = inc;
51  if (sentry != "") _sentry = sentry;
52 
53  std::ifstream in( fileName.c_str() );
54 
55  if( !in ) {
56 #ifdef NOTHROW
57  std::cerr<<"File not found: "<<fileName<<std::endl;
58  exit(1);
59 #else
60  throw FileNotFoundError(fileName);
61 #endif
62  }
63 
64  in >> (*this);
65 
66  _delimiter = delimiter1;
67  _comment = comment1;
68  _include = inc1;
69  _sentry = sentry1;
70 }
71 
72 ConvertibleString& ConfigFile::getNoCheck( const std::string& key )
73 {
74  std::string key2 = key;
75  trim(key2);
76  return _contents[key2];
77 }
78 
79 ConvertibleString ConfigFile::get( const std::string& key ) const
80 {
81  std::string key2 = key;
82  trim(key2);
83  MapCIt p = _contents.find(key2);
84  if (p == _contents.end()) {
85 #ifdef NOTHROW
86  std::cerr<<"Key not found: "<<key2<<std::endl;
87  exit(1); return key;
88 #else
89  throw ParameterException(
90  "ConfigFile error: key "+key2+" not found");
91 #endif
92  } else {
93  return p->second;
94  }
95 }
96 
97 // special string getter. This is really for the python
98 // bindings for just viewing quickly the contents. Hence
99 // also throwing const char* for now, which swig can easily
100 // deal with
101 std::string ConfigFile::getstr(const std::string key) const throw (const char*) {
102  MapCIt p = _contents.find(key);
103 
104  if (p == _contents.end()) {
105  std::stringstream err;
106  err<<"ConfigFile error: key '"<<key<<"' not found";
107  throw err.str().c_str();
108  }
109 
110  std::string val = get(key);
111  return val;
112 }
113 // with default value
114 std::string ConfigFile::getstr(
115  const std::string key,
116  const std::string defval) {
117  MapCIt p = _contents.find(key);
118 
119  std::string val;
120  if (p == _contents.end()) {
121  val = defval;
122  } else {
123  val = get(key);
124  }
125  return val;
126 }
127 
128 
129 
130 
131 void ConfigFile::remove( const std::string& key )
132 {
133  // Remove key and its value
134  _contents.erase( _contents.find( key ) );
135  return;
136 }
137 
138 
139 bool ConfigFile::keyExists( const std::string& key ) const
140 {
141  // Indicate whether key is found
142  MapCIt p = _contents.find( key );
143  return ( p != _contents.end() );
144 }
145 
146 
147 void ConfigFile::trim( std::string& s )
148 {
149  // Remove leading and trailing whitespace
150  std::string whiteSpace = " \n\t\v\r\f";
151  s.erase( 0, s.find_first_not_of(whiteSpace) );
152  s.erase( s.find_last_not_of(whiteSpace) + 1);
153 }
154 
155 
156 void ConfigFile::write(std::ostream& os) const
157 {
158  // Save a ConfigFile to os
159  for(MapCIt p = _contents.begin(); p != _contents.end(); ++p ) {
160  os << p->first << " " << _delimiter << " ";
161  os << p->second << std::endl;
162  }
163 }
164 
165 void ConfigFile::writeAsComment(std::ostream& os) const
166 {
167  // Save a ConfigFile to os
168  for(MapCIt p = _contents.begin(); p != _contents.end(); ++p ) {
169  std::string f = p->first;
170  std::string s = p->second;
171  std::replace(f.begin(),f.end(),'\n',' ');
172  std::replace(s.begin(),s.end(),'\n',' ');
173  os << _comment << " " << f << " " << _delimiter << " ";
174  os << s << std::endl;
175  }
176 }
177 
178 void ConfigFile::read(std::istream& is)
179 {
180  // Load a ConfigFile from is
181  // Read in keys and values, keeping internal whitespace
182  const std::string& delim = _delimiter; // separator
183  const std::string& comm = _comment; // comment
184  const std::string& inc = _include; // include directive
185  const std::string& sentry = _sentry; // end of file sentry
186  const std::string::size_type skip = delim.size(); // length of separator
187 
188  std::string nextLine = "";
189  // might need to read ahead to see where value ends
190 
191  while( is || nextLine.size() > 0 ) {
192  // Read an entire line at a time
193  std::string line;
194  if( nextLine.size() > 0 ) {
195  line = nextLine; // we read ahead; use it now
196  nextLine = "";
197  } else {
198  std::getline( is, line );
199  }
200 
201  // Ignore comments
202  line = line.substr( 0, line.find(comm) );
203 
204  // Remove leading and trailing whitespace
205  trim(line);
206 
207  // If line is blank, go on to next line.
208  if (line.size() == 0) continue;
209 
210  // Check for include directive (only at start of line)
211  if (line.find(inc) == 0) {
212  line.erase(0,inc.size());
213  std::stringstream ss(line);
214  std::string fileName;
215  ss >> fileName;
216  load(fileName);
217  // implcitly skip the rest of the line.
218  continue;
219  }
220 
221  // Check for end of file sentry
222  if( sentry != "" && line.find(sentry) != std::string::npos ) return;
223 
224  // Parse the line if it contains a delimiter
225  std::string::size_type delimPos = line.find( delim );
226  if( delimPos < std::string::npos ) {
227  // Extract the key
228  std::string key = line.substr( 0, delimPos );
229  line.replace( 0, delimPos+skip, "" );
230 
231  // See if value continues on the next line
232  // Stop at blank line, next line with a key, end of stream,
233  // or end of file sentry
234  bool terminate = false;
235  while( !terminate && is ) {
236  std::getline( is, nextLine );
237  terminate = true;
238 
239  std::string nextLineCopy = nextLine;
240  ConfigFile::trim(nextLineCopy);
241  if( nextLineCopy == "" ) continue;
242 
243  nextLine = nextLine.substr( 0, nextLine.find(comm) );
244  if( nextLine.find(delim) != std::string::npos )
245  continue;
246  if( sentry != "" && nextLine.find(sentry) != std::string::npos )
247  continue;
248 
249  nextLineCopy = nextLine;
250  ConfigFile::trim(nextLineCopy);
251  if( nextLineCopy != "" ) line += "\n";
252  line += nextLine;
253  terminate = false;
254  }
255 
256  // Store key and value
257  ConfigFile::trim(key);
258  ConfigFile::trim(line);
259  _contents[key] = line; // overwrites if key is repeated
260  }
261  }
262 }
263 
264 }}}}
std::string getstr(const std::string key) const
Definition: ConfigFile.cc:101
bool val
ConvertibleString get(const std::string &key) const
Definition: ConfigFile.cc:79
void load(const std::string fileName)
Definition: ConfigFile.h:254
void write(std::ostream &os) const
Definition: ConfigFile.cc:156
bool keyExists(const std::string &key) const
Definition: ConfigFile.cc:139
ConvertibleString & getNoCheck(const std::string &key)
Definition: ConfigFile.cc:72
void writeAsComment(std::ostream &os) const
Definition: ConfigFile.cc:165
std::map< std::string, ConvertibleString > _contents
Definition: ConfigFile.h:334
std::map< std::string, ConvertibleString >::const_iterator MapCIt
Definition: ConfigFile.h:338
void remove(const std::string &key)
Definition: ConfigFile.cc:131