mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-03 04:03:45 +02:00
229 lines
5.0 KiB
ObjectPascal
229 lines
5.0 KiB
ObjectPascal
unit ConfigFile;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils;
|
|
|
|
type
|
|
|
|
{ TConfigFile }
|
|
|
|
TConfigFile = class
|
|
private
|
|
FDirty: Boolean;
|
|
FFileName: string;
|
|
FSections: TStringList;
|
|
procedure LoadFromFile;
|
|
function AddSection(s: string): TStringList;
|
|
public
|
|
constructor Create(const AFileName: string);
|
|
destructor Destroy; override;
|
|
function ReadString(const Section, Ident, Default: string): string;
|
|
procedure WriteString(const Section, Ident, Value: String);
|
|
function ReadBool(const Section, Ident: string; Default: Boolean): Boolean;
|
|
procedure WriteBool(const Section, Ident: string; Value: Boolean);
|
|
procedure ReadSection(const Section: string; Strings: TStrings);
|
|
procedure WriteSection(const Section: string; Strings: TStrings);
|
|
procedure WriteSectionValues(const Section: string; Strings: TStrings);
|
|
function FindSection(Section: string): TStringList;
|
|
function SectionExists(const Section: string): Boolean;
|
|
procedure Flush;
|
|
property Dirty : Boolean Read FDirty;
|
|
property FileName: string read FFileName;
|
|
property Sections: TStringList read FSections;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TConfigFile }
|
|
|
|
constructor TConfigFile.Create(const AFileName: string);
|
|
begin
|
|
FSections := TStringList.Create;
|
|
FSections.OwnsObjects := True;
|
|
if AFileName = '' then
|
|
exit; //nothing to do
|
|
FFileName:=AFileName;
|
|
LoadFromFile;
|
|
end;
|
|
|
|
destructor TConfigFile.Destroy;
|
|
begin
|
|
Flush;
|
|
FreeAndNil(FSections); //recursive!
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TConfigFile.LoadFromFile;
|
|
var
|
|
lst, sec: TStringList;
|
|
s: string;
|
|
i: integer;
|
|
begin
|
|
if (FFileName = '') or not FileExists(FFileName) then
|
|
exit; //nothing to load
|
|
lst := TStringList.Create;
|
|
lst.LoadFromFile(FFileName);
|
|
sec := nil;
|
|
for i := 0 to lst.Count - 1 do begin
|
|
s := lst[i];
|
|
if s = '' then
|
|
continue;
|
|
if s[1] = '[' then
|
|
sec := AddSection(s)
|
|
else
|
|
sec.Add(s);
|
|
end;
|
|
lst.Free;
|
|
FDirty:=False; //in case it was set during initialization
|
|
end;
|
|
|
|
function TConfigFile.FindSection(Section: string): TStringList;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := nil;
|
|
if Section = '' then
|
|
exit;
|
|
if Section[1] = '[' then
|
|
Section := Copy(Section, 2, Length(Section)-2); //strip []
|
|
i := FSections.IndexOf(Section);
|
|
if i >= 0 then
|
|
TObject(Result) := FSections.Objects[i];
|
|
end;
|
|
|
|
function TConfigFile.SectionExists(const Section: string): Boolean;
|
|
begin
|
|
Result := FindSection(Section) <> nil;
|
|
end;
|
|
|
|
function TConfigFile.AddSection(s: string): TStringList;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := nil;
|
|
if s = '' then
|
|
exit;
|
|
if s[1] = '[' then
|
|
s := Copy(s, 2, Length(s)-2);
|
|
i := FSections.IndexOf(s);
|
|
if i < 0 then begin
|
|
Result := TStringList.Create;
|
|
FSections.AddObject(s, Result);
|
|
FDirty:=True;
|
|
end else
|
|
TObject(Result) := FSections.Objects[i];
|
|
end;
|
|
|
|
function TConfigFile.ReadString(const Section, Ident, Default: string): string;
|
|
var
|
|
sec: TStringList;
|
|
i: integer;
|
|
begin
|
|
sec := FindSection(Section);
|
|
if sec = nil then
|
|
exit(Default);
|
|
i := sec.IndexOfName(Ident);
|
|
if i < 0 then
|
|
Result := Default
|
|
else
|
|
Result := sec.ValueFromIndex[i];
|
|
end;
|
|
|
|
procedure TConfigFile.WriteString(const Section, Ident, Value: String);
|
|
var
|
|
sec: TStringList;
|
|
i: integer;
|
|
s: string;
|
|
begin
|
|
if (Ident = '') {or (Value = '')} then
|
|
exit; //invalid Ident
|
|
sec := AddSection(Section);
|
|
s := Ident + '=' + Value;
|
|
i := sec.IndexOf(s);
|
|
if i >= 0 then
|
|
exit; //already stored
|
|
i := sec.IndexOfName(ident);
|
|
if i < 0 then
|
|
sec.Add(s)
|
|
else
|
|
sec.Strings[i] := s;
|
|
FDirty:=True;
|
|
end;
|
|
|
|
function TConfigFile.ReadBool(const Section, Ident: string; Default: Boolean
|
|
): Boolean;
|
|
var
|
|
s: string;
|
|
begin
|
|
s := ReadString(Section, Ident, '');
|
|
if s = '' then
|
|
Result := Default
|
|
else
|
|
Result := s <> '0';
|
|
end;
|
|
|
|
procedure TConfigFile.WriteBool(const Section, Ident: string; Value: Boolean);
|
|
const
|
|
aValues: array[boolean] of string = ('0', '1');
|
|
begin
|
|
WriteString(Section, Ident, aValues[Value]);
|
|
end;
|
|
|
|
procedure TConfigFile.ReadSection(const Section: string; Strings: TStrings);
|
|
var
|
|
sec: TStringList;
|
|
begin
|
|
Strings.Clear;
|
|
sec := FindSection(Section);
|
|
if sec <> nil then
|
|
Strings.Assign(sec);
|
|
end;
|
|
|
|
procedure TConfigFile.WriteSection(const Section: string; Strings: TStrings);
|
|
var
|
|
sec: TStringList;
|
|
begin
|
|
if Strings = nil then
|
|
exit;
|
|
if Strings.Count = 0 then
|
|
exit; //delete section???
|
|
sec := AddSection(Section);
|
|
if not sec.Equals(Strings) then begin
|
|
sec.Assign(Strings);
|
|
FDirty:=True;
|
|
end;
|
|
end;
|
|
|
|
procedure TConfigFile.WriteSectionValues(const Section: string;
|
|
Strings: TStrings);
|
|
begin
|
|
WriteSection(Section, Strings);
|
|
end;
|
|
|
|
procedure TConfigFile.Flush;
|
|
var
|
|
lst, sec: TStringList;
|
|
i: integer;
|
|
s: string;
|
|
begin
|
|
if (not FDirty) or (FFileName = '') then
|
|
exit;
|
|
lst := TStringList.Create;
|
|
for i := 0 to FSections.Count - 1 do begin
|
|
s := FSections[i];
|
|
TObject(sec) := FSections.Objects[i];
|
|
lst.Add('[' + s + ']');
|
|
lst.AddStrings(sec);
|
|
end;
|
|
lst.SaveToFile(FFileName);
|
|
lst.Free;
|
|
FDirty:=False;
|
|
end;
|
|
|
|
end.
|
|
|