// LZ.InWindow package sevenzip.compression.lz; import java.io.IOException; public class InWindow { public byte[] _bufferBase; // pointer to buffer with data java.io.InputStream _stream; int _posLimit; // offset (from _buffer) of first byte when new block reading must be done boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream int _pointerToLastSafePosition; public int _bufferOffset; public int _blockSize; // Size of Allocated memory block public int _pos; // offset (from _buffer) of curent byte int _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos int _keepSizeAfter; // how many BYTEs must be kept buffer after _pos public int _streamPos; // offset (from _buffer) of first not read byte from Stream public void MoveBlock() { int offset = _bufferOffset+_pos-_keepSizeBefore; // we need one additional byte, since MovePos moves on 1 byte. if (offset>0) { offset--; } int numBytes = _bufferOffset+_streamPos-offset; // check negative offset ???? for (int i = 0; i<numBytes; i++) { _bufferBase[i] = _bufferBase[offset+i]; } _bufferOffset -= offset; } public void ReadBlock() throws IOException { if (_streamEndWasReached) { return; } while (true) { int size = (0-_bufferOffset)+_blockSize-_streamPos; if (size==0) { return; } int numReadBytes = _stream.read(_bufferBase, _bufferOffset+_streamPos, size); if (numReadBytes==-1) { _posLimit = _streamPos; int pointerToPostion = _bufferOffset+_posLimit; if (pointerToPostion>_pointerToLastSafePosition) { _posLimit = _pointerToLastSafePosition-_bufferOffset; } _streamEndWasReached = true; return; } _streamPos += numReadBytes; if (_streamPos>=_pos+_keepSizeAfter) { _posLimit = _streamPos-_keepSizeAfter; } } } void Free() { _bufferBase = null; } public void Create(int keepSizeBefore, int keepSizeAfter, int keepSizeReserv) { _keepSizeBefore = keepSizeBefore; _keepSizeAfter = keepSizeAfter; int blockSize = keepSizeBefore+keepSizeAfter+keepSizeReserv; if (_bufferBase==null||_blockSize!=blockSize) { Free(); _blockSize = blockSize; _bufferBase = new byte[_blockSize]; } _pointerToLastSafePosition = _blockSize-keepSizeAfter; } public void SetStream(java.io.InputStream stream) { _stream = stream; } public void ReleaseStream() { _stream = null; } public void Init() throws IOException { _bufferOffset = 0; _pos = 0; _streamPos = 0; _streamEndWasReached = false; ReadBlock(); } public void MovePos() throws IOException { _pos++; if (_pos>_posLimit) { int pointerToPostion = _bufferOffset+_pos; if (pointerToPostion>_pointerToLastSafePosition) { MoveBlock(); } ReadBlock(); } } public byte GetIndexByte(int index) { return _bufferBase[_bufferOffset+_pos+index]; } // index + limit have not to exceed _keepSizeAfter; public int GetMatchLen(int index, int distance, int limit) { if (_streamEndWasReached) { if ((_pos+index)+limit>_streamPos) { limit = _streamPos-(_pos+index); } } distance++; // Byte *pby = _buffer + (size_t)_pos + index; int pby = _bufferOffset+_pos+index; int i; for (i = 0; i<limit&&_bufferBase[pby+i]==_bufferBase[pby+i-distance];) { i++; } return i; } public int GetNumAvailableBytes() { return _streamPos-_pos; } public void ReduceOffsets(int subValue) { _bufferOffset += subValue; _posLimit -= subValue; _pos -= subValue; _streamPos -= subValue; } }