001: // LZ.InWindow
002:
003: package SevenZip.Compression.lz;
004:
005: import java.io.IOException;
006:
007: public class InWindow {
008: public byte[] _bufferBase; // pointer to buffer with data
009: java.io.InputStream _stream;
010: int _posLimit; // offset (from _buffer) of first byte when new block reading must be done
011: boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream
012:
013: int _pointerToLastSafePosition;
014:
015: public int _bufferOffset;
016:
017: public int _blockSize; // Size of Allocated memory block
018: public int _pos; // offset (from _buffer) of curent byte
019: int _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
020: int _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
021: public int _streamPos; // offset (from _buffer) of first not read byte from Stream
022:
023: public void MoveBlock() {
024: int offset = _bufferOffset + _pos - _keepSizeBefore;
025: // we need one additional byte, since MovePos moves on 1 byte.
026: if (offset > 0)
027: offset--;
028:
029: int numBytes = _bufferOffset + _streamPos - offset;
030:
031: // check negative offset ????
032: for (int i = 0; i < numBytes; i++)
033: _bufferBase[i] = _bufferBase[offset + i];
034: _bufferOffset -= offset;
035: }
036:
037: public void ReadBlock() throws IOException {
038: if (_streamEndWasReached)
039: return;
040: while (true) {
041: int size = (0 - _bufferOffset) + _blockSize - _streamPos;
042: if (size == 0)
043: return;
044: int numReadBytes = _stream.read(_bufferBase, _bufferOffset
045: + _streamPos, size);
046: if (numReadBytes == -1) {
047: _posLimit = _streamPos;
048: int pointerToPostion = _bufferOffset + _posLimit;
049: if (pointerToPostion > _pointerToLastSafePosition)
050: _posLimit = _pointerToLastSafePosition
051: - _bufferOffset;
052:
053: _streamEndWasReached = true;
054: return;
055: }
056: _streamPos += numReadBytes;
057: if (_streamPos >= _pos + _keepSizeAfter)
058: _posLimit = _streamPos - _keepSizeAfter;
059: }
060: }
061:
062: void Free() {
063: _bufferBase = null;
064: }
065:
066: public void Create(int keepSizeBefore, int keepSizeAfter,
067: int keepSizeReserv) {
068: _keepSizeBefore = keepSizeBefore;
069: _keepSizeAfter = keepSizeAfter;
070: int blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
071: if (_bufferBase == null || _blockSize != blockSize) {
072: Free();
073: _blockSize = blockSize;
074: _bufferBase = new byte[_blockSize];
075: }
076: _pointerToLastSafePosition = _blockSize - keepSizeAfter;
077: }
078:
079: public void SetStream(java.io.InputStream stream) {
080: _stream = stream;
081: }
082:
083: public void ReleaseStream() {
084: _stream = null;
085: }
086:
087: public void Init() throws IOException {
088: _bufferOffset = 0;
089: _pos = 0;
090: _streamPos = 0;
091: _streamEndWasReached = false;
092: ReadBlock();
093: }
094:
095: public void MovePos() throws IOException {
096: _pos++;
097: if (_pos > _posLimit) {
098: int pointerToPostion = _bufferOffset + _pos;
099: if (pointerToPostion > _pointerToLastSafePosition)
100: MoveBlock();
101: ReadBlock();
102: }
103: }
104:
105: public byte GetIndexByte(int index) {
106: return _bufferBase[_bufferOffset + _pos + index];
107: }
108:
109: // index + limit have not to exceed _keepSizeAfter;
110: public int GetMatchLen(int index, int distance, int limit) {
111: if (_streamEndWasReached)
112: if ((_pos + index) + limit > _streamPos)
113: limit = _streamPos - (_pos + index);
114: distance++;
115: // Byte *pby = _buffer + (size_t)_pos + index;
116: int pby = _bufferOffset + _pos + index;
117:
118: int i;
119: for (i = 0; i < limit
120: && _bufferBase[pby + i] == _bufferBase[pby + i
121: - distance]; i++)
122: ;
123: return i;
124: }
125:
126: public int GetNumAvailableBytes() {
127: return _streamPos - _pos;
128: }
129:
130: public void ReduceOffsets(int subValue) {
131: _bufferOffset += subValue;
132: _posLimit -= subValue;
133: _pos -= subValue;
134: _streamPos -= subValue;
135: }
136: }
|