1370b324cSopenharmony_ci// LzInWindow.cs 2370b324cSopenharmony_ci 3370b324cSopenharmony_ciusing System; 4370b324cSopenharmony_ci 5370b324cSopenharmony_cinamespace SevenZip.Compression.LZ 6370b324cSopenharmony_ci{ 7370b324cSopenharmony_ci public class InWindow 8370b324cSopenharmony_ci { 9370b324cSopenharmony_ci public Byte[] _bufferBase = null; // pointer to buffer with data 10370b324cSopenharmony_ci System.IO.Stream _stream; 11370b324cSopenharmony_ci UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done 12370b324cSopenharmony_ci bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci UInt32 _pointerToLastSafePosition; 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci public UInt32 _bufferOffset; 17370b324cSopenharmony_ci 18370b324cSopenharmony_ci public UInt32 _blockSize; // Size of Allocated memory block 19370b324cSopenharmony_ci public UInt32 _pos; // offset (from _buffer) of curent byte 20370b324cSopenharmony_ci UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos 21370b324cSopenharmony_ci UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos 22370b324cSopenharmony_ci public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream 23370b324cSopenharmony_ci 24370b324cSopenharmony_ci public void MoveBlock() 25370b324cSopenharmony_ci { 26370b324cSopenharmony_ci UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore; 27370b324cSopenharmony_ci // we need one additional byte, since MovePos moves on 1 byte. 28370b324cSopenharmony_ci if (offset > 0) 29370b324cSopenharmony_ci offset--; 30370b324cSopenharmony_ci 31370b324cSopenharmony_ci UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset; 32370b324cSopenharmony_ci 33370b324cSopenharmony_ci // check negative offset ???? 34370b324cSopenharmony_ci for (UInt32 i = 0; i < numBytes; i++) 35370b324cSopenharmony_ci _bufferBase[i] = _bufferBase[offset + i]; 36370b324cSopenharmony_ci _bufferOffset -= offset; 37370b324cSopenharmony_ci } 38370b324cSopenharmony_ci 39370b324cSopenharmony_ci public virtual void ReadBlock() 40370b324cSopenharmony_ci { 41370b324cSopenharmony_ci if (_streamEndWasReached) 42370b324cSopenharmony_ci return; 43370b324cSopenharmony_ci while (true) 44370b324cSopenharmony_ci { 45370b324cSopenharmony_ci int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos); 46370b324cSopenharmony_ci if (size == 0) 47370b324cSopenharmony_ci return; 48370b324cSopenharmony_ci int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size); 49370b324cSopenharmony_ci if (numReadBytes == 0) 50370b324cSopenharmony_ci { 51370b324cSopenharmony_ci _posLimit = _streamPos; 52370b324cSopenharmony_ci UInt32 pointerToPostion = _bufferOffset + _posLimit; 53370b324cSopenharmony_ci if (pointerToPostion > _pointerToLastSafePosition) 54370b324cSopenharmony_ci _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset); 55370b324cSopenharmony_ci 56370b324cSopenharmony_ci _streamEndWasReached = true; 57370b324cSopenharmony_ci return; 58370b324cSopenharmony_ci } 59370b324cSopenharmony_ci _streamPos += (UInt32)numReadBytes; 60370b324cSopenharmony_ci if (_streamPos >= _pos + _keepSizeAfter) 61370b324cSopenharmony_ci _posLimit = _streamPos - _keepSizeAfter; 62370b324cSopenharmony_ci } 63370b324cSopenharmony_ci } 64370b324cSopenharmony_ci 65370b324cSopenharmony_ci void Free() { _bufferBase = null; } 66370b324cSopenharmony_ci 67370b324cSopenharmony_ci public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) 68370b324cSopenharmony_ci { 69370b324cSopenharmony_ci _keepSizeBefore = keepSizeBefore; 70370b324cSopenharmony_ci _keepSizeAfter = keepSizeAfter; 71370b324cSopenharmony_ci UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; 72370b324cSopenharmony_ci if (_bufferBase == null || _blockSize != blockSize) 73370b324cSopenharmony_ci { 74370b324cSopenharmony_ci Free(); 75370b324cSopenharmony_ci _blockSize = blockSize; 76370b324cSopenharmony_ci _bufferBase = new Byte[_blockSize]; 77370b324cSopenharmony_ci } 78370b324cSopenharmony_ci _pointerToLastSafePosition = _blockSize - keepSizeAfter; 79370b324cSopenharmony_ci } 80370b324cSopenharmony_ci 81370b324cSopenharmony_ci public void SetStream(System.IO.Stream stream) { _stream = stream; } 82370b324cSopenharmony_ci public void ReleaseStream() { _stream = null; } 83370b324cSopenharmony_ci 84370b324cSopenharmony_ci public void Init() 85370b324cSopenharmony_ci { 86370b324cSopenharmony_ci _bufferOffset = 0; 87370b324cSopenharmony_ci _pos = 0; 88370b324cSopenharmony_ci _streamPos = 0; 89370b324cSopenharmony_ci _streamEndWasReached = false; 90370b324cSopenharmony_ci ReadBlock(); 91370b324cSopenharmony_ci } 92370b324cSopenharmony_ci 93370b324cSopenharmony_ci public void MovePos() 94370b324cSopenharmony_ci { 95370b324cSopenharmony_ci _pos++; 96370b324cSopenharmony_ci if (_pos > _posLimit) 97370b324cSopenharmony_ci { 98370b324cSopenharmony_ci UInt32 pointerToPostion = _bufferOffset + _pos; 99370b324cSopenharmony_ci if (pointerToPostion > _pointerToLastSafePosition) 100370b324cSopenharmony_ci MoveBlock(); 101370b324cSopenharmony_ci ReadBlock(); 102370b324cSopenharmony_ci } 103370b324cSopenharmony_ci } 104370b324cSopenharmony_ci 105370b324cSopenharmony_ci public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; } 106370b324cSopenharmony_ci 107370b324cSopenharmony_ci // index + limit have not to exceed _keepSizeAfter; 108370b324cSopenharmony_ci public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) 109370b324cSopenharmony_ci { 110370b324cSopenharmony_ci if (_streamEndWasReached) 111370b324cSopenharmony_ci if ((_pos + index) + limit > _streamPos) 112370b324cSopenharmony_ci limit = _streamPos - (UInt32)(_pos + index); 113370b324cSopenharmony_ci distance++; 114370b324cSopenharmony_ci // Byte *pby = _buffer + (size_t)_pos + index; 115370b324cSopenharmony_ci UInt32 pby = _bufferOffset + _pos + (UInt32)index; 116370b324cSopenharmony_ci 117370b324cSopenharmony_ci UInt32 i; 118370b324cSopenharmony_ci for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++); 119370b324cSopenharmony_ci return i; 120370b324cSopenharmony_ci } 121370b324cSopenharmony_ci 122370b324cSopenharmony_ci public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; } 123370b324cSopenharmony_ci 124370b324cSopenharmony_ci public void ReduceOffsets(Int32 subValue) 125370b324cSopenharmony_ci { 126370b324cSopenharmony_ci _bufferOffset += (UInt32)subValue; 127370b324cSopenharmony_ci _posLimit -= (UInt32)subValue; 128370b324cSopenharmony_ci _pos -= (UInt32)subValue; 129370b324cSopenharmony_ci _streamPos -= (UInt32)subValue; 130370b324cSopenharmony_ci } 131370b324cSopenharmony_ci } 132370b324cSopenharmony_ci} 133