📄 zinflate.pas
字号:
begin
z.state^.mode := DONE;
continue; { break C-switch }
end;
z.state^.mode := CHECK4; { falltrough }
end;
CHECK4:
begin
{NEEDBYTE}
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f;
{z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}
Dec(z.avail_in);
Inc(z.total_in);
z.state^.sub.check.need := uLong(z.next_in^) shl 24;
Inc(z.next_in);
z.state^.mode := CHECK3; { falltrough }
end;
CHECK3:
begin
{NEEDBYTE}
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f;
{Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}
Dec(z.avail_in);
Inc(z.total_in);
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 16);
Inc(z.next_in);
z.state^.mode := CHECK2; { falltrough }
end;
CHECK2:
begin
{NEEDBYTE}
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f;
{Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}
Dec(z.avail_in);
Inc(z.total_in);
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 8);
Inc(z.next_in);
z.state^.mode := CHECK1; { falltrough }
end;
CHECK1:
begin
{NEEDBYTE}
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f;
{Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}
Dec(z.avail_in);
Inc(z.total_in);
Inc(z.state^.sub.check.need, uLong(z.next_in^) );
Inc(z.next_in);
if (z.state^.sub.check.was <> z.state^.sub.check.need) then
begin
z.state^.mode := BAD;
z.msg := 'incorrect data check';
z.state^.sub.marker := 5; { can't try inflateSync }
continue; { break C-switch }
end;
{$IFDEF DEBUG}
Tracev('inflate: zlib check ok');
{$ENDIF}
z.state^.mode := DONE; { falltrough }
end;
DONE:
begin
inflate := Z_STREAM_END;
exit;
end;
METHOD:
begin
{NEEDBYTE}
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f; {}
{z.state^.sub.method := NEXTBYTE(z);}
Dec(z.avail_in);
Inc(z.total_in);
z.state^.sub.method := z.next_in^;
Inc(z.next_in);
if ((z.state^.sub.method and $0f) <> Z_DEFLATED) then
begin
z.state^.mode := BAD;
z.msg := 'unknown compression method';
z.state^.sub.marker := 5; { can't try inflateSync }
continue; { break C-switch }
end;
if ((z.state^.sub.method shr 4) + 8 > z.state^.wbits) then
begin
z.state^.mode := BAD;
z.msg := 'invalid window size';
z.state^.sub.marker := 5; { can't try inflateSync }
continue; { break C-switch }
end;
z.state^.mode := FLAG;
{ fall trough }
end;
FLAG:
begin
{NEEDBYTE}
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f; {}
{b := NEXTBYTE(z);}
Dec(z.avail_in);
Inc(z.total_in);
b := z.next_in^;
Inc(z.next_in);
if (((z.state^.sub.method shl 8) + b) mod 31) <> 0 then {% mod ?}
begin
z.state^.mode := BAD;
z.msg := 'incorrect header check';
z.state^.sub.marker := 5; { can't try inflateSync }
continue; { break C-switch }
end;
if ((b and PRESET_DICT) = 0) then
begin
z.state^.mode := BLOCKS;
continue; { break C-switch }
end;
z.state^.mode := DICT4;
{ falltrough }
end;
DICT4:
begin
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f;
{z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}
Dec(z.avail_in);
Inc(z.total_in);
z.state^.sub.check.need := uLong(z.next_in^) shl 24;
Inc(z.next_in);
z.state^.mode := DICT3; { falltrough }
end;
DICT3:
begin
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f;
{Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}
Dec(z.avail_in);
Inc(z.total_in);
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 16);
Inc(z.next_in);
z.state^.mode := DICT2; { falltrough }
end;
DICT2:
begin
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
r := f;
{Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}
Dec(z.avail_in);
Inc(z.total_in);
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 8);
Inc(z.next_in);
z.state^.mode := DICT1; { falltrough }
end;
DICT1:
begin
if (z.avail_in = 0) then
begin
inflate := r;
exit;
end;
{ r := f; --- wird niemals benutzt }
{Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}
Dec(z.avail_in);
Inc(z.total_in);
Inc(z.state^.sub.check.need, uLong(z.next_in^) );
Inc(z.next_in);
z.adler := z.state^.sub.check.need;
z.state^.mode := DICT0;
inflate := Z_NEED_DICT;
exit;
end;
DICT0:
begin
z.state^.mode := BAD;
z.msg := 'need dictionary';
z.state^.sub.marker := 0; { can try inflateSync }
inflate := Z_STREAM_ERROR;
exit;
end;
BAD:
begin
inflate := Z_DATA_ERROR;
exit;
end;
else
begin
inflate := Z_STREAM_ERROR;
exit;
end;
end;
{$ifdef NEED_DUMMY_result}
result := Z_STREAM_ERROR; { Some dumb compilers complain without this }
{$endif}
end;
function inflateSetDictionary(var z : z_stream;
dictionary : pBytef; {const array of byte}
dictLength : uInt) : int;
var
length : uInt;
begin
length := dictLength;
if (z.state = Z_NULL) or (z.state^.mode <> DICT0) then
begin
inflateSetDictionary := Z_STREAM_ERROR;
exit;
end;
if (adler32(Long(1), dictionary, dictLength) <> z.adler) then
begin
inflateSetDictionary := Z_DATA_ERROR;
exit;
end;
z.adler := Long(1);
if (length >= (uInt(1) shl z.state^.wbits)) then
begin
length := (1 shl z.state^.wbits)-1;
Inc( dictionary, dictLength - length);
end;
inflate_set_dictionary(z.state^.blocks^, dictionary^, length);
z.state^.mode := BLOCKS;
inflateSetDictionary := Z_OK;
end;
function inflateSync(var z : z_stream) : int;
const
mark : packed array[0..3] of byte = (0, 0, $ff, $ff);
var
n : uInt; { number of bytes to look at }
p : pBytef; { pointer to bytes }
m : uInt; { number of marker bytes found in a row }
r, w : uLong; { temporaries to save total_in and total_out }
begin
{ set up }
if (z.state = Z_NULL) then
begin
inflateSync := Z_STREAM_ERROR;
exit;
end;
if (z.state^.mode <> BAD) then
begin
z.state^.mode := BAD;
z.state^.sub.marker := 0;
end;
n := z.avail_in;
if (n = 0) then
begin
inflateSync := Z_BUF_ERROR;
exit;
end;
p := z.next_in;
m := z.state^.sub.marker;
{ search }
while (n <> 0) and (m < 4) do
begin
if (p^ = mark[m]) then
Inc(m)
else
if (p^ <> 0) then
m := 0
else
m := 4 - m;
Inc(p);
Dec(n);
end;
{ restore }
Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
z.avail_in := n;
z.state^.sub.marker := m;
{ return no joy or set up to restart on a new block }
if (m <> 4) then
begin
inflateSync := Z_DATA_ERROR;
exit;
end;
r := z.total_in;
w := z.total_out;
inflateReset(z);
z.total_in := r;
z.total_out := w;
z.state^.mode := BLOCKS;
inflateSync := Z_OK;
end;
{
returns true if inflate is currently at the end of a block generated
by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
but removes the length bytes of the resulting empty stored block. When
decompressing, PPP checks that at the end of input packet, inflate is
waiting for these length bytes.
}
function inflateSyncPoint(var z : z_stream) : int;
begin
if (z.state = Z_NULL) or (z.state^.blocks = Z_NULL) then
begin
inflateSyncPoint := Z_STREAM_ERROR;
exit;
end;
inflateSyncPoint := inflate_blocks_sync_point(z.state^.blocks^);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -