File: ini_file.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (182 lines) | stat: -rw-r--r-- 5,549 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

//=============================================================================
//
// IniFile class defines contents of the configuration file.
// It serves as a INI parser and plain enumerator of all the sections and items
// found in file, or, oppositely, as INI file constructor.
// But is not much suitable for regular key/value lookup. It is suggested to
// create a proper map to store items, from IniFile contents.
//
//=============================================================================

#ifndef AGS_SHARED_UTIL_INIFILE_H
#define AGS_SHARED_UTIL_INIFILE_H

#include "common/std/list.h"
#include "common/std/utility.h"
#include "ags/shared/util/string.h"

namespace AGS3 {
namespace AGS {
namespace Shared {

class IniFile {
public:
	// Position of a string in the line of text:
	// is defined by a pair of first and next-after-last character indices
	typedef std::pair<size_t, size_t> StrPos;
	// Location of section in the array of text lines:
	// is defined by a pair of first and next-after-last line indices
	typedef std::pair<size_t, size_t> SectionPos;

	inline static bool IsValidStrPos(const StrPos &pos) {
		return pos.first < pos.second;
	}

	// Item definition
	// Valid key indicates a key-value line; no key means unparsed
	// line of text, e.g. comment or incorrectly formatted item.
	class ItemDef {
	public:
		ItemDef(const String &key, const String &value);
		ItemDef(const String &line, const StrPos &key, const StrPos &value, size_t sep_at);
		String GetLine()  const {
			return Line;
		}
		String GetKey()   const {
			return SubString(Line, Key);
		}
		String GetValue() const {
			return SubString(Line, Value);
		}
		// Tells if this is a valid key/value item, which means that it has a valid key
		bool IsKeyValue() const {
			return IsValidStrPos(Key);
		}
		void SetKey(const String &key);
		void SetValue(const String &value);

	private:
		String  Line;  // actual text
		StrPos  Key;   // position of item key
		size_t  SepAt; // position of the separator (assignment) symbol
		StrPos  Value; // position of item value
	};
	// Linked list of items
	typedef std::list<ItemDef> LItems;
	typedef LItems::iterator          ItemIterator;
	typedef LItems::const_iterator    ConstItemIterator;

	// Section definition
	class SectionDef {
	public:
		SectionDef(const String &name);
		SectionDef(const String &line, const StrPos &name);
		String GetLine() const {
			return Header;
		}
		String GetName() const {
			return SubString(Header, Name);
		}
		size_t GetItemCount() const {
			return Items.size();
		}
		// Tells if this is a "global" section, which means that it has no name
		bool IsGlobal() const {
			return !IsValidStrPos(Name);
		}
		ItemIterator Begin() {
			return Items.begin();
		}
		ItemIterator End() {
			return Items.end();
		}
		ConstItemIterator CBegin() const {
			return Items.begin();
		}
		ConstItemIterator CEnd()   const {
			return Items.end();
		}
		void SetName(const String &sec_name);
		void Clear();
		ItemIterator InsertItem(ItemIterator item, const ItemDef &itemdef);
		void EraseItem(ItemIterator item);

	private:
		String      Header;// section's heading line
		StrPos      Name;  // location of section name in the header line
		LItems      Items; // linked list of items belonging to the section
	};

	// Linked list of sections
	typedef std::list<SectionDef>     LSections;
	typedef LSections::iterator       SectionIterator;
	typedef LSections::const_iterator ConstSectionIterator;

private:
	inline static String SubString(const String &line, const StrPos &pos) {
		return line.Mid(pos.first, pos.second - pos.first);
	}

public:
	IniFile();

	SectionIterator Begin() {
		return _sections.begin();
	}
	SectionIterator End() {
		return _sections.end();
	}
	ConstSectionIterator CBegin() const {
		return _sections.begin();
	}
	ConstSectionIterator CEnd()   const {
		return _sections.end();
	}

	void Read(Stream *in);
	void Write(Stream *out) const;

	// Return number of sections
	size_t GetSectionCount() const {
		return _sections.size();
	}
	// Insert new item *before* existing item
	ItemIterator InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value);
	// Insert new section *before* existing section
	SectionIterator InsertSection(SectionIterator sec, const String &name);
	// Remove a single item
	void RemoveItem(SectionIterator sec, ItemIterator item);
	// Completely remove whole section; this removes all lines between section
	// header and the last item found in that section (inclusive).
	void RemoveSection(SectionIterator sec);

private:
	LSections _sections;
};

} // namespace Shared
} // namespace AGS
} // namespace AGS3

#endif