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