MeteoIODoc 20250905.f67af007
 
Loading...
Searching...
No Matches
Config.h
Go to the documentation of this file.
1/***********************************************************************************/
2/* Copyright 2009 WSL Institute for Snow and Avalanche Research SLF-DAVOS */
3/***********************************************************************************/
4/* This file is part of MeteoIO.
5 MeteoIO is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 MeteoIO is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with MeteoIO. If not, see <http://www.gnu.org/licenses/>.
17*/
18#ifndef CONFIGREADER_H
19#define CONFIGREADER_H
20
21#include <meteoio/IOUtils.h>
23
24#include <string>
25#include <map>
26#include <vector>
27
28namespace mio {
29
77class ConfigProxy;
78
79class Config {
80 public:
84 Config();
85
90 Config(const std::string& filename_in);
91
96 void write(const std::string& filename) const;
97
102 void addFile(const std::string& filename_in);
103
111 void addKey(std::string key, std::string section, const std::string& value);
112
118 void deleteKey(std::string key, std::string section);
119
130 void deleteKeys(std::string keymatch, std::string section, const bool& anywhere=false);
131
136 std::string getSourceName() const {return sourcename;}
137
142 std::string getConfigRootDir() const {return configRootDir;}
143
150 bool keyExists(std::string key, std::string section) const;
151 bool keyExistsRegex(std::string key_pattern, std::string section) const;
152
158 bool sectionExists(std::string section) const;
159
164 const std::string toString() const;
165
166 friend std::ostream& operator<<(std::ostream& os, const Config& cfg);
167 friend std::istream& operator>>(std::istream& is, Config& cfg);
168
169 template <typename T> std::vector<T> getValue(const std::string& key, std::string& section,
171 {
172 std::vector<T> tmp;
173 getValue(key, section, tmp, opt);
174 return tmp;
175 }
176
187 template <typename T> void getValue(const std::string& key,
188 std::vector<T>& vecT,
190 {
191 getValue(key, "GENERAL", vecT, opt);
192 }
193
205 template <typename T> void getValue(std::string key, std::string section,
206 std::vector<T>& vecT, const IOUtils::ThrowOptions& opt=IOUtils::dothrow) const
207 {
208 vecT.clear();
209 IOUtils::toUpper(key);
210 IOUtils::toUpper(section);
211
212 try {
213 IOUtils::getValueForKey<T>(properties, section + "::" + key, vecT, opt);
214 } catch(const std::exception&){
215 throw UnknownValueException("[E] Error in "+sourcename+": no value for key "+section+"::"+key, AT);
216 }
217 }
218
233 const ConfigProxy get(const std::string& key, const std::string& section) const;
234
249 template <typename T> T get(const std::string& key, const std::string& section, const T& dflt) const;
250
267 std::string get(const std::string& key, const std::string& section, const std::string& dflt) const;
268 std::string get(const std::string& key, const std::string& section, const char dflt[]) const;
269 double get(const std::string& key, const std::string& section, const double& dflt) const; //surprisingly, in c++11 with gcc 9.3.0 this is needed...
270 bool get(const std::string& key, const std::string& section, const bool& dflt) const;
271
272
279 template <typename T> void getValue(const std::string& key, T& t, const IOUtils::ThrowOptions& opt=IOUtils::dothrow) const
280 {
281 getValue(key, "GENERAL", t, opt);
282 }
283
291 template <typename T> void getValue(std::string key, std::string section, T& t,
293 {
294 IOUtils::toUpper(key);
295 IOUtils::toUpper(section);
296
297 try {
298 IOUtils::getValueForKey<T>(properties, section + "::" + key, t, opt);
299 } catch(const std::exception&){
300 throw UnknownValueException("[E] Error in "+sourcename+": no value for key "+section+"::"+key, AT);
301 }
302 }
303
312 void getValue(std::string key, std::string section, Date& t, const double& time_zone,
314 {
315 t.setUndef(true);
316 IOUtils::toUpper(key);
317 IOUtils::toUpper(section);
318 std::string tmp;
319
320 try {
321 IOUtils::getValueForKey<std::string>(properties, section + "::" + key, tmp, opt);
322 } catch(const std::exception&){
323 throw UnknownValueException("[E] Error in "+sourcename+": no value for key "+section+"::"+key, AT);
324 }
325
326 bool parse_ok = false;
327 try {
328 parse_ok = IOUtils::convertString(t, tmp, time_zone);
329 } catch(const std::exception&){
330 parse_ok = false;
331 }
332 if (!parse_ok && opt==IOUtils::dothrow)
333 throw InvalidFormatException("Could not parse date '"+tmp+"' in "+sourcename+"for key "+section+"::"+key, AT);
334 }
335
345 template <typename T> void getValues(std::string keymatch, std::string section, std::vector<T>& vecT) const
346 {
347 vecT.clear();
348 IOUtils::toUpper(keymatch);
349 IOUtils::toUpper(section);
350 const std::vector< std::string > vecKeys( getKeys(keymatch, section) );
351
352 for (const std::string& key : vecKeys) {
353 const std::string full_key( section + "::" + key );
354 T tmp;
355 try {
356 IOUtils::getValueForKey<T>(properties, full_key, tmp, IOUtils::dothrow);
357 } catch(const std::exception&){
358 throw UnknownValueException("[E] Error in "+sourcename+" reading key "+full_key, AT);
359 }
360 vecT.push_back( tmp );
361 }
362 }
363
364 template <typename T> void getValues(std::string keymatch, std::string section, std::vector<T>& vecT, std::vector<std::string>& vecKeys) const
365 {
366 vecT.clear();
367 IOUtils::toUpper(keymatch);
368 IOUtils::toUpper(section);
369 vecKeys = getKeys(keymatch, section);
370
371 for (const std::string& key : vecKeys) {
372 const std::string full_key = section + "::" + key;
373 T tmp;
374 try {
375 IOUtils::getValueForKey<T>(properties, full_key, tmp, IOUtils::dothrow);
376 } catch(const std::exception&){
377 throw UnknownValueException("[E] Error in "+sourcename+" reading key "+full_key, AT);
378 }
379 vecT.push_back( tmp );
380 }
381 }
382
394 std::vector< std::pair<std::string, std::string> > getValues(std::string keymatch, std::string section, const bool& anywhere=false) const;
395
396 std::vector< std::pair<std::string, std::string> > getValuesRegex(const std::string& regex_str, std::string section) const;
397
409 std::vector<std::string> getKeys(std::string keymatch, std::string section, const bool& anywhere=false) const;
410 std::vector<std::string> getKeysRegex(const std::string& regex_str, std::string section) const;
415 std::set<std::string> getSections() const {return sections;}
416
423 void moveSection(std::string org, std::string dest, const bool& overwrite);
424
437 static unsigned int getCommandNr(const std::string& section, const std::string& cmd_pattern, const std::string& cmd_key);
438
454 std::vector< std::pair<std::string, std::string> > parseArgs(const std::string& section, const std::string& cmd_id, const unsigned int& cmd_nr, const std::string& arg_pattern) const;
455
464 std::vector< std::pair<std::string, std::string> > getArgumentsForAlgorithm(const std::string& parname, const std::string& algorithm,
465 const std::string& section = "Interpolations1d") const;
466 // overload for indexed algorith
467 std::vector< std::pair<std::string, std::string> > getArgumentsForAlgorithm(const std::string& parname, const std::string& algorithm, const size_t& algo_index,
468 const std::string& section = "Interpolations1d") const;
469
470
471
472 private:
473 std::map<std::string, std::string> properties;
474 std::set<std::string> sections;
475 std::string sourcename;
476 std::string configRootDir;
477}; //end class definition Config
478
479class ConfigProxy {
480 public:
481 const Config& proxycfg;
482 const std::string& key;
483 const std::string& section;
484
485 ConfigProxy(const Config& i_cfg, const std::string& i_key,
486 const std::string& i_section)
487 : proxycfg(i_cfg), key(i_key),section(i_section) { }
488
489 template<typename T> operator T() const {
490 T tmp;
491 proxycfg.getValue(key, section, tmp, IOUtils::dothrow);
492 return tmp;
493 }
494};
495
497 public:
498 ConfigParser(const std::string& filename, std::map<std::string, std::string> &i_properties, std::set<std::string> &i_sections);
499
500 static std::string extract_section(const std::string& key, const bool& provide_default=false);
501
502 private:
503 enum VarType {
504 ROOT,
505 ENV,
506 EXPR,
507 REF
508 };
509
511 typedef struct VARIABLE {
512 VARIABLE() : value(), children_idx(), children_not_ready(0), parent_idx(IOUtils::npos), pos_start(std::string::npos), pos_end(std::string::npos), type(REF), isExpanded(false) {}
513 VARIABLE(const size_t& i_pos_start, const VarType& i_type) : value(), children_idx(), children_not_ready(0), parent_idx(IOUtils::npos), pos_start(i_pos_start), pos_end(std::string::npos), type(i_type), isExpanded(false) {}
514 VARIABLE(const std::string& i_value, const size_t& i_pos_start, const size_t& i_pos_end, const VarType& i_type) : value(i_value), children_idx(), children_not_ready(0), parent_idx(IOUtils::npos), pos_start(i_pos_start), pos_end(i_pos_end), type(i_type), isExpanded(false) {}
515
516 void finalize(const std::string& i_value, const size_t& i_pos_end) {value=i_value; pos_end=i_pos_end;}
517 void setParent(const size_t& idx) {parent_idx=idx;}
518 void setChild(const size_t& idx) {children_idx.insert(idx); children_not_ready++;}
519
520 std::string toString() const {std::ostringstream os; os << "<Variable>" << (type==EXPR?"expr":(type==ENV?"env":"ref")) << " @[" << pos_start << ","; if(pos_end!=IOUtils::npos) os << pos_end; else os << "-"; os << "]" << " is '" << value << "'"; if(parent_idx!=IOUtils::npos) os << " parent: " << parent_idx; if(!children_idx.empty()){ os << " children: "; for(const auto& val : children_idx) os << val << " ";}; os << " children_not_ready=" << children_not_ready << " "; os << "</variable>"; return os.str();}
521
522 std::string value;
523 std::set<size_t> children_idx;
524 size_t children_not_ready;
525 size_t parent_idx;
526 size_t pos_start, pos_end;
527 VarType type;
528 bool isExpanded;
529 } variable;
530
532 typedef struct FILE_PPT {
533 FILE_PPT() : original_name(), restrict_section(), clean_name() {}
534 FILE_PPT(const std::string& filename, const std::string& ini_sourcename);
535
536 std::string toString() const {std::ostringstream os; os << "<INI file>" << original_name << ", cleaned as " << clean_name; if (!restrict_section.empty()) os << ", restricted to [" << restrict_section << "]"; os << "</INI file>"; return os.str();}
537
538 bool operator<(const FILE_PPT& a) const { //needed for "sort"
539 if (original_name<a.original_name) return true;
540 if (original_name>a.original_name) return false;
541 if (clean_name<a.clean_name) return true;
542 if (clean_name>a.clean_name) return false;
543 return restrict_section < a.restrict_section;
544 }
545 bool operator==(const FILE_PPT& a) const { //needed to check for uniqueness
546 return (original_name==a.original_name) && (restrict_section==a.restrict_section) && (clean_name==a.clean_name);
547 }
548
549 std::string original_name;
550 std::string restrict_section;
551 std::string clean_name;
552 } fileProperties;
553
554 static std::vector<ConfigParser::variable> parseVariable(const std::string &value);
555 bool expandVar(const variable& var, const std::string& section, std::string &replacement) const;
556 bool expandVarsForKey(std::vector<variable>& vecVars, const std::string& section, bool& hasSomeSuccesses);
557
558 void parseFile(const fileProperties& iniFile);
559 void parseLine(const unsigned int& linenr, const std::string& restrict_section, std::vector< fileProperties > &import_after, bool &accept_import_before, std::string line, std::string &section);
560
561 static bool onlyOneEqual(const std::string& str);
562 bool processSectionHeader(const std::string& line, std::string &section, const unsigned int& linenr);
563 bool processImports(const std::string& key, const std::string& value, std::vector< fileProperties > &import_after, const bool &accept_import_before);
564 void handleNonKeyValue(const std::string& line_backup, const std::string& section, const unsigned int& linenr, bool &accept_import_before);
565
566 std::map<std::string, std::string> properties;
567 std::set< fileProperties > imported;
568 std::set<std::string> sections;
569 std::map<std::string, std::vector<variable> > vars;
570 std::string sourcename;
571};
572
573} //end namespace mio
574
575#endif
#define AT
Definition IOExceptions.h:28
Definition Config.h:496
static std::string extract_section(const std::string &key, const bool &provide_default=false)
Definition Config.cc:816
A class that reads a key/value file. These files (typically named *.ini) follow the INI file format s...
Definition Config.h:79
std::string getSourceName() const
Returns the filename that the Config object was constructed with.
Definition Config.h:136
void getValue(const std::string &key, T &t, const IOUtils::ThrowOptions &opt=IOUtils::dothrow) const
Template function to retrieve a value of class T for a certain key.
Definition Config.h:279
void getValues(std::string keymatch, std::string section, std::vector< T > &vecT, std::vector< std::string > &vecKeys) const
Definition Config.h:364
void getValues(std::string keymatch, std::string section, std::vector< T > &vecT) const
Template function to retrieve a vector of values of class T for a certain key pattern.
Definition Config.h:345
friend std::ostream & operator<<(std::ostream &os, const Config &cfg)
Definition Config.cc:450
void deleteKey(std::string key, std::string section)
Delete a specific key/value pair from the internal map object, key/section are case insensitive.
Definition Config.cc:127
const ConfigProxy get(const std::string &key, const std::string &section) const
A function that allows to retrieve a value for a key as return parameter (vectors of values too).
Definition Config.cc:52
const std::string toString() const
Print the content of the Config object (useful for debugging) The Config is bound by "<Config>" and "...
Definition Config.cc:439
Config()
Empty constructor. The user MUST later one fill the internal key/value map object.
Definition Config.cc:45
std::vector< std::string > getKeys(std::string keymatch, std::string section, const bool &anywhere=false) const
Function that searches for a given string within the keys of a given section (default: GENERAL) it re...
Definition Config.cc:384
static unsigned int getCommandNr(const std::string &section, const std::string &cmd_pattern, const std::string &cmd_key)
Extract the command number from a given command string, given the command pattern.
Definition Config.cc:529
std::set< std::string > getSections() const
Returns all the sections that are present in the config object.
Definition Config.h:415
void getValue(const std::string &key, std::vector< T > &vecT, const IOUtils::ThrowOptions &opt=IOUtils::dothrow) const
Template function to retrieve a vector of values of class T for a certain key.
Definition Config.h:187
std::vector< std::string > getKeysRegex(const std::string &regex_str, std::string section) const
Definition Config.cc:372
void addFile(const std::string &filename_in)
Add the content of a file to the internal key/value map object.
Definition Config.cc:113
void getValue(std::string key, std::string section, Date &t, const double &time_zone, const IOUtils::ThrowOptions &opt=IOUtils::dothrow) const
Function to retrieve a Date value for a certain key.
Definition Config.h:312
std::vector< std::pair< std::string, std::string > > parseArgs(const std::string &section, const std::string &cmd_id, const unsigned int &cmd_nr, const std::string &arg_pattern) const
Extract the arguments for a given command and store them into a vector of key / value pairs.
Definition Config.cc:547
friend std::istream & operator>>(std::istream &is, Config &cfg)
Definition Config.cc:485
void addKey(std::string key, std::string section, const std::string &value)
Add a specific key/value pair to the internal key/value map object. key and section are case insensit...
Definition Config.cc:120
void write(const std::string &filename) const
Write the Config object to a file.
Definition Config.cc:398
bool keyExists(std::string key, std::string section) const
Return if a given key exists in a given section (matching is case insensitive)
Definition Config.cc:164
std::vector< T > getValue(const std::string &key, std::string &section, const IOUtils::ThrowOptions &opt=IOUtils::dothrow) const
Definition Config.h:169
void getValue(std::string key, std::string section, T &t, const IOUtils::ThrowOptions &opt=IOUtils::dothrow) const
Template function to retrieve a value of class T for a certain key.
Definition Config.h:291
void getValue(std::string key, std::string section, std::vector< T > &vecT, const IOUtils::ThrowOptions &opt=IOUtils::dothrow) const
Template function to retrieve a vector of values of class T for a certain key.
Definition Config.h:205
bool sectionExists(std::string section) const
Return if a given section exists in the Config object.
Definition Config.cc:185
bool keyExistsRegex(std::string key_pattern, std::string section) const
Definition Config.cc:174
std::string getConfigRootDir() const
Returns the directory where the root configuration file is (needed to resolv relative paths).
Definition Config.h:142
void moveSection(std::string org, std::string dest, const bool &overwrite)
Move all keys of the org section to the dest section.
Definition Config.cc:197
std::vector< std::pair< std::string, std::string > > getValuesRegex(const std::string &regex_str, std::string section) const
Definition Config.cc:236
std::vector< std::pair< std::string, std::string > > getArgumentsForAlgorithm(const std::string &parname, const std::string &algorithm, const std::string &section="Interpolations1d") const
retrieve the resampling algorithm to be used for the 1D interpolation of meteo parameters....
Definition Config.cc:563
void deleteKeys(std::string keymatch, std::string section, const bool &anywhere=false)
Delete keys matching a specific pattern from the internal map object, key/section are case insensitiv...
Definition Config.cc:134
A class to handle timestamps. This class handles conversion between different time display formats (I...
Definition Date.h:87
void setUndef(const bool &flag=true)
Definition Date.cc:194
thrown when parsed data does not reflect an expected format (e.g. premature end of a line,...
Definition IOExceptions.h:94
thrown when encountered an unexpected value (e.g. unknown name or key)
Definition IOExceptions.h:142
bool convertString(Date &t, std::string str, const double &time_zone, std::ios_base &(*f)(std::ios_base &))
Convert a string to a date (template specialization of convertString)
Definition IOUtils.cc:660
void toUpper(std::string &str)
Definition IOUtils.cc:285
ThrowOptions
Definition IOUtils.h:74
@ dothrow
Definition IOUtils.h:74
bool operator==(const geoLocation &lhs, const geoLocation &rhs)
Definition iCSVHelper.cc:633
Definition Config.cc:34