123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- // LzInWindow.cs
- using System;
- namespace SevenZip.Compression.LZ
- {
- public class InWindow
- {
- public Byte[] _bufferBase = null; // pointer to buffer with data
- System.IO.Stream _stream;
- UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
- bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
- UInt32 _pointerToLastSafePosition;
- public UInt32 _bufferOffset;
- public UInt32 _blockSize; // Size of Allocated memory block
- public UInt32 _pos; // offset (from _buffer) of curent byte
- UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
- 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 = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;
- // we need one additional byte, since MovePos moves on 1 byte.
- if (offset > 0)
- offset--;
-
- UInt32 numBytes = (UInt32)(_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.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size);
- if (numReadBytes == 0)
- {
- _posLimit = _streamPos;
- UInt32 pointerToPostion = _bufferOffset + _posLimit;
- if (pointerToPostion > _pointerToLastSafePosition)
- _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);
- _streamEndWasReached = true;
- return;
- }
- _streamPos += (UInt32)numReadBytes;
- if (_streamPos >= _pos + _keepSizeAfter)
- _posLimit = _streamPos - _keepSizeAfter;
- }
- }
- 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;
- }
- public void SetStream(System.IO.Stream stream) { _stream = stream; }
- 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;
- }
- }
- }
|