-
Notifications
You must be signed in to change notification settings - Fork 0
/
PV_Compressor.pas
112 lines (85 loc) · 2.07 KB
/
PV_Compressor.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
103
104
105
106
107
108
109
110
111
112
unit PV_Compressor;
{$mode objfpc}{$H+}
//PV Pack
//https://github.com/PascalVault
//Licence: MIT
//Last update: 2023-10-06
interface
uses
Classes, SysUtils, DateUtils, ZStream, Dialogs, CRC32_ISOHDLC;
type
{ TCompressor }
TCompressor = class
public
constructor Create(OutStr: TStream);
destructor Destroy; override;
function Write(const Buffer; Count: Integer): Integer; virtual; abstract;
end;
{ TCompressorGzip }
TCompressorGzip = class(TCompressor)
private
FHandle: TCompressionStream;
FHasher: TCRC32_ISO;
FSize: Cardinal;
public
constructor Create(OutStr: TStream);
destructor Destroy; override;
function Write(const Buffer; Count: Integer): Integer;
end;
implementation
{ TCompressor }
constructor TCompressor.Create(OutStr: TStream);
begin
inherited Create;
end;
destructor TCompressor.Destroy;
begin
inherited Destroy;
end;
{ TCompressorGzip }
constructor TCompressorGzip.Create(OutStr: TStream);
type THead = packed record
ID1: Byte;
ID2: Byte;
Method: Byte;
Flag: Byte;
ModTime: Cardinal; //unix
XFlag: Byte;
OS: Byte;
end;
var Head: THead;
begin
inherited Create(OutStr);
FHandle := TCompressionStream.Create(cldefault, OutStr, True);
with Head do begin
ID1 := 31;
ID2 := 139;
Method := 8; //deflate
Flag := 0;
ModTime := DateTimeToUnix(Now, True);
XFlag := 0;
OS := 0; //0=DOS+Win
end;
OutStr.Write(Head, SizeOf(Head));
FHasher := TCRC32_ISO.Create;
FSize := 0;
end;
destructor TCompressorGzip.Destroy;
var CRC: Cardinal;
OutStr: TStream;
begin
FHandle.Free;
CRC := FHasher.Final;
FHasher.Free;
OutStr := FHandle.Source;
OutStr.Write(CRC, 4);
OutStr.Write(FSize, 4);
inherited Destroy;
end;
function TCompressorGzip.Write(const Buffer; Count: Integer): Integer;
begin
Result := FHandle.Write(Buffer, Count);
FHasher.Update(@Buffer, Count);
Inc(FSize, Result);
end;
end.