// LZInWindow.cpp #include "StdAfx.h" #include "LZInWindow.h" #include "../../../Common/MyCom.h" #include "../../../Common/Alloc.h" void CLZInWindow::Free() { ::BigFree(_bufferBase); _bufferBase = 0; } bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) { _keepSizeBefore = keepSizeBefore; _keepSizeAfter = keepSizeAfter; UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; if (_bufferBase == 0 || _blockSize != blockSize) { Free(); _blockSize = blockSize; if (_blockSize != 0) _bufferBase = (Byte *)::BigAlloc(_blockSize); } _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter; if (_blockSize == 0) return true; return (_bufferBase != 0); } void CLZInWindow::SetStream(ISequentialInStream *stream) { _stream = stream; } HRESULT CLZInWindow::Init() { _buffer = _bufferBase; _pos = 0; _streamPos = 0; _streamEndWasReached = false; return ReadBlock(); } /* void CLZInWindow::ReleaseStream() { _stream.Release(); } */ /////////////////////////////////////////// // ReadBlock // In State: // (_buffer + _streamPos) <= (_bufferBase + _blockSize) // Out State: // _posLimit <= _blockSize - _keepSizeAfter; // if(_streamEndWasReached == false): // _streamPos >= _pos + _keepSizeAfter // _posLimit = _streamPos - _keepSizeAfter; // else // HRESULT CLZInWindow::ReadBlock() { if(_streamEndWasReached) return S_OK; while(true) { UInt32 size = (UInt32)(_bufferBase - _buffer) + _blockSize - _streamPos; if(size == 0) return S_OK; UInt32 numReadBytes; RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes)); if(numReadBytes == 0) { _posLimit = _streamPos; const Byte *pointerToPostion = _buffer + _posLimit; if(pointerToPostion > _pointerToLastSafePosition) _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer); _streamEndWasReached = true; return S_OK; } _streamPos += numReadBytes; if(_streamPos >= _pos + _keepSizeAfter) { _posLimit = _streamPos - _keepSizeAfter; return S_OK; } } } void CLZInWindow::MoveBlock() { UInt32 offset = (UInt32)(_buffer - _bufferBase) + _pos - _keepSizeBefore; // we need one additional byte, since MovePos moves on 1 byte. if (offset > 0) offset--; UInt32 numBytes = (UInt32)(_buffer - _bufferBase) + _streamPos - offset; memmove(_bufferBase, _bufferBase + offset, numBytes); _buffer -= offset; }