1 /*
2     Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
3 
4     This program is free software; you can redistribute it and/or
5     modify it under the terms of the GNU General Public License
6     as published by the Free Software Foundation; either version
7     3 of the License, or (at your option) any 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 <http://www.gnu.org/licenses/>.
16 */
17 
18 #ifndef CONF_FILE_H
19 #define CONF_FILE_H
20 
21 #include <ostream>
22 #include <fstream>
23 #include <string>
24 #include <list>
25 #include <map>
26 #include <exception>
27 
28 #include "vectors.h"
29 
30 class ConfFileException : public std::exception {
31 protected:
32     std::string errmsg;
33 public:
errmsg(errmsg)34     ConfFileException(const std::string& errmsg, const std::string& conffile, int lineno = 0) : errmsg(errmsg), conffile(conffile), lineno(lineno) {}
35 
36     std::string conffile;
37     int lineno;
38 
~ConfFileException()39     virtual ~ConfFileException() throw () {};
40 
what()41     virtual const char* what() const throw() { return errmsg.c_str(); }
42 };
43 
44 class ConfEntry {
45     std::string name;
46     std::string value;
47     int lineno;
48 
49 public:
50     ConfEntry();
51     ConfEntry(const std::string& name);
52     ConfEntry(const std::string& name, const std::string& value, int lineno = 0);
53     ConfEntry(const std::string& name, int value);
54     ConfEntry(const std::string& name, float value);
55     ConfEntry(const std::string& name, bool value);
56     ConfEntry(const std::string& name, vec2 value);
57     ConfEntry(const std::string& name, vec3 value);
58     ConfEntry(const std::string& name, vec4 value);
59 
60     void setName(const std::string& name);
61 
62     void setString(const std::string& value);
63     void setFloat(float value);
64     void setInt(int value);
65     void setBool(bool value);
66     void setVec2(vec2 value);
67     void setVec3(vec3 value);
68     void setVec4(vec4 value);
69 
70     bool hasValue();
71 
72     int getLineNumber();
73     std::string getName();
74 
75     std::string getString();
76     int         getInt();
77     float       getFloat();
78     bool        getBool();
79     vec2       getVec2();
80     vec3       getVec3();
81     vec4       getVec4();
82 
83     bool isFloat();
84     bool isInt();
85     bool isBool();
86     bool isVec2();
87     bool isVec3();
88     bool isVec4();
89 };
90 
91 typedef std::list<ConfEntry*> ConfEntryList;
92 
93 class ConfFile;
94 
95 class ConfSection {
96     std::map<std::string, ConfEntryList*> entrymap;
97     std::string name;
98     int lineno;
99     ConfFile* conf;
100 public:
101     ConfSection();
102     ConfSection(const std::string& name, int lineno = 0);
103     ~ConfSection();
104 
105     void clear();
106 
107     ConfFile* getConfFile();
108     ConfEntry* getEntry(const std::string& key);
109     ConfEntryList* getEntries(const std::string& key);
110 
111     void setConfFile(ConfFile* conf);
112 
113     void sectionException(ConfEntry* entry, std::string reason);
114 
115     std::string getName();
116 
117     int getLineNumber();
118 
119     bool        hasValue(const std::string& key);
120 
121     std::string getString(const std::string& key);
122     int         getInt(const std::string& key);
123     float       getFloat(const std::string& key);
124     bool        getBool(const std::string& key);
125     vec3       getVec3(const std::string& key);
126     vec4       getVec4(const std::string& key);
127 
128     void print(std::ostream& out);
129 
130     void setEntry(ConfEntry* entry);
131     void addEntry(ConfEntry* entry);
132 
133     void setEntry(const std::string& name, const std::string& value, int lineno=0);
134     void addEntry(const std::string& name, const std::string& value, int lineno=0);
135 };
136 
137 typedef std::list<ConfSection*> ConfSectionList;
138 
139 class ConfFile {
140 
141     std::string conffile;
142 
143     std::map<std::string, ConfSectionList*> sectionmap;
144 public:
145     ConfFile();
146     ~ConfFile();
147     void clear();
148 
149     void setFilename(const std::string& filename);
150     std::string getFilename();
151 
152     void load(const std::string& conffile);
153     void load();
154 
155     void save(const std::string& conffile);
156     void save();
157 
158     bool hasSection(const std::string& section);
159     ConfSection* getSection(const std::string& section);
160     ConfSectionList* getSections(const std::string& section);
161 
162     ConfEntry*   getEntry(const std::string& section, const std::string& key);
163     ConfEntryList* getEntries(const std::string& section, const std::string& key);
164 
165     void addSection(ConfSection* section);
166     ConfSection* addSection(const std::string& section);
167 
168     void setSection(ConfSection* section);
169 
170     int countSection(const std::string& section);
171 
172     void setEntry(const std::string& section, const std::string& key, const std::string& value);
173 
174     bool        hasEntry(const std::string& section,  const std::string& key);
175     bool        hasValue(const std::string& section,  const std::string& key);
176     std::string getString(const std::string& section, const std::string& key);
177     int         getInt(const std::string& section,    const std::string& key);
178     float       getFloat(const std::string& section,  const std::string& key);
179     bool        getBool(const std::string& section,   const std::string& key);
180     vec3       getVec3(const std::string& section,   const std::string& key);
181     vec4       getVec4(const std::string& section,   const std::string& key);
182 
183     static void trim(std::string& value);
184 
185     void unknownOptionException(ConfEntry* entry);
186     void missingValueException(ConfEntry* entry);
187     void invalidValueException(ConfEntry* entry);
188     void missingEntryException(ConfSection* section, std::string entryname);
189     void sectionException(ConfSection* section, std::string reason);
190     void entryException(ConfEntry* entry, std::string reason);
191 };
192 
193 #endif
194