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 } |
|