DEADSOFTWARE

44866f41e1cc0195ba10cd98fe6735128d0048c3
[d2df-sdl.git] / src / shared / CONFIG.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE a_modes.inc}
17 unit CONFIG;
19 interface
21 {$IFDEF USE_MEMPOOL}
22 uses
23 mempool;
24 {$ENDIF}
26 type
27 TParam = record
28 Param: ShortString;
29 Value: ShortString;
30 Section: Word;
31 end;
33 TConfig = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
34 private
35 FParams: array of TParam;
36 FSections: array of ShortString;
37 FCurrentSection: Word;
38 function ReadParam(Section, Param, Default: string): string;
39 procedure WriteParam(Section, Param, Value: string);
40 procedure ProcessStr(Str: string);
41 public
42 constructor Create();
43 constructor CreateFile(FileName: string);
44 constructor CreateMem(pData: Pointer; _Length: LongWord);
45 destructor Destroy(); override;
46 procedure FreeConfig();
47 procedure SaveFile(FileName: string);
48 function ReadInt(Section, Param: string; Default: Integer): Integer;
49 function ReadStr(Section, Param: string; Default: String): string;
50 function ReadBool(Section, Param: string; Default: Boolean): Boolean;
51 function SectionExists(Section: string): Boolean;
52 procedure WriteInt(Section, Param: string; Value: Integer);
53 procedure WriteStr(Section, Param, Value: string);
54 procedure WriteBool(Section, Param: string; Value: Boolean);
55 end;
57 implementation
59 uses
60 SysUtils, utils;
62 { TConfig }
64 constructor TConfig.Create();
65 begin
66 inherited Create;
68 FreeConfig();
69 end;
71 constructor TConfig.CreateFile(FileName: string);
72 var
73 f: TextFile;
74 a: string;
75 begin
76 FreeConfig();
78 if not FileExists(FileName) then Exit;
80 AssignFile(f, FileName);
81 Reset(f);
82 while not EOF(f) do
83 begin
84 Readln(f, a);
85 ProcessStr(a);
86 end;
87 CloseFile(f);
88 end;
90 constructor TConfig.CreateMem(pData: Pointer; _Length: LongWord);
91 var
92 a: Integer;
93 str: string;
94 begin
95 FreeConfig();
97 if _Length = 0 then Exit;
98 if pData = nil then Exit;
100 SetLength(str, _Length);
102 CopyMemory(@str[1], pData, _Length);
104 while Str <> '' do
105 begin
106 for a := 2 to Length(Str) do
107 if (Str[a-1]+Str[a] = #13#10) or (a = Length(Str)) then
108 begin
109 if a <> Length(Str) then ProcessStr(Copy(Str, 1, a-2)) else ProcessStr(Str);
110 Delete(Str, 1, a);
111 Str := Trim(Str);
112 Break;
113 end;
114 end;
115 end;
117 destructor TConfig.Destroy();
118 begin
119 FParams := nil;
120 FSections := nil;
122 inherited;
123 end;
125 procedure TConfig.FreeConfig();
126 begin
127 FParams := nil;
128 FSections := nil;
130 SetLength(FSections, 1);
131 FSections[0] := '';
132 FCurrentSection := 0;
133 end;
135 procedure TConfig.ProcessStr(Str: string);
136 var
137 a, l: Integer;
138 begin
139 Str := Trim(Str);
141 if (Str <> '') and (Length(Str) > 2) and (Str[1] <> ';') then
142 begin
143 l := Length(Str);
145 if Pos('=', Str) > 0 then
146 begin
147 SetLength(FParams, Length(FParams)+1);
149 with FParams[High(FParams)] do
150 begin
151 a := Pos('=', Str);
152 Param := Trim(Copy(Str, 1, a-1));
153 Value := Trim(Copy(Str, a+1, l));
154 Section := FCurrentSection;
155 end;
156 end
157 else if (Str[1] = '[') and (Str[l] = ']') then
158 begin
159 SetLength(FSections, Length(FSections)+1);
160 FCurrentSection := High(FSections);
161 FSections[FCurrentSection] := Trim(Copy(Str, 2, l-2));
162 end;
163 end;
164 end;
166 function TConfig.ReadBool(Section, Param: string; Default: Boolean): Boolean;
167 var
168 a: Integer;
169 begin
170 if Default then a := 1 else a := 0;
172 Result := StrToIntDef(ReadParam(Section, Param, IntToStr(a)), a) <> 0;
173 end;
175 function TConfig.ReadInt(Section, Param: string; Default: Integer): Integer;
176 begin
177 Result := StrToIntDef(ReadParam(Section, Param, IntToStr(Default)), Default);
178 end;
180 function TConfig.ReadParam(Section, Param, Default: string): string;
181 var
182 a: Integer;
183 s: Word;
184 ok: Boolean;
185 p: string;
186 begin
187 Result := default;
189 if FParams = nil then Exit;
190 if FSections = nil then Exit;
192 ok := False;
193 s := 0;
194 for a := 0 to High(FSections) do
195 if LowerCase(FSections[a]) = LowerCase(Section) then
196 begin
197 s := a;
198 ok := True;
199 end;
201 if not ok then Exit;
203 p := LowerCase(Param);
205 for a := 0 to High(FParams) do
206 if (FParams[a].Section = s) and (LowerCase(FParams[a].Param) = p) then
207 begin
208 Result := FParams[a].Value;
209 Break;
210 end;
211 end;
213 function TConfig.ReadStr(Section, Param, Default: string): string;
214 begin
215 Result := ReadParam(Section, Param, Default);
216 end;
218 procedure TConfig.SaveFile(FileName: string);
219 var
220 f: TextFile;
221 a: Integer;
222 b: Integer;
223 begin
224 AssignFile(f, FileName);
225 Rewrite(f);
226 if (FSections <> nil) or (FParams <> nil) then
227 begin
228 if FSections <> nil then
229 for a := 0 to High(FSections) do
230 begin
231 if FSections[a] <> '' then Writeln(f, '['+FSections[a]+']');
233 if FParams <> nil then
234 for b := 0 to High(FParams) do
235 if FParams[b].Section = a then WriteLn(f, FParams[b].Param+'='+FParams[b].Value);
237 if (a <> High(FSections)) and (FSections[a] <> '') then WriteLn(f, '');
238 end;
239 end;
240 CloseFile(f);
241 end;
243 function TConfig.SectionExists(Section: string): Boolean;
244 var
245 a: Integer;
246 begin
247 Result := False;
249 if FSections = nil then Exit;
251 Section := LowerCase(Section);
253 for a := 0 to High(FSections) do
254 if Section = LowerCase(FSections[a]) then
255 begin
256 Result := True;
257 Exit;
258 end;
259 end;
261 procedure TConfig.WriteBool(Section, Param: string; Value: Boolean);
262 begin
263 WriteParam(Section, Param, BoolToStr(Value));
264 end;
266 procedure TConfig.WriteInt(Section, Param: string; Value: Integer);
267 begin
268 WriteParam(Section, Param, IntToStr(Value));
269 end;
271 procedure TConfig.WriteParam(Section, Param, Value: string);
272 var
273 a, b: Integer;
274 ok: Boolean;
275 begin
276 a := 0;
277 b := 0;
279 ok := False;
281 if FSections <> nil then
282 for a := 0 to High(FSections) do
283 if FSections[a] = Section then
284 begin
285 ok := True;
286 Break;
287 end;
289 if not ok then
290 begin
291 SetLength(FSections, Length(FSections)+1);
292 a := High(FSections);
293 FSections[a] := Section;
294 end;
296 ok := False;
297 if FParams <> nil then
298 for b := 0 to High(FParams) do
299 if (LowerCase(FParams[b].Param) = LowerCase(Param)) and (FParams[b].Section = a) then
300 begin
301 ok := True;
302 Break;
303 end;
305 if ok then FParams[b].Value := Value
306 else
307 begin
308 SetLength(FParams, Length(FParams)+1);
309 FParams[High(FParams)].Param := Param;
310 FParams[High(FParams)].Value := Value;
311 FParams[High(FParams)].Section := a;
312 end;
313 end;
315 procedure TConfig.WriteStr(Section, Param, Value: string);
316 begin
317 WriteParam(Section, Param, Value);
318 end;
320 end.