unit ChecksumList; { Martin Harvey 29/5/2000 } interface uses SimpleSync, Classes, SysUtils; type TChecksumList = class private FCheckList: TList; FSync: TSimpleSynchronizer; protected { Find function returns -1 if not found } function FindFileIndex(FileName: string): integer; function NoLockGetFileList: TStringList; function NoLockGetChecksum(FileName: string): integer; public constructor Create; destructor Destroy; override; procedure SetChecksum(FileName: string; Checksum: integer); procedure RemoveChecksum(FileName: string); function GetChecksum(FileName: string): integer; function GetFileList: TStringList; function GetChecksumList: TStringList; end; implementation type TCheckSum = record FileName: string; Checksum: integer; end; PCheckSum = ^TCheckSum; constructor TChecksumList.Create; begin inherited Create; FCheckList := TList.Create; FSync := TSimpleSynchronizer.Create; end; destructor TCheckSumList.Destroy; var iter: integer; CurSum: PCheckSum; begin if FCheckList.Count > 0 then begin for iter := 0 to FCheckList.Count - 1 do begin CurSum := PCheckSum(FCheckList.Items[iter]); if Assigned(CurSum) then Dispose(CurSum); end; end; FCheckList.Free; FSync.Free; inherited Destroy; end; function TCheckSumList.FindFileIndex(FileName: string): integer; var iter: integer; CurSum: PCheckSum; begin result := -1; if FCheckList.Count > 0 then begin for iter := 0 to FCheckList.Count - 1 do begin CurSum := PCheckSum(FCheckList.Items[iter]); Assert(Assigned(CurSum)); if AnsiCompareText(FileName, CurSum.FileName) = 0 then begin result := iter; exit; end; end; end; end; procedure TCheckSumList.SetChecksum(FileName: string; Checksum: integer); var CurSum: PCheckSum; CurIndex: integer; begin FSync.StartWrite; CurIndex := FindFileIndex(FileName); if CurIndex >= 0 then CurSum := PCheckSum(FCheckList.Items[CurIndex]) else begin New(CurSum); FCheckList.Add(CurSum); end; CurSum.FileName := FileName; CurSum.Checksum := Checksum; FSync.EndWrite; end; procedure TCheckSumList.RemoveChecksum(FileName: string); var CurIndex: integer; begin FSync.StartWrite; CurIndex := FindFileIndex(FileName); if CurIndex >= 0 then begin FCheckList.Delete(CurIndex); FCheckList.Pack; end; FSync.EndWrite; end; function TCheckSumList.NoLockGetChecksum(FileName: string): integer; var CurIndex: integer; CurSum: PCheckSum; begin result := 0; CurIndex := FindFileIndex(FileName); if CurIndex >= 0 then begin CurSum := PCheckSum(FCheckList.Items[CurIndex]); Assert(Assigned(CurSum)); result := CurSum.Checksum; end; end; function TCheckSumList.GetChecksum(FileName: string): integer; begin FSync.StartRead; result := NoLockGetChecksum(FileName); FSync.EndRead; end; function TCheckSumList.NoLockGetFileList: TStringList; var iter: integer; CurSum: PCheckSum; begin result := TStringList.Create; if FCheckList.Count > 0 then begin for iter := 0 to FCheckList.Count - 1 do begin CurSum := PCheckSum(FCheckList.Items[iter]); Assert(Assigned(CurSum)); result.Add(CurSum.FileName); end; end; result.Sort; end; function TCheckSumList.GetFileList: TStringList; begin FSync.StartRead; result := NoLockGetFileList; FSync.EndRead; end; function TCheckSumList.GetChecksumList: TStringList; var iter: integer; begin FSync.StartRead; result := NoLockGetFileList; if result.Count > 0 then begin for iter := 0 to result.Count - 1 do begin result.strings[iter] := result.strings[iter] + ' ' + IntToStr(NoLockGetChecksum(result.strings[iter])); end; end; FSync.EndRead; end; end.