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.