Files
InnoPatcher/LzOutWindow.cs

116 lines
2.3 KiB
C#

namespace SevenZip.Compression.LZ
{
public class OutWindow
{
byte[] _buffer = null;
uint _pos;
uint _windowSize = 0;
uint _streamPos;
uint _writePos;
internal System.IO.Stream _stream;
public uint TrainSize = 0;
public void Create(uint windowSize)
{
if (_windowSize != windowSize)
{
// System.GC.Collect();
_buffer = new byte[windowSize];
}
_windowSize = windowSize;
_pos = 0;
_streamPos = 0;
_writePos = 0;
}
public void Init(System.IO.Stream stream, bool solid)
{
ReleaseStream();
_stream = stream;
if (!solid)
{
_streamPos = 0;
_writePos = 0;
_pos = 0;
TrainSize = 0;
}
}
public bool Train(System.IO.Stream stream)
{
long len = stream.Length;
uint size = (len < _windowSize) ? (uint)len : _windowSize;
TrainSize = size;
stream.Position = len - size;
_streamPos = _pos = _writePos = 0;
while (size > 0)
{
uint curSize = _windowSize - _pos;
if (size < curSize)
curSize = size;
int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize);
if (numReadBytes == 0)
return false;
size -= (uint)numReadBytes;
_pos += (uint)numReadBytes;
_streamPos += (uint)numReadBytes;
_writePos += (uint)numReadBytes;
if (_pos == _windowSize)
_streamPos = _pos = _writePos = 0;
}
return true;
}
public void ReleaseStream()
{
Flush();
_stream = null;
}
public void Flush(bool writeOnly = false, int avoidNewestCount = 0)
{
int size = (int)(_pos - _writePos) - avoidNewestCount;
if (size <= 0)
return;
_stream.Write(_buffer, (int)_writePos, (int)size);
_writePos += (uint)size;
if (!writeOnly) {
if (_pos >= _windowSize)
_pos = 0;
_streamPos = _pos;
}
}
public void CopyBlock(uint distance, uint len)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
for (; len > 0; len--)
{
if (pos >= _windowSize)
pos = 0;
_buffer[_pos++] = _buffer[pos++];
if (_pos >= _windowSize)
Flush();
}
}
public void PutByte(byte b)
{
_buffer[_pos++] = b;
if (_pos >= _windowSize)
Flush();
}
public byte GetByte(uint distance)
{
uint pos = _pos - distance - 1;
if (pos >= _windowSize)
pos += _windowSize;
return _buffer[pos];
}
}
}