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