1 /*
2 	OpenLieroX
3 
4 	INI reader
5 
6 	18-01-2008, by Albert Zeyer
7 	code under LGPL
8 */
9 
10 #ifndef __INI_READER_H__
11 #define __INI_READER_H__
12 
13 #include "StringUtils.h"
14 #include <map>
15 
16 struct Color;
17 
18 /*
19 	to use this class, you have to create a subclass from it and
20 	overload the OnNewSection or/and OnEntry
21 */
22 class IniReader {
23 public:
24 	typedef std::map<std::string, int, stringcaseless> KeywordList;
25 
26 
27 	IniReader(const std::string& filename, KeywordList& keywords = IniReader::DefaultKeywords);
28 	virtual ~IniReader();
29 
30 	// returns false if there was an error
31 	// if you break via the callbacks, this is also an error
32 	bool Parse();
33 
34 	// if the return value is false, the parsing will break
OnNewSection(const std::string & section)35 	virtual bool OnNewSection (const std::string& section) { return true; }
OnEntry(const std::string & section,const std::string & propname,const std::string & value)36 	virtual bool OnEntry (const std::string& section, const std::string& propname, const std::string& value) { return true; }
37 
38 	// Reading
39 	bool ReadString(const std::string& section, const std::string& key, std::string& value, std::string defaultv) const;
40 	bool ReadInteger(const std::string& section, const std::string& key, int *value, int defaultv) const;
41 	bool ReadFloat(const std::string& section, const std::string& key, float *value, float defaultv) const;
42 	bool ReadIntArray(const std::string& section, const std::string& key, int *array, int num_items) const;
43 	bool ReadColour(const std::string& section, const std::string& key, Color& value, const Color& defaultv) const;
44 	bool ReadKeyword(const std::string& section, const std::string& key, int *value, int defaultv) const;
45 	bool ReadKeyword(const std::string& section, const std::string& key, bool *value, bool defaultv) const;
46 	bool ReadKeywordList(const std::string& section, const std::string& key, int *value, int defaultv)const;
47 
48 	template<typename T>
ReadArray(const std::string & section,const std::string & key,T * data,size_t num)49 	bool ReadArray(const std::string& section, const std::string& key, T* data, size_t num) const {
50 		std::string string;
51 
52 		if (!ReadString(section, key, string, ""))
53 			return false;
54 
55 		std::vector<std::string> arr = explode(string,",");
56 		for (size_t i=0; i< MIN(num,arr.size()); i++)
57 			data[i] = from_string<T>(arr[i]);
58 
59 		return num == arr.size();
60 	}
61 
62 	template<typename T>
63 	bool ReadVectorD2(const std::string& section, const std::string& key, VectorD2<T>& v, VectorD2<T> defv = VectorD2<T>(), bool acceptSimple = true) const {
64 		v = defv;
65 
66 		T _v[2] = {0,0};
67 		if(!ReadArray(section, key, _v, 2)) {
68 			if(!acceptSimple || !ReadArray(section, key, _v, 1)) return false;
69 			v.x = v.y = _v[0];
70 			return true;
71 		}
72 
73 		v.x = _v[0]; v.y = _v[1];
74 		return true;
75 	}
76 
77 	template<typename T>
78 	bool ReadMatrixD2(const std::string& section, const std::string& key, MatrixD2<T>& v, MatrixD2<T> defv = MatrixD2<T>(), bool acceptSimple = true) const {
79 		v = defv;
80 
81 		T _v[4] = {0,0,0,0};
82 		if(!ReadArray(section, key, _v, 4)) {
83 			if(!acceptSimple || !ReadArray(section, key, _v, 1)) return false;
84 			v.v1.x = v.v2.y = _v[0];
85 			v.v1.y = v.v2.x = 0;
86 			return true;
87 		}
88 
89 		v.v1.x = _v[0]; v.v1.y = _v[1]; v.v2.x = _v[2]; v.v2.y = _v[3];
90 		return true;
91 	}
92 
93 	// Keyword
getFileName()94 	std::string getFileName() const { return m_filename; }
95 
96 	static KeywordList DefaultKeywords;
97 protected:
98 	typedef std::map<std::string, std::string> Section;
99 	typedef std::map<std::string, Section> SectionMap;
100 
101 	std::string m_filename;
102 	SectionMap m_sections;
103 	KeywordList& m_keywords;
104 
105 private:
106 	Section *m_curSection;
107 
108 private:
109 	bool GetString(const std::string& section, const std::string& key, std::string& string) const;
110 	void NewSection(const std::string& name);
111 	void NewEntryInSection(const std::string& name, const std::string& value);
112 };
113 
114 #endif
115 
116