123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- {
- $Id$
- This file is part of the Free Component Library (FCL)
- Copyright (c) 1999-2000 by Michael A. Hess
- Old inifiles unit adapted for fpcmake
- 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.
- **********************************************************************}
- unit MakeIni;
- {$mode objfpc}
- {$H+}
- interface
- uses Classes;
- type
- { TIniFile class }
- TIniFile = class(TObject)
- private
- FEscapeLineFeeds : Boolean;
- FFileName : string;
- FStream : TStream;
- FFileBuffer : TStringList;
- function GetName(const line : string) : string;
- function GetValue(const line, name : string) : string;
- function IsComment(const line : string) : boolean;
- function IsSection(const line : string) : boolean;
- function GetSectionIndex(const section : string) : integer;
- protected
- procedure SetFileName(const fn:string);
- procedure SetStream(s:TStream);
- procedure LoadFromFile;
- procedure SaveToFile;
- procedure LoadFromStream;
- procedure SaveToStream;
- public
- constructor Create(const theFileName : string);
- constructor Create(s:TStream);
- destructor Destroy; override;
- procedure DeleteKey(const section, ident : string);
- procedure EraseSection(const section : string);
- function ReadBool(const section, ident : string; defaultValue : boolean) : boolean;
- function ReadInteger(const section, ident : string; defaultValue : longint) : longint;
- procedure ReadSection(const section : string; strings : TStrings);
- procedure ReadSections(strings : TStrings);
- procedure ReadSectionValues(const section : string; strings : TStrings);
- procedure ReadSectionRaw(const section : string; strings : TStrings);
- function ReadString(const section, ident, defaultValue : string) : string;
- procedure WriteBool(const section, ident : string; value : boolean);
- procedure WriteInteger(const section, ident : string; value : longint);
- procedure WriteString(const section, ident, value : string);
- property FileName : String read FFileName;
- property EscapeLineFeeds : Boolean Read FEscapeLineFeeds Write FEscapeLineFeeds default false;
- end;
- implementation
- uses SysUtils;
- const
- brackets : array[0..1] of Char = ('[', ']');
- separator : Char = '=';
- comment : Char = ';';
- { TIniFile }
- constructor TIniFile.Create(const theFileName : string);
- begin
- FFileName := theFileName;
- FStream:=nil;
- FEscapeLineFeeds:=False;
- FFileBuffer := TStringList.Create;
- if FileExists(fileName) then
- LoadFromFile;
- end;
- constructor TIniFile.Create(s:TStream);
- begin
- FFileName := '';
- FStream:=s;
- FEscapeLineFeeds:=False;
- FFileBuffer := TStringList.Create;
- LoadFromStream;
- end;
- destructor TIniFile.Destroy;
- begin
- FFileBuffer.Free;
- end;
- function TIniFile.GetName(const line : string) : string;
- var
- index,index2 : integer;
- begin
- Result := '';
- index := Pos(separator, line);
- if index <> 0 then
- begin
- index2:=Pos(comment, line);
- if (index2=0) or (index2>index) then
- result := Trim(Copy(line, 1, index - 1));
- end;
- end;
- function TIniFile.GetValue(const line, name : string) : string;
- var
- index1,index2,index3 : integer;
- begin
- result := '';
- if (line <> '') and (name <> '') then
- begin
- index1 := Pos(name, line);
- index2 := Pos(separator, line);
- index3 := Pos(comment, line);
- if index3=0 then
- index3:=MaxInt;
- if (index1 <> 0) and (index2 <> 0) and (index2 > index1) then
- result := Trim(Copy(line, index2 + 1, index3));
- end;
- end;
- function TIniFile.IsSection(const line : string) : boolean;
- var
- str : string;
- begin
- result := False;
- if line <> '' then
- begin
- str := Trim(line);
- if (str[1] = brackets[0]) and (str[Length(str)] = brackets[1]) then
- result := True;
- end;
- end;
- function TIniFile.IsComment(const line : string) : boolean;
- var
- str : string;
- begin
- result := False;
- if line <> '' then
- begin
- str := Trim(line);
- result := (str[1]=comment);
- end;
- end;
- function TIniFile.GetSectionIndex(const section : string) : integer;
- begin
- result := FFileBuffer.IndexOf(brackets[0] + section + brackets[1]);
- end;
- { Load/Save }
- procedure TIniFile.SetFileName(const fn:string);
- begin
- FFileName:=fn;
- end;
- procedure TIniFile.SetStream(s:TStream);
- begin
- FStream:=s;
- end;
- procedure TIniFile.LoadFromFile;
- begin
- if FFileName<>'' then
- FFileBuffer.LoadFromFile(FFileName);
- end;
- procedure TIniFile.SaveToFile;
- begin
- if FFileName<>'' then
- FFileBuffer.SaveToFile(FFileName);
- end;
- procedure TIniFile.LoadFromStream;
- begin
- if assigned(FStream) then
- FFileBuffer.LoadFromStream(FStream);
- end;
- procedure TIniFile.SaveToStream;
- begin
- if assigned(FStream) then
- FFileBuffer.SaveToStream(FStream);
- end;
- { Read all Names of one Section }
- procedure TIniFile.ReadSection(const section : string; strings : TStrings);
- var
- index : integer;
- name : string;
- begin
- strings.BeginUpdate;
- try
- strings.Clear;
- if FFileBuffer.Count > 0 then
- begin
- index := GetSectionIndex(section);
- if index <> -1 then
- begin
- Inc(index);
- while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
- begin
- name := GetName(FFileBuffer[index]);
- if name <> '' then
- strings.Add(name);
- Inc(index);
- end;
- end;
- end;
- finally
- strings.EndUpdate;
- end;
- end;
- { Read all Sections of the Ini-File }
- procedure TIniFile.ReadSections(strings : TStrings);
- var
- index : integer;
- section : string;
- begin
- strings.BeginUpdate;
- try
- strings.Clear;
- if FFileBuffer.Count > 0 then
- begin
- index := 0;
- while (index < FFileBuffer.Count) do
- begin
- if IsSection(FFileBuffer[index]) then
- begin
- section := Trim(FFileBuffer[index]);
- Delete(section, 1, 1);
- Delete(section, Length(section), 1);
- strings.Add(Trim(section));
- end;
- Inc(index);
- end;
- end;
- finally
- strings.EndUpdate;
- end;
- end;
- { Reads a String-Value of "ident" in one "section".
- The result is "defaultValue" if
- o section doesn't exists
- o ident doesn't exists
- o ident doesn't have any assigned value }
- function TIniFile.ReadString(const section, ident, defaultValue : string) : string;
- var
- index : integer;
- value : string;
- begin
- result := defaultValue;
- if FFileBuffer.Count > 0 then
- begin
- index := GetSectionIndex(section);
- if index <> -1 then
- begin
- Inc(index);
- while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
- begin
- if CompareText(GetName(FFileBuffer[index]),ident)=0 then
- begin
- value := GetValue(FFileBuffer[index], ident);
- if value <> '' then
- begin
- result := value;
- if EscapeLineFeeds and (result[length(result)]='\') then
- begin
- inc(index);
- while (index < FFileBuffer.Count) and (result[length(result)]='\') do
- begin
- result:=Copy(result,1,length(result)-1)+Trim(FFileBuffer[index]);
- inc(index);
- end;
- end;
- end;
- break;
- end;
- Inc(index);
- end;
- end;
- end;
- end;
- { Reads an Integer-Value of Ident in one Section }
- function TIniFile.ReadInteger(const section, ident : string; defaultValue : longint) : longint;
- var
- intStr : string;
- begin
- intStr := ReadString(section, ident, '');
- { convert a Hex-Value }
- if (Length(intStr) > 2) and (intStr[1] = '0') and ((intStr[2] = 'X') or (intStr[2] = 'x')) then
- intStr := '$' + Copy(intStr, 3, Maxint);
- result := StrToIntDef(intStr, defaultValue);
- end;
- { Reads a Bool-Value of Ident in one Section }
- function TIniFile.ReadBool(const section, ident : string; defaultValue : boolean) : boolean;
- begin
- result := ReadInteger(section, ident, Ord(defaultValue)) <> 0;
- end;
- { Reads all Names + Values of one Section }
- procedure TIniFile.ReadSectionValues(const section : string; strings : TStrings);
- var
- name : string;
- value : string;
- index : integer;
- begin
- strings.BeginUpdate;
- try
- strings.Clear;
- if FFileBuffer.Count > 0 then
- begin
- index := GetSectionIndex(section);
- if index <> -1 then
- begin
- Inc(index);
- while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
- begin
- name := GetName(FFileBuffer[index]);
- if name <> '' then
- begin
- value := GetValue(FFileBuffer[index], name);
- strings.Add(name + separator + value);
- end;
- Inc(index);
- end;
- end;
- end;
- finally
- strings.EndUpdate;
- end;
- end;
- procedure TIniFile.ReadSectionRaw(const section : string; strings : TStrings);
- var
- eols,index : integer;
- begin
- strings.BeginUpdate;
- try
- eols:=0;
- strings.Clear;
- if FFileBuffer.Count > 0 then
- begin
- index := GetSectionIndex(section);
- if index <> -1 then
- begin
- Inc(index);
- while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
- begin
- { Skip empty lines at the end of the section }
- if FFileBuffer[index]='' then
- inc(eols)
- else
- begin
- while eols>0 do
- begin
- Strings.Add('');
- dec(eols);
- end;
- if not IsComment(FFileBuffer[index]) then
- strings.Add(FFileBuffer[index]);
- end;
- Inc(index);
- end;
- end;
- end;
- finally
- strings.EndUpdate;
- end;
- end;
- { Writes a String-Value for Ident in one Section.
- Note: If Section and/or Ident don't exist, they will be placed in the Ini-File }
- procedure TIniFile.WriteString(const section, ident, value : string);
- var
- index : integer;
- begin
- index := GetSectionIndex(section);
- { Section exists }
- if index <> -1 then
- begin
- Inc(index);
- while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) and
- (GetName(FFileBuffer[index]) <> ident) do
- Inc(index);
- if (index >= FFileBuffer.Count) or IsSection(FFileBuffer[index]) then
- begin { End of File or ident doesn't exists in the section }
- if ident <> '' then
- FFileBuffer.Insert(index, ident + separator + value);
- end
- else if ident <> '' then { Ident does exists in the section }
- FFileBuffer[index] := ident + separator + value;
- end
- else { section doesn't exists, so add new [section] with ident=value }
- begin
- FFileBuffer.Add('');
- FFileBuffer.Add(brackets[0] + section + brackets[1]);
- if ident <> '' then
- FFileBuffer.Add(ident + separator + value);
- end;
- SaveToFile;
- end;
- { Writes an Integer-Value for Ident in one Section }
- procedure TIniFile.WriteInteger(const section, ident : string; value : longint);
- begin
- WriteString(section, ident, IntToStr(value));
- end;
- { Writes a Bool-Value for Ident in one Section }
- procedure TIniFile.WriteBool(const section, ident : string; value : boolean);
- const
- values: array[boolean] of string = ('0', '1');
- begin
- WriteString(section, ident, values[Value]);
- end;
- { Deletes the value of ident in one section.
- Note: Only if section and ident exist, the value of ident will be set to NULL }
- procedure TIniFile.DeleteKey(const section, ident : string);
- var
- index : integer;
- begin
- index := GetSectionIndex(section);
- if index <> -1 then
- begin
- Inc(index);
- while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) and
- (GetName(FFileBuffer[index]) <> ident) do
- Inc(index);
- if not (index >= FFileBuffer.Count) and not IsSection(FFileBuffer[index]) then
- begin { Ident does exists }
- FFileBuffer.Delete(index);
- SaveToFile;
- end;
- end;
- end;
- { Erases the whole Section from an Ini-File }
- procedure TIniFile.EraseSection(const section : string);
- var
- index : integer;
- begin
- index := GetSectionIndex(section);
- if index <> -1 then
- begin
- FFileBuffer.Delete(index); { Delete Section-Header }
- while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
- FFileBuffer.Delete(index); { Delete Section-Items }
- if index > 0 then FFileBuffer.Insert(index, '');
- SaveToFile;
- end;
- end;
- end.
- {
- $Log$
- Revision 1.1 2000-05-11 17:59:12 peter
- * makeini unit added as replacement for old inifiles unit
- }
|