1 /*
2  * Copyright 2007-2010 Boris Kochergin. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 #ifndef CONFIGURATION_HPP
26 #define CONFIGURATION_HPP
27 
28 #include <fstream>
29 #include <stdlib.h>
30 #include <limits>
31 #include <map>
32 #include <string>
33 #include <vector>
34 
35 #include <errno.h>
36 #include <string.h>
37 
38 class Configuration {
39   public:
40     Configuration(const std::string);
41     Configuration();
42     bool initialize(const std::string);
43     operator bool() const;
44     std::string error() const;
45     std::string fileName() const;
46     std::string getString(const std::string);
47     std::vector <std::string> &getStrings(const std::string);
48     size_t getNumber(const std::string);
49   private:
50     std::map <std::string, std::vector <std::string> > options;
51     std::string _fileName;
52     bool _error;
53     std::string errorMessage;
54 };
55 
Configuration(const std::string fileName)56 Configuration::Configuration(const std::string fileName) {
57   initialize(fileName);
58 }
59 
Configuration()60 Configuration::Configuration() {
61   _error = true;
62   errorMessage = "Configuration::Configuration(): class not initialized";
63 }
64 
initialize(const std::string fileName)65 bool Configuration::initialize(const std::string fileName) {
66   std::string line, option, value;
67   size_t delimiter, openingQuote, closingQuote;
68   std::ifstream file;
69   _fileName = fileName;
70   file.open(fileName.c_str());
71   if (!file) {
72     _error = true;
73     errorMessage = "Configuration::initialize(): " + fileName + ": " +
74                    strerror(errno);
75     return false;
76   }
77   while (getline(file, line)) {
78     delimiter = line.find('=');
79     option = line.substr(0, delimiter);
80     value = line.substr(delimiter + 1);
81     openingQuote = value.find('"');
82     if (openingQuote != std::string::npos) {
83       closingQuote = value.find('"', openingQuote + 1);
84       if (closingQuote != std::string::npos) {
85         value = value.substr(openingQuote + 1,
86                              closingQuote - openingQuote - 1);
87       }
88     }
89     options[option].push_back(value);
90   }
91   file.close();
92   _error = false;
93   errorMessage.clear();
94   return true;
95 }
96 
operator bool() const97 Configuration::operator bool() const {
98   return !_error;
99 }
100 
error() const101 std::string Configuration::error() const {
102   return errorMessage;
103 }
104 
fileName() const105 std::string Configuration::fileName() const {
106   return _fileName;
107 }
108 
getString(const std::string option)109 std::string Configuration::getString(const std::string option) {
110   if (options[option].size()) {
111     return options[option][0];
112   }
113   return "";
114 }
115 
getStrings(const std::string option)116 std::vector <std::string> &Configuration::getStrings(const std::string option) {
117   return options[option];
118 }
119 
getNumber(const std::string option)120 size_t Configuration::getNumber(const std::string option) {
121   if (options[option].size()) {
122     return strtoul(options[option][0].c_str(), NULL, 10);
123   }
124   return std::numeric_limits <size_t>::max();
125 }
126 
127 #endif
128