forked from iLya2IK/wchttpserver
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwcdeflatedecoder.pas
More file actions
89 lines (75 loc) · 2.35 KB
/
Copy pathwcdeflatedecoder.pas
File metadata and controls
89 lines (75 loc) · 2.35 KB
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
unit wcdeflatedecoder;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, wcdecoders, zlib;
type
{ TWCDeflateClientDecoder }
TWCDeflateClientDecoder = class(TWCClientDecoder)
protected
class procedure Decode(Buffer: Pointer; Count: PtrInt;
out NewBuffer: PByte; out NewCount: PtrInt); override;
public
class function DecoderName : String; override;
end;
implementation
{ TWCDeflateClientDecoder }
class procedure TWCDeflateClientDecoder.Decode(Buffer : Pointer; Count : PtrInt;
out NewBuffer : PByte; out NewCount : PtrInt);
const CHUNCK_START_SZ = 512;
CHUNCK_MAX_SZ = 32768;
var ret, have : Integer;
infstream : z_stream;
decompressChunckSize : uInt;
begin
infstream.zalloc := nil;
infstream.zfree := nil;
infstream.opaque := nil;
infstream.avail_in := Count;
infstream.next_in := Buffer; // input char array
ret := inflateInit(infstream);
if ret <> Z_OK then raise Exception.CreateFmt('inflateInit return code %d', [ret]);
NewCount := 0;
decompressChunckSize := CHUNCK_START_SZ;
NewBuffer := AllocMem(decompressChunckSize);
try
while true do begin
infstream.avail_out := decompressChunckSize;
infstream.next_out := @(NewBuffer[NewCount]);
ret := inflate(infstream, Z_NO_FLUSH);
if ret = Z_STREAM_ERROR then raise Exception.Create('inflate Z_STREAM_ERROR');
if not (ret in [Z_OK, Z_STREAM_END]) then
begin
inflateEnd(infstream);
raise Exception.CreateFmt('inflate error code %d', [ret]);
end;
have := decompressChunckSize - infstream.avail_out;
Inc(NewCount, have);
if infstream.avail_out = 0 then begin
NewBuffer := ReAllocMem(NewBuffer, NewCount + decompressChunckSize);
decompressChunckSize := decompressChunckSize shl 1;
if decompressChunckSize > CHUNCK_MAX_SZ then
decompressChunckSize := CHUNCK_MAX_SZ;
end else begin
ret := Z_OK;
Break;
end;
end;
inflateEnd(infstream);
finally
if ret <> Z_OK then
begin
NewCount := 0;
FreeMemAndNil(NewBuffer);
end;
end;
end;
class function TWCDeflateClientDecoder.DecoderName : String;
begin
Result := 'deflate';
//according:
//https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Content-Encoding
end;
initialization
RegisterWCDecoder(TWCDeflateClientDecoder);
end.