1 /*
2  * configdb.h - classes to simplify configuration file handling
3  *
4  * Copyright (c) 2004, 2005 by Alastair M. Robinson
5  * Distributed under the terms of the GNU General Public License -
6  * see the file named "COPYING" for more details.
7  *
8 
9 In its simplest form you use it like this:
10 
11 #include <iostream>
12 
13 #include "configdb.h"
14 
15 class MyClassThatNeedsConfigData : public ConfigDB
16 {
17 	public:
18 	MyClassThatNeedsConfigData(ConfigFile *myfile)
19 		: ConfigDB(Template)
20 	{
21 		new ConfigDBHandler(myfile,"[SectionName]",this);
22 		// (This object is owned by the ConfigFile and will be freed by it.)
23 	}
24 	void MemberFunction()
25 	{
26 		std::cout << "Int value: " << FindInt("AnIntValue") << std::endl;
27 	}
28 	private:
29 	static ConfigTemplate Template[];
30 };
31 
32 ConfigTemplate MyClassThatNeedsConfigData::Template[]=
33 {
34 	ConfigTemplate("AnIntValue",int(17)), // Default value is 17
35 	ConfigTemplate("AStringValue","Default"),
36 	ConfigTemplate("AFloatValue",float(3.5)),
37 	ConfigTemplate() // NULL terminated...
38 };
39 
40 
41 int main(int argc,char **argv)
42 {
43 	ConfigFile myconfig;
44 	MyClassThatNeedsConfigData myclass(&myconfig);
45 	myconfig.ParseConfigFile("/path/to/myconfigfile");
46 
47 	myclass.MemberFunction();
48 	std::cout << "String value: " << myclass.FindString("AStringValue") << std::endl;
49 
50 	myclass.SetFloat("AFloatValue",1.45);
51 
52 	myconfig.SaveConfigFile("/path/to/myconfigfile");
53 
54 	return(0);
55 }
56 */
57 
58 #ifndef CONFIGDB_H
59 #define CONFIGDB_H
60 
61 enum ConfigArgType {ConfigARG_UNKNOWN,ConfigARG_STRING,ConfigARG_INTEGER,ConfigARG_FLOAT};
62 
63 class ConfigTemplate
64 {
65 	public:
ConfigTemplate(const char * name,const char * val)66 	ConfigTemplate(const char *name, const char *val) : Name(name), Type(ConfigARG_STRING), defstring(val)
67 	{
68 	}
ConfigTemplate(const char * name,int val)69 	ConfigTemplate(const char *name, int val) : Name(name), Type(ConfigARG_INTEGER), defint(val)
70 	{
71 	}
ConfigTemplate(const char * name,double val)72 	ConfigTemplate(const char *name, double val) : Name(name), Type(ConfigARG_FLOAT), deffloat(val)
73 	{
74 	}
ConfigTemplate()75 	ConfigTemplate() : Type(ConfigARG_UNKNOWN)
76 	{
77 	}
78 	const char *Name;
79 	enum ConfigArgType Type;
80 	const char *defstring;
81 	int defint;
82 	double deffloat;
83 };
84 
85 
86 class ConfigOption;
87 
88 
89 class ConfigDB
90 {
91 	public:
92 	ConfigDB(struct ConfigTemplate *templ);
93 	virtual ~ConfigDB();
94 	int ParseString(const char *string);
95 	virtual void SaveDB(FILE *file);
96 	enum ConfigArgType QueryType(const char *Name);
97 	const char *FindString(const char *Name);
98 	int FindInt(const char *Name);
99 	double FindFloat(const char *Name);
100 	void SetInt(const char *Name,int val);
101 	void SetFloat(const char *Name,double val);
102 	void SetString(const char *Name,const char *val);
103 	ConfigDB &operator=(ConfigDB &other);
104 	private:
105 	ConfigOption *FindOption(const char *Name);
106 	struct ConfigOption *firstopt;
107 	friend class ConfigOption;
108 };
109 
110 
111 class ConfigOption
112 {
113 	public:
114 	ConfigOption(ConfigDB *db,struct ConfigTemplate *templ);
115 	~ConfigOption();
116 	private:
117 	const char *Name;
118 	enum ConfigArgType Type;
119 	union
120 	{
121 		char *string;
122 		int intnumber;
123 		double floatnumber;
124 	} Value;
125 	ConfigOption *next;
126 	ConfigOption *prev;
127 	ConfigDB *db;
128 	friend class ConfigDB;
129 };
130 
131 class ConfigFile;
132 class ConfigSectionHandler
133 {
134 	public:
135 	ConfigSectionHandler(ConfigFile *inifile,const char *section);
136 	virtual ~ConfigSectionHandler();
137 	virtual void SelectSection();
138 	virtual void LeaveSection();
139 	virtual void ParseString(const char *string)=0;
140 	virtual void SaveSection(FILE *file)=0;
141 	const char *section;
142 	private:
143 	ConfigSectionHandler *next,*prev;
144 	ConfigFile *inifile;
145 	friend class ConfigFile;
146 };
147 
148 
149 class ConfigDBHandler : public ConfigSectionHandler
150 {
151 	public:
152 	ConfigDBHandler(ConfigFile *inf,const char *section,ConfigDB *db);
153 	~ConfigDBHandler();
154 	virtual void ParseString(const char *string);
155 	virtual void SaveSection(FILE *file);
156 	private:
157 	ConfigDB *db;
158 };
159 
160 
161 class ConfigFile
162 {
163 	public:
164 	ConfigFile();
165 	virtual ~ConfigFile();
166 	virtual bool ParseConfigFile(const char *inifile);
167 	virtual bool SaveConfigFile(const char *inifile);
168 	private:
169 	ConfigSectionHandler *FindHandler(const char *section);
170 	ConfigSectionHandler *first;
171 	ConfigSectionHandler *current;
172 	friend class ConfigSectionHandler;
173 };
174 
175 #endif
176