kolmck/Addons/ULZOutWindow.pas
dkolmck 8a71ebf5bc addons update
git-svn-id: https://svn.code.sf.net/p/kolmck/code@67 91bb2d04-0c0c-4d2d-88a5-bbb6f4c1fa07
2010-10-04 12:58:59 +00:00

108 lines
2.3 KiB
ObjectPascal

unit ULZOutWindow;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
interface
uses KOL;
type PLZOutWindow = ^TLZOutWindow;
TLZOutWindow=object(TObj)
public
buffer: array of byte;
pos:integer;
windowSize:integer;
streamPos:integer;
stream:PStream;
procedure _Create(const AwindowSize:integer);
procedure SetStream(const Astream:PStream);
procedure ReleaseStream;
procedure _Init(const Asolid:boolean);
procedure Flush;
procedure CopyBlock(const Adistance:integer; Alen:integer);
procedure PutByte(const Ab:byte);
function GetByte(const Adistance:integer):byte;
end;
implementation
procedure TLZOutWindow._Create(const AwindowSize:integer);
begin
if (length(buffer)=0) or (self.windowSize <> AwindowSize) then
setlength(buffer,AwindowSize);
self.windowSize := AwindowSize;
pos := 0;
streamPos := 0;
end;
procedure TLZOutWindow.SetStream(const Astream:PStream);
begin
ReleaseStream;
self.stream:=Astream;
end;
procedure TLZOutWindow.ReleaseStream;
begin
flush;
self.stream:=nil;
end;
procedure TLZOutWindow._Init(const Asolid:boolean);
begin
if not Asolid then begin
streamPos:=0;
Pos:=0;
end;
end;
procedure TLZOutWindow.Flush;
var size:integer;
begin
size := pos - streamPos;
if (size = 0) then
exit;
stream.write(buffer[streamPos], size);
if (pos >= windowSize) then
pos := 0;
streamPos := pos;
end;
procedure TLZOutWindow.CopyBlock(const Adistance:integer;Alen:integer);
var _pos:integer;
begin
_pos := self.pos - Adistance - 1;
if _pos < 0 then
_pos := _pos + windowSize;
while Alen<>0 do begin
if _pos >= windowSize then
_pos := 0;
buffer[self.pos] := buffer[_pos];
inc(self.pos);
inc(_pos);
if self.pos >= windowSize then
Flush();
dec(Alen);
end;
end;
procedure TLZOutWindow.PutByte(const Ab:byte);
begin
buffer[pos] := Ab;
inc(pos);
if (pos >= windowSize) then
Flush();
end;
function TLZOutWindow.GetByte(const Adistance:integer):byte;
var _pos:integer;
begin
_pos := self.pos - Adistance - 1;
if (_pos < 0) then
_pos := _pos + windowSize;
result:=buffer[_pos];
end;
end.