123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- using System;
- using System.IO;
- namespace SharpCompress.Compressors.LZMA.LZ
- {
- internal class InWindow
- {
- public Byte[] _bufferBase; // pointer to buffer with data
- private Stream _stream;
- private UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
- private bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
- private UInt32 _pointerToLastSafePosition;
- public UInt32 _bufferOffset;
- public UInt32 _blockSize; // Size of Allocated memory block
- public UInt32 _pos; // offset (from _buffer) of curent byte
- private UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
- private UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
- public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
- public void MoveBlock()
- {
- UInt32 offset = _bufferOffset + _pos - _keepSizeBefore;
- // we need one additional byte, since MovePos moves on 1 byte.
- if (offset > 0)
- {
- offset--;
- }
- UInt32 numBytes = _bufferOffset + _streamPos - offset;
- // check negative offset ????
- for (UInt32 i = 0; i < numBytes; i++)
- {
- _bufferBase[i] = _bufferBase[offset + i];
- }
- _bufferOffset -= offset;
- }
- public virtual void ReadBlock()
- {
- if (_streamEndWasReached)
- {
- return;
- }
- while (true)
- {
- int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);
- if (size == 0)
- {
- return;
- }
- int numReadBytes = _stream != null
- ? _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size)
- : 0;
- if (numReadBytes == 0)
- {
- _posLimit = _streamPos;
- UInt32 pointerToPostion = _bufferOffset + _posLimit;
- if (pointerToPostion > _pointerToLastSafePosition)
- {
- _posLimit = _pointerToLastSafePosition - _bufferOffset;
- }
- _streamEndWasReached = true;
- return;
- }
- _streamPos += (UInt32)numReadBytes;
- if (_streamPos >= _pos + _keepSizeAfter)
- {
- _posLimit = _streamPos - _keepSizeAfter;
- }
- }
- }
- private void Free()
- {
- _bufferBase = null;
- }
- public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
- {
- _keepSizeBefore = keepSizeBefore;
- _keepSizeAfter = keepSizeAfter;
- UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
- if (_bufferBase == null || _blockSize != blockSize)
- {
- Free();
- _blockSize = blockSize;
- _bufferBase = new Byte[_blockSize];
- }
- _pointerToLastSafePosition = _blockSize - keepSizeAfter;
- _streamEndWasReached = false;
- }
- public void SetStream(Stream stream)
- {
- _stream = stream;
- if (_streamEndWasReached)
- {
- _streamEndWasReached = false;
- if (IsDataStarved)
- {
- ReadBlock();
- }
- }
- }
- public void ReleaseStream()
- {
- _stream = null;
- }
- public void Init()
- {
- _bufferOffset = 0;
- _pos = 0;
- _streamPos = 0;
- _streamEndWasReached = false;
- ReadBlock();
- }
- public void MovePos()
- {
- _pos++;
- if (_pos > _posLimit)
- {
- UInt32 pointerToPostion = _bufferOffset + _pos;
- if (pointerToPostion > _pointerToLastSafePosition)
- {
- MoveBlock();
- }
- ReadBlock();
- }
- }
- public Byte GetIndexByte(Int32 index)
- {
- return _bufferBase[_bufferOffset + _pos + index];
- }
- // index + limit have not to exceed _keepSizeAfter;
- public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
- {
- if (_streamEndWasReached)
- {
- if ((_pos + index) + limit > _streamPos)
- {
- limit = _streamPos - (UInt32)(_pos + index);
- }
- }
- distance++;
- // Byte *pby = _buffer + (size_t)_pos + index;
- UInt32 pby = _bufferOffset + _pos + (UInt32)index;
- UInt32 i;
- for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++)
- {
- ;
- }
- return i;
- }
- public UInt32 GetNumAvailableBytes()
- {
- return _streamPos - _pos;
- }
- public void ReduceOffsets(Int32 subValue)
- {
- _bufferOffset += (UInt32)subValue;
- _posLimit -= (UInt32)subValue;
- _pos -= (UInt32)subValue;
- _streamPos -= (UInt32)subValue;
- }
- public bool IsDataStarved => _streamPos - _pos < _keepSizeAfter;
- }
- }
|