WinSkinIni.pas
上传用户:xjwsee
上传日期:2008-08-02
资源大小:796k
文件大小:14k
- unit WinSkinIni;
- {$B-}
- interface
- uses Classes,winconvert;
- type
- { TQuickIni class }
- TQuickIni = class(TObject)
- private
- FAuto : boolean;
- FFileName: String;
- FIniFile : TStrings;
- function GetName(const Line: String): String;
- function GetValue(const Line, Name: String): String;
- function GetSectionIndex(const Section: String): Integer;
- function IsSection(const Line: String): Boolean;
- procedure SetFileName(Value: string);
- procedure SetIniFile(Value: TStrings);
- protected
- FSections: TStrings;
- procedure Compress(source,dest:TStream);
- procedure Decompress(source,Dest:TStream);
- public
- constructor Create;
- destructor Destroy; override;
- procedure LoadFromFile(aname:string);
- procedure SaveToFile(aname:string);
- procedure LoadFromStream(Stream: TStream);
- procedure SaveToStream(Stream:Tstream);
- procedure LoadFromZip(aname:string);
- procedure SavetoZip(aname:string);
- procedure DeleteKey(const Section, Ident: String);
- procedure EraseSection(const Section: String);
- function ReadBool(const Section, Ident: String; Default: Boolean): Boolean;
- function ReadInteger(const Section, Ident: String; Default: Longint): Longint;
- procedure ReadSection(const Section: AnsiString; Strings: TStrings);
- procedure ReadSections(Strings: TStrings);
- procedure ReadSectionValues(const Section: String; Strings: TStrings);
- function ReadString(const Section, Ident: AnsiString; Default: AnsiString): AnsiString;
- procedure RebuildSections;
- procedure WriteBool(const Section, Ident: String; Value: Boolean);
- procedure WriteInteger(const Section, Ident: String; Value: Longint);
- procedure WriteString(const Section, Ident: String; Value: String);
- property FileName: String read FFileName write SetFileName;
- property AutoSaveLoad: boolean read FAuto write FAuto;
- property IniFile: TStrings read FIniFile write SetIniFile;
- procedure Clear;
- end;
- implementation
- uses SysUtils;
- const
- SStringsUnassignedError = 'The parameter Strings is unassigned!';
- StartBracket = '[';
- EndBracket = ']';
- Separator = '=';
- { TQuickIni }
- constructor TQuickIni.Create;
- begin
- FAuto := False;
- FIniFile := TStringList.Create;
- FSections := TStringList.Create;
- // if FileExists(FileName) then
- // LoadFromFile;
- end;
- destructor TQuickIni.Destroy;
- begin
- FSections.Free;
- FIniFile.Free;
- // Finalize(FFileName);
- end;
- function TQuickIni.GetName(const Line: String): String;
- var
- I: Integer;
- begin
- I := Pos(Separator, Line);
- if I <> 0 then
- Result := Trim(Copy(Line, 1, I-1))
- else
- Result := EmptyStr;
- result:=lowercase(result);
- end;
- function TQuickIni.GetValue(const Line, Name: String): String;
- var
- I: Integer;
- begin
- Result := EmptyStr;
- if (Line <> EmptyStr) and (Name <> EmptyStr) then
- begin
- I := Pos(Separator, Line);
- if (Name = GetName(Line)) and (I <> 0) then
- Result := Trim(System.Copy(Line, I+1, Maxint));
- end;
- end;
- function TQuickIni.IsSection(const Line: String): Boolean;
- var
- S: String;
- begin
- Result := False;
- if Line <> EmptyStr then
- begin
- S := Trim(Line);
- if (S[1] = StartBracket) and (S[System.Length(S)] = EndBracket) then
- Result := True;
- end;
- end;
- function TQuickIni.GetSectionIndex(const Section: String): Integer;
- begin
- Result := FSections.IndexOf(StartBracket + Section + EndBracket);
- if Result >= 0 then
- Result := Integer(FSections.Objects[Result])
- else
- Result := -1;
- end;
- procedure TQuickIni.Decompress(source,Dest:TStream);
- var
- LZH: TLZH;
- Size, Bytes: Longint;
- begin
- // Decompress in memory blob.
- LZH := TLZH.Create;
- try
- LZH.StreamIn:= source;
- LZH.StreamOut:=dest;
- LZH.StreamIn.Position := 0;
- LZH.StreamOut.Position := 0;
- // Uncompressed file size
- LZH.StreamIn.Read(size, sizeof(Longint));
- Bytes := Size;
- // Decompress rest of stream.
- LZH.LZHUnpack(Bytes, LZH.GetBlockStream, LZH.PutBlockStream);
- finally
- LZH.Free;
- end;
- end;
- procedure TQuickIni.compress(source,dest:TStream);
- var
- LZH: TLZH;
- Size, Bytes: Longint;
- begin
- // Decompress in memory blob.
- LZH := TLZH.Create;
- try
- LZH.StreamIn := Source;
- LZH.StreamOut := dest;
- LZH.StreamIn.Position := 0;
- LZH.StreamOut.Position := 0;
- //write uncompressed size
- Size := LZH.StreamIn.Size;
- LZH.StreamOut.Write(Size, sizeof(Longint));
- // Compress stream.
- LZH.LZHPack(Bytes, LZH.GetBlockStream, LZH.PutBlockStream);
- finally
- LZH.Free;
- end;
- end;
- procedure TQuickIni.LoadFromZip(aname:string);
- var
- r,r2: TMemoryStream;
- begin
- r:=Tmemorystream.create;
- r2:=Tmemorystream.create;
- try
- r2.loadfromfile(aname);
- Decompress(r2,r);
- r.Seek(0,soFromBeginning);
- loadfromstream(r);
- finally
- r.free;
- r2.free;
- end;
- end;
- procedure TQuickIni.SavetoZip(aname:string);
- var
- m,m2: TMemoryStream;
- begin
- m:=Tmemorystream.create;
- m2:=Tmemorystream.create;
- try
- savetostream(m);
- compress(m,m2);
- m2.savetofile(aname);
- finally
- m.free;
- m2.free;
- end;
- end;
- procedure TQuickIni.LoadFromFile(aname:string);
- var
- Stream: TStream;
- Ptr, Start: PChar;
- StmStr,Str: string;
- Size : integer;
- I : integer;
- begin
- Stream := TFileStream.Create(aname, fmOpenRead or fmShareDenyWrite);
- LoadFromStream(Stream);
- Stream.Free;
- end;
- procedure TQuickIni.LoadFromStream(Stream: TStream);
- var
- Ptr, Start: PAnsiChar;
- StmStr,Str: Ansistring;
- Size : integer;
- I : integer;
- begin
- if not assigned(Stream) then exit;
- FIniFile.BeginUpdate;
- FSections.BeginUpdate;
- try
- Size := Stream.Size - Stream.Position;
- SetString(StmStr, nil, Size);
- Stream.Read(Pointer(StmStr)^, Size);
- FIniFile.Clear;
- FSections.Clear;
- Ptr := Pointer(StmStr);
- I := 0;
- if Ptr <> nil then
- while Ptr^ <> #0 do
- begin
- Start := Ptr;
- while not (Ptr^ in [#0, #10, #13]) do
- Inc(Ptr);
- SetString(Str, Start, Ptr - Start);
- Str := Trim(Str);
- if (Str <> '') and (Str[1] <> ';') then
- begin
- FIniFile.Add(Str);
- if (Str[1] = '[') and (Str[Length(Str)] = ']') then
- begin
- FSections.AddObject(Trim(Str),TObject(I));
- end;
- inc(I);
- end;
- if Ptr^ = #13 then Inc(Ptr);
- if Ptr^ = #10 then Inc(Ptr);
- end;
- finally
- FSections.EndUpdate;
- FIniFile.EndUpdate;
- end;
- end;
- procedure TQuickIni.SaveToFile(aname:string);
- begin
- // if AutoSaveLoad then
- FIniFile.SaveToFile(aname);
- end;
- procedure TQuickIni.SaveToStream(Stream:Tstream);
- begin
- // if AutoSaveLoad then
- if assigned(stream) then
- FIniFile.SaveTostream(stream);
- end;
- { Read all Names of one Section }
- procedure TQuickIni.ReadSection(const Section: AnsiString; Strings: TStrings);
- var
- I: Integer;
- N: String;
- begin
- Assert(Assigned(Strings), SStringsUnassignedError);
- Strings.BeginUpdate;
- try
- Strings.Clear;
- if FIniFile.Count > 0 then
- begin
- I := GetSectionIndex(Section);
- if I <> -1 then
- begin
- Inc(I);
- while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
- begin
- N := GetName(FIniFile[I]);
- if N <> EmptyStr then Strings.Add(N);
- Inc(I);
- end;
- end;
- end;
- finally
- Strings.EndUpdate;
- end;
- end;
- { Read all Sections of the Ini-File }
- procedure TQuickIni.ReadSections(Strings: TStrings);
- var
- I: Integer;
- Section: String;
- begin
- Assert(Assigned(Strings), SStringsUnassignedError);
- Strings.Assign(FSections);
- I := 0;
- while I < Strings.Count do
- begin
- Strings.Objects[I] := Nil;
- Section := Trim(Strings.Strings[I]);
- System.Delete(Section, 1, 1);
- System.Delete(Section, System.Length(Section), 1);
- Strings.Strings[I] := Trim(Section);
- Inc(I);
- end;
- end;
- { Reads a String-Value of Ident in one Section.
- The result is Default if
- o Section doesn't exists
- o Ident doesn't exists
- o Ident doesn't have any assigned value }
- function TQuickIni.ReadString(const Section, Ident: AnsiString; Default: AnsiString): AnsiString;
- var
- I: Integer;
- V,s: AnsiString;
- begin
- Result := Default;
- s:=lowercase(ident);
- if FIniFile.Count > 0 then
- begin
- I := GetSectionIndex(Section);
- if I <> -1 then
- begin
- Inc(I);
- while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
- begin
- if GetName(FIniFile[I]) = s then
- begin
- V := GetValue(FIniFile[I], s);
- if V <> EmptyStr then
- Result := V;
- break;
- end;
- Inc(I);
- end;
- end;
- end;
- end;
- { Reads an Integer-Value of Ident in one Section }
- function TQuickIni.ReadInteger(const Section, Ident: String; Default: Longint): Longint;
- var
- IntStr: ansistring;
- 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 := '$' + System.Copy(IntStr, 3, Maxint);
- Result := StrToIntDef(IntStr, Default);
- end;
- { Reads a Bool-Value of Ident in one Section }
- function TQuickIni.ReadBool(const Section, Ident: String; Default: Boolean): Boolean;
- begin
- Result := ReadInteger(Section, Ident, Ord(Default)) <> 0;
- end;
- { Reads all Names + Values of one Section }
- procedure TQuickIni.ReadSectionValues(const Section: String; Strings: TStrings);
- var
- I: Integer;
- begin
- Assert(Assigned(Strings), SStringsUnassignedError);
- Strings.BeginUpdate;
- try
- Strings.Clear;
- if FIniFile.Count > 0 then
- begin
- I := GetSectionIndex(Section);
- if I <> -1 then
- begin
- Inc(I);
- while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
- begin
- if (FIniFile[I] <> '') then
- Strings.Add(FIniFile[I]);
- Inc(I);
- 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 TQuickIni.WriteString(const Section, Ident: String; Value: String);
- var
- I: Integer;
- Q : integer;
- s:string;
- begin
- I := GetSectionIndex(Section);
- s:=lowercase(ident);
- // Section exists
- if I >= 0 then
- begin
- Inc(I);
- while (I < FIniFile.Count) and not IsSection(FIniFile[I])
- and (GetName(FIniFile[I]) <> s) do
- begin
- Inc(I);
- end;
- // End of File or Ident doesn't exists in the Section
- if (I >= FIniFile.Count) then
- begin
- if Ident <> EmptyStr then
- begin
- FIniFile.Add(Ident + Separator + Value);
- end
- end
- else if (I < FIniFile.Count) and IsSection(FIniFile[I]) then
- begin
- if Ident <> EmptyStr then
- begin
- FIniFile.Insert(I,Ident + Separator + Value);
- Inc(I);
- Q := FSections.IndexOf(FIniFile[I]);
- FSections.Objects[Q] := TObject(I+1);
- end
- end
- // Ident does exists in the section
- else if Ident <> EmptyStr then
- begin
- FIniFile[I] := Ident + Separator + Value;
- end;
- end
- // Section doesn't exists, so add new [Section] with Ident=Value
- else
- begin
- I := FIniFile.Add(StartBracket + Section + EndBracket);
- FSections.AddObject(StartBracket + Section + EndBracket,TObject(I));
- if Ident <> EmptyStr then
- begin
- FIniFile.Add(Ident + Separator + Value);
- end;
- end;
- // SaveToFile;
- end;
- { Writes an Integer-Value for Ident in one Section }
- procedure TQuickIni.WriteInteger(const Section, Ident: String; Value: Longint);
- begin
- WriteString(Section, Ident, IntToStr(Value));
- end;
- { Writes a Bool-Value for Ident in one Section }
- procedure TQuickIni.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 TQuickIni.DeleteKey(const Section, Ident: String);
- var
- I: Integer;
- begin
- I := GetSectionIndex(Section);
- if I <> -1 then
- begin
- Inc(I);
- while (I < FIniFile.Count) and not IsSection(FIniFile[I]) and
- (GetName(FIniFile[I]) <> Ident) do Inc(I);
- // Ident does exists
- if not (I >= FIniFile.Count) and not IsSection(FIniFile[I]) then
- begin
- FIniFile.Delete(I);
- // SaveToFile;
- end;
- end;
- end;
- procedure TQuickIni.EraseSection(const Section: String);
- var
- I: Integer;
- begin
- I := GetSectionIndex(Section);
- if I <> -1 then
- begin
- // Delete Section-Header
- FIniFile.Delete(I);
- // Delete Section-Items
- while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
- FIniFile.Delete(I);
- if I > 0 then FIniFile.Insert(I, EmptyStr);
- // SaveToFile;
- end;
- end;
- procedure TQuickIni.SetFileName(Value: string);
- begin
- if Value <> FFileName then
- begin
- FFileName := Value;
- // if FileExists(Value) and FAuto then
- // LoadFromFile;
- end;
- end;
- procedure TQuickIni.SetIniFile(Value: TStrings);
- begin
- FIniFile.Assign(Value);
- RebuildSections;
- end;
- procedure TQuickIni.RebuildSections;
- Var
- I : integer;
- Count : integer;
- begin
- FSections.Clear;
- I := 0;
- Count := FIniFile.Count;
- while I < Count do
- begin
- if (FIniFile[I] <> '') and (FIniFile[I][1] = '[') and (FIniFile[I][Length(FIniFile[I])] = ']') then
- begin
- if assigned(FSections) then
- FSections.AddObject(Trim(FIniFile[I]),TObject(I));
- end;
- inc(I);
- end;
- end;
- procedure TQuickIni.Clear;
- begin
- FIniFile.Clear;
- FSections.Clear;
- end;
- end.