unit ChecksumList;
 
{ Martin Harvey 29/5/2000 }
 
interface
 
uses SimpleSync, Classes, SysUtils;
 
type
 TChecksumList = class
 private
 FCheckList: TList;
 FSync: TSimpleSynchronizer;
 protected
 { Funcin Find devuelve -1 si no se encuentra }
 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.