// LzOutWindow.cs namespace SevenZip.Compression.LZ { public class OutWindow { byte[] _buffer = null; uint _pos; uint _windowSize = 0; uint _streamPos; 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; } public void Init(System.IO.Stream stream, bool solid) { ReleaseStream(); _stream = stream; if (!solid) { _streamPos = 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 = 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; if (_pos == _windowSize) _streamPos = _pos = 0; } return true; } public void ReleaseStream() { Flush(); _stream = null; } public void Flush() { uint size = _pos - _streamPos; if (size == 0) return; _stream.Write(_buffer, (int)_streamPos, (int)size); 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]; } } }