summaryrefslogtreecommitdiffstats
path: root/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/InWindow.java
blob: 5f3f0b4d091ffe76fb4a7fb08ddcbd622bad878c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// 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;
	}
}