1 // LzInWindow.cs 2 3 using System; 4 5 namespace SevenZip.Compression.LZ 6 { 7 public class InWindow 8 { 9 public Byte[] _bufferBase = null; // pointer to buffer with data 10 System.IO.Stream _stream; 11 UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done 12 bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream 13 14 UInt32 _pointerToLastSafePosition; 15 16 public UInt32 _bufferOffset; 17 18 public UInt32 _blockSize; // Size of Allocated memory block 19 public UInt32 _pos; // offset (from _buffer) of curent byte 20 UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos 21 UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos 22 public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream 23 MoveBlock()24 public void MoveBlock() 25 { 26 UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore; 27 // we need one additional byte, since MovePos moves on 1 byte. 28 if (offset > 0) 29 offset--; 30 31 UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset; 32 33 // check negative offset ???? 34 for (UInt32 i = 0; i < numBytes; i++) 35 _bufferBase[i] = _bufferBase[offset + i]; 36 _bufferOffset -= offset; 37 } 38 ReadBlock()39 public virtual void ReadBlock() 40 { 41 if (_streamEndWasReached) 42 return; 43 while (true) 44 { 45 int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos); 46 if (size == 0) 47 return; 48 int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size); 49 if (numReadBytes == 0) 50 { 51 _posLimit = _streamPos; 52 UInt32 pointerToPostion = _bufferOffset + _posLimit; 53 if (pointerToPostion > _pointerToLastSafePosition) 54 _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset); 55 56 _streamEndWasReached = true; 57 return; 58 } 59 _streamPos += (UInt32)numReadBytes; 60 if (_streamPos >= _pos + _keepSizeAfter) 61 _posLimit = _streamPos - _keepSizeAfter; 62 } 63 } 64 Free()65 void Free() { _bufferBase = null; } 66 Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)67 public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) 68 { 69 _keepSizeBefore = keepSizeBefore; 70 _keepSizeAfter = keepSizeAfter; 71 UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; 72 if (_bufferBase == null || _blockSize != blockSize) 73 { 74 Free(); 75 _blockSize = blockSize; 76 _bufferBase = new Byte[_blockSize]; 77 } 78 _pointerToLastSafePosition = _blockSize - keepSizeAfter; 79 } 80 SetStream(System.IO.Stream stream)81 public void SetStream(System.IO.Stream stream) { _stream = stream; } ReleaseStream()82 public void ReleaseStream() { _stream = null; } 83 Init()84 public void Init() 85 { 86 _bufferOffset = 0; 87 _pos = 0; 88 _streamPos = 0; 89 _streamEndWasReached = false; 90 ReadBlock(); 91 } 92 MovePos()93 public void MovePos() 94 { 95 _pos++; 96 if (_pos > _posLimit) 97 { 98 UInt32 pointerToPostion = _bufferOffset + _pos; 99 if (pointerToPostion > _pointerToLastSafePosition) 100 MoveBlock(); 101 ReadBlock(); 102 } 103 } 104 GetIndexByte(Int32 index)105 public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; } 106 107 // index + limit have not to exceed _keepSizeAfter; GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)108 public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) 109 { 110 if (_streamEndWasReached) 111 if ((_pos + index) + limit > _streamPos) 112 limit = _streamPos - (UInt32)(_pos + index); 113 distance++; 114 // Byte *pby = _buffer + (size_t)_pos + index; 115 UInt32 pby = _bufferOffset + _pos + (UInt32)index; 116 117 UInt32 i; 118 for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++); 119 return i; 120 } 121 GetNumAvailableBytes()122 public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; } 123 ReduceOffsets(Int32 subValue)124 public void ReduceOffsets(Int32 subValue) 125 { 126 _bufferOffset += (UInt32)subValue; 127 _posLimit -= (UInt32)subValue; 128 _pos -= (UInt32)subValue; 129 _streamPos -= (UInt32)subValue; 130 } 131 } 132 } 133