// MIT License - Copyright (c) 2025 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE // LzOutWindow.cs namespace SevenZip.Compression.LZ { public class OutWindow { private byte[] _buffer = null; private uint _pos; private uint _windowSize = 0; private uint _streamPos; private 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]; } } }