crawlserv++  [under development]
Application for crawling and analyzing textual content of websites.
ConfigFile.hpp
Go to the documentation of this file.
1 /*
2  *
3  * ---
4  *
5  * Copyright (C) 2021 Anselm Schmidt (ans[ät]ohai.su)
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version in addition to the terms of any
11  * licences already herein identified.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  *
21  * ---
22  *
23  * ConfigFile.hpp
24  *
25  * A simple one line one entry configuration file where each line consists of a key=value pair.
26  *
27  * Created on: Sep 30, 2018
28  * Author: ans
29  */
30 
31 #ifndef MAIN_CONFIGFILE_HPP_
32 #define MAIN_CONFIGFILE_HPP_
33 
34 #include "Exception.hpp"
35 
36 #include <boost/core/typeinfo.hpp>
37 #include <boost/lexical_cast.hpp>
38 
39 #include <algorithm> // std::find_if, std::transform
40 #include <cctype> // std::tolower
41 #include <fstream> // std::ifstream
42 #include <string> // std::string, std::getline
43 #include <utility> // std::pair
44 #include <vector> // std::vector
45 
46 namespace crawlservpp::Main {
47 
48  /*
49  * DECLARATION
50  */
51 
53 
58  class ConfigFile {
59 
60  public:
63 
64  explicit ConfigFile(const std::string& name);
65 
69 
70  bool getValue(const std::string& name, std::string& to) const;
71 
73 
91  template<typename T> bool getValue(const std::string& name, T& to) const {
92  std::string result;
93 
94  if(this->getValue(name, result) && !result.empty()) {
95  try {
96  to = boost::lexical_cast<T>(result);
97 
98  return true;
99  }
100  catch(const boost::bad_lexical_cast& e) {
101  throw Exception(
102  this->fileName + ":"
103  " Could not convert config file entry \"" + name + "\""
104  " (=\"" + result + "\")"
105  " to " + boost::core::demangled_name(typeid(T))
106  );
107  }
108  }
109 
110  return false;
111  }
112 
114 
117 
118  protected:
119  // configuration entries
120  std::vector<std::pair<std::string, std::string>> entries;
121 
122  private:
123  // file name
124  std::string fileName;
125  };
126 
127  /*
128  * IMPLEMENTATION
129  */
130 
132 
140  inline ConfigFile::ConfigFile(const std::string& name) : fileName(name) {
141  std::ifstream fileStream(name);
142  std::string line;
143 
144  if(fileStream.is_open()) {
145  while(std::getline(fileStream, line)) {
146  const auto nameEnd{line.find('=')};
147 
148  if(nameEnd < line.length()) {
149  std::string nameInLine(line, 0, nameEnd);
150 
151  std::transform(
152  nameInLine.begin(),
153  nameInLine.end(),
154  nameInLine.begin(),
155  [](const auto c) {
156  return std::tolower(c);
157  }
158  );
159 
160  this->entries.emplace_back(
161  nameInLine,
162  line.substr(nameEnd + 1)
163  );
164  }
165  else {
166  this->entries.emplace_back(
167  line,
168  ""
169  );
170  }
171  }
172 
173  fileStream.close();
174  }
175  else {
176  throw Exception("Could not open \"" + name + "\" for reading");
177  }
178  }
179 
181 
194  inline bool ConfigFile::getValue(const std::string& name, std::string& to) const {
195  std::string nameCopy(name);
196 
197  std::transform(
198  nameCopy.begin(),
199  nameCopy.end(),
200  nameCopy.begin(),
201  [](const auto c) {
202  return std::tolower(c);
203  }
204  );
205 
206  const auto valueIt{
207  std::find_if(
208  this->entries.cbegin(),
209  this->entries.cend(),
210  [&nameCopy](const auto& entry) {
211  return entry.first == nameCopy;
212  }
213  )
214  };
215 
216  if(valueIt != this->entries.cend()) {
217  to = valueIt->second;
218 
219  return true;
220  }
221 
222  return false;
223  }
224 
225 } /* namespace crawlservpp::Main */
226 
227 #endif /* MAIN_CONFIGFILE_HPP_ */
ConfigFile(const std::string &name)
Constructor reading the file.
Definition: ConfigFile.hpp:140
std::vector< std::pair< std::string, std::string > > entries
Definition: ConfigFile.hpp:120
#define MAIN_EXCEPTION_CLASS()
Macro used to easily define classes for general exceptions.
Definition: Exception.hpp:50
Configuration file.
Definition: ConfigFile.hpp:58
bool getValue(const std::string &name, std::string &to) const
Gets the string value of a configuration entry.
Definition: ConfigFile.hpp:194
Class for configuration file exceptions.
Definition: ConfigFile.hpp:116
Namespace for the main classes of the program.
Definition: App.cpp:34
bool getValue(const std::string &name, T &to) const
Gets the converted value of a configuration entry.
Definition: ConfigFile.hpp:91