Upload 2.0.2
[physicsfs] / lzma / Java / SevenZip / Compression / LZ / InWindow.java
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 }