Вход/Регистрация
Фундаментальные алгоритмы и структуры данных в Delphi
вернуться

Бакнелл Джулиан М.

Шрифт:

FStart : PAnsiChar;{начало скользящего окна}

FStartOffset : longint;{смещение потока для FStart}

FStream : TStream;{базовый поток}

protected

procedure swAdvanceAfterAdd(aCount : integer);

procedure swReadFromStream;

procedure swSetCapacity(aValue : longint);

procedure swWriteToStream(aFinalBlock : boolean);

public

constructor Create(aStream : TStream;

aCompressing : boolean);

destructor Destroy; override;

{методы, используемые как во время сжатия, так и во время восстановления}

procedure Clear;

{методы, используемые во время сжатия}

procedure Advance(aCount : integer);

function Compare(aOffset : longint;

var aDistance : integer): integer;

procedure GetNextSignature(var aMS : TtdLZSignature;

varaOffset : longint);

{методы, используемые во время восстановления}

procedure AddChar(aCh : AnsiChar);

procedureAddCode(aDistance : integer;

aLength : integer);

property Name : TtdNameString read FName write FName;

end;

constructor TtdLZSlidingWindow.Create(aStream : TStream;

aCompressing : boolean);

begin

inherited Create;

{сохранить параметры}

FCompressing := aCompressing;

FStream := aStream;

{установить размер скользящего окна: согласно принятого определения размер скользящего окна равен 8192 байтам плюс 10 байтов для упреждающего просмотра}

swSetCapacity(tdcLZSlidingWindowSize + tdcLZLookAheadSize);

{сбросить буфер и, если выполняется сжатие, считать определенные данные из сжимаемого потока}

Clear;

if aCompressing then

swReadFromStream;

end;

destructor TtdLZSlidingWindow.Destroy;

begin

if Assigned(FBuffer) then begin

{завершить запись в выходной поток, если выполняется сжатие}

if not FCompressing then

swWriteToStream(true);

{освободить буфер}

FreeMem(FBuffer, FBufferEnd - FBuffer);

end;

inherited Destroy;

end;

procedure TtdLZSlidingWindow.AddChar(aCh : AnsiChar);

begin

{добавить символ в буфер}

FCurrent^ :=aCh;

{сместить скользящее окно на один символ}

swAdvanceAfterAdd(1);

end;

procedure TtdLZSlidingWindow.AddCode(aDistance : integer;

aLength : integer);

var

FromChar : PAnsiChar;

ToChar : PAnsiChar;

i : integer;

begin

{установить указатели для выполнения копирования данных; обратите внимание, что в данном случае нельзя использовать процедуру Move, поскольку часть копируемых данных может быть определена реальным копированием данных}

FromChar := FCurrent - aDistance;

ToChar := FCurrent;

for i := 1 to aLength do

begin

ToChar^ := FromChar^;

inc(FromChar);

inc(ToChar);

end;

{сместить начало скользящего окна}

swAdvanceAfterAdd(aLength);

end;

procedure TtdLZSlidingWindow.swAdvanceAfterAdd(aCount : integer);

begin

{при необходимости сместить начало скользящего окна}

if ( (FCurrent - FStart) >= tdcLZSlidingWindowSize) then begin

inc(FStart, aCount);

inc(FStartOffset, aCount);

end;

{сместить текущий указатель}

inc(FCurrent, aCount);

{проверить смещение в зону переполнения}

if (FStart >= FMidPoint) then begin

{записать дополнительные данные в поток (от позиции FBuffer до позиции FStart)}

swWriteToStream(false);

{переместить текущие данные обратно в начало буфера}

Move(FStart^, FBuffer^, FCurrent - FStart );

{сбросить различные указатели}

dec(FCurrent, FStart - FBuffer);

FStart := FBuffer;

end;

end;

procedure TtdLZSlidingWindow.swSetCapacity(aValue : longint);

var

NewQueue : PAnsiChar;

begin

{округлить запрошенный объем до ближайшего значения, кратного 64 байтам}

aValue := (aValue + 63) and $7FFFFFC0;

{распределить новый буфер}

GetMem(NewQueue, aValue * 2);

{уничтожить старый буфер}

if ( FBuffer <> nil ) then

FreeMem(FBuffer, FBufferEnd - FBuffer);

  • Читать дальше
  • 1
  • ...
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: