Marine Library  1.0
C++ library for Linux Networking Development
configuration.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Zhao DAI <daidodo@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or any
7  * later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see accompanying file LICENSE.txt
16  * or <http://www.gnu.org/licenses/>.
17  */
18 
25 #ifndef DOZERG_CONFIGURATION_H_20070821
26 #define DOZERG_CONFIGURATION_H_20070821
27 
28 #include <map>
29 #include <string>
30 #include <sstream>
31 #include <fstream>
32 #include <limits> //std::numeric_limits
33 #include <cstdlib> //atoi
34 #include "template.hh" //CTypeTraits
35 #include "tools/string.hh" //Trim,AbsFilename
36 
37 NS_SERVER_BEGIN
38 
39 //TODO: re-write unit test
40 //TODO: add json support, add range support(1,3-10,20,23-100)
85 {
86  typedef std::map<std::string, std::string> container_type;
87 public:
88  static const int kFormatEqual = 0;
89  static const int kFormatSpace = 1;
90  static const int kFormatColon = 2;
95  std::string getConfName() const{return conf_file_;}
100  void clear(){content_.clear();}
108  bool load(const std::string & file_name, int format = kFormatSpace){
109  std::string abs_file = tools::AbsFilename(file_name);
110  std::ifstream inf(abs_file.c_str());
111  if(!inf.is_open())
112  return false;
113  clear();
114  for(std::string line;!inf.eof();){
115  std::getline(inf, line);
116  parseFormat(line.substr(0, line.find_first_of("#")), format);
117  }
118  conf_file_ = abs_file;
119  return true;
120  }
127  std::string getString(const std::string & key, const std::string & strdefault = "") const{
128  container_type::const_iterator wh = content_.find(key);
129  if(wh == content_.end())
130  return strdefault;
131  return wh->second;
132  }
142  std::string getFilepath(const std::string & key, const std::string & strdefault = "") const{
143  const std::string v = getString(key, strdefault);
144  return (v.empty() ? v : tools::AbsFilename(v));
145  }
169  int getInt(const std::string & key, int ndefault = 0,
170  int min = std::numeric_limits<int>::min(),
171  int max = std::numeric_limits<int>::max()) const
172  {
173  return getInt<int>(key, ndefault, min, max);
174  }
175  template<typename Int>
176  Int getInt(const std::string & key, Int ndefault = 0,
177  Int min = std::numeric_limits<Int>::min(),
178  Int max = std::numeric_limits<Int>::max()) const
179  {
180  container_type::const_iterator wh = content_.find(key);
181  Int ret = ndefault;
182  if(wh != content_.end()){
184  ret = atoi(wh->second.c_str());
185  }else{
186  std::istringstream iss(wh->second);
187  iss>>ret;
188  }
189  if(ret && wh->second.size() > 0){
190  char c = *wh->second.rbegin();
191  if(('b' == c || 'B' == c) //TODO: unit test
192  && wh->second.size() > 1)
193  c = *(wh->second.rbegin() + 1);
194  switch(c){
195  case 'k':case 'K':
196  ret <<= 10;
197  break;
198  case 'm':case 'M':
199  ret <<= 20;
200  break;
201  case 'g':case 'G':
202  ret <<= 30;
203  break;
204  case 't':case 'T':
205  ret *= (1ull << 40);
206  break;
207  case 'p':case 'P':
208  ret *= (1ull << 50);
209  break;
210  case 'e':case 'E':
211  ret *= (1ull << 60);
212  break;
213  default:;
214  }
215  }
216  }
217  return (ret <= min ? min : (ret >= max ? max : ret));
218  }
224  //TODO: unit test
225  std::string toString() const{
226  CToString oss;
227  oss<<"{conf_file_="<<conf_file_
228  <<", content_={";
229  int s = 0;
230  for(container_type::const_iterator i = content_.begin();i != content_.end();++i, ++s){
231  if(s)
232  oss<<", ";
233  oss<<"\""<<i->first<<"\"=\""<<i->second;
234  }
235  oss<<"}}";
236  return oss.str();
237  }
238 private:
239  void parseFormat(const std::string & line, int format){
240  if(line.empty())
241  return;
242  const std::string sep = (format == kFormatEqual ? "="
243  : (format == kFormatSpace ? " \t"
244  : (format == kFormatColon ? ":" : std::string())));
245  if(!sep.empty()){
246  const size_t i = line.find_first_of(sep);
247  content_[tools::Trim(line.substr(0, i))]
248  = tools::Trim((std::string::npos == i ? std::string() : line.substr(i + 1)));
249  }
250  }
251  //members
252  std::string conf_file_;
253  container_type content_;
254 };
255 
256 NS_SERVER_END
257 
258 #endif
259 
void clear()
Clear all attributes loaded.
Definition: configuration.hh:100
Definition: to_string.hh:43
std::string toString() const
Get a readable description of this object.
Definition: configuration.hh:225
Definition: template.hh:23
std::string getConfName() const
Get config file name.
Definition: configuration.hh:95
std::string getFilepath(const std::string &key, const std::string &strdefault="") const
Get file name value of an attribute.
Definition: configuration.hh:142
std::string getString(const std::string &key, const std::string &strdefault="") const
Get string value of an attribute.
Definition: configuration.hh:127
Parse config file and get attributes.
Definition: configuration.hh:84
bool load(const std::string &file_name, int format=kFormatSpace)
Parse and load content of a config file.
Definition: configuration.hh:108