-
Notifications
You must be signed in to change notification settings - Fork 2
/
_threadDigest.pas
102 lines (86 loc) · 2.49 KB
/
_threadDigest.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
{
Autor: Luis Gustavo Carneiro
email: [email protected]
}
unit _threadDigest;
interface
uses
System.Hash,
System.Classes;
const
_SUSPENDED = True;
type
TOnRead = procedure(const bytesRead: Int64; const fileSize: Int64) of object;
TOnFileOpen = procedure(const fileSize: Int64) of object;
TDoneProc = procedure(var md5: string) of object;
TThreadDigest = class(TThread)
private
sha256: THashSha2;
f_sha256string: String;
md5: THashMD5;
f_md5string: String;
f_filename: String;
f_stream: TStream;
f_size: Int64;
f_totalBytes : Int64;
f_onDone: TDoneProc;
f_onFileOpen: TOnFileOpen;
f_onRead: TOnRead;
procedure SetFileName(const Value: String);
protected
procedure DoFileOpen;
procedure OnSync;
procedure Execute; override;
public
property MD5String: String read f_md5string;
property SHA256String: String read f_sha256string;
property OnRead: TOnRead read f_onRead write f_onRead;
property OnDone: TDoneProc read f_ondone write f_ondone;
property OnFileOpen: TOnFileOpen read f_onFileOpen write f_onFileOpen;
property FileName: String read f_filename write SetFileName;
end;
implementation
uses
System.SysUtils;
{ TThreadDigest }
procedure TThreadDigest.DoFileOpen;
begin
if Assigned(f_onFileOpen) then f_onFileOpen(f_stream.Size);
end;
procedure TThreadDigest.Execute;
var
Buffer: array[0..1024] of Byte;
ReadBytes : Int64;
begin
md5 := System.Hash.THashMD5.Create;
sha256 := System.Hash.THashSHA2.Create(System.Hash.THashSHA2.TSHA2Version.SHA256);
f_size := f_stream.Size;
f_totalBytes := 0;
try
f_stream.Seek(0, soBeginning);
repeat
ReadBytes := f_stream.Read(Buffer, SizeOf(Buffer));
Inc(f_totalBytes, ReadBytes);
md5.Update(Buffer, ReadBytes);
sha256.Update(Buffer, ReadBytes);
Synchronize(OnSync); // Synchronize Interface
until (ReadBytes = 0) or (f_totalBytes = f_size);
finally
FreeAndNil(f_stream);
end;
f_md5string := UpperCase(md5.HashAsString);
f_sha256string := UpperCase(sha256.HashAsString);
if Assigned(f_ondone) then f_ondone(f_md5string);
end;
procedure TThreadDigest.SetFileName(const Value: String);
begin
if (Value <> f_filename) then f_filename := Value;
if Assigned(f_stream) then FreeAndNil(f_stream);
f_stream := TFileStream.Create(Value, fmOpenRead or fmShareDenyWrite);
DoFileOpen;
end;
procedure TThreadDigest.OnSync;
begin
if Assigned(f_onRead) then f_onRead(f_totalBytes, f_size);
end;
end.