1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// LzOutWindow.cs 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace SevenZip.Compression.LZ 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public class OutWindow 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync byte[] _buffer = null; 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint _pos; 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint _windowSize = 0; 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint _streamPos; 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync System.IO.Stream _stream; 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public uint TrainSize = 0; 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Create(uint windowSize) 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_windowSize != windowSize) 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // System.GC.Collect(); 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer = new byte[windowSize]; 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _windowSize = windowSize; 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _pos = 0; 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamPos = 0; 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Init(System.IO.Stream stream, bool solid) 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReleaseStream(); 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _stream = stream; 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!solid) 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamPos = 0; 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _pos = 0; 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync TrainSize = 0; 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public bool Train(System.IO.Stream stream) 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync long len = stream.Length; 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint size = (len < _windowSize) ? (uint)len : _windowSize; 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync TrainSize = size; 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stream.Position = len - size; 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamPos = _pos = 0; 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (size > 0) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint curSize = _windowSize - _pos; 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size < curSize) 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync curSize = size; 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize); 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numReadBytes == 0) 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size -= (uint)numReadBytes; 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _pos += (uint)numReadBytes; 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamPos += (uint)numReadBytes; 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_pos == _windowSize) 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamPos = _pos = 0; 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void ReleaseStream() 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Flush(); 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _stream = null; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void Flush() 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint size = _pos - _streamPos; 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size == 0) 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _stream.Write(_buffer, (int)_streamPos, (int)size); 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_pos >= _windowSize) 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _pos = 0; 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamPos = _pos; 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void CopyBlock(uint distance, uint len) 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint pos = _pos - distance - 1; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos >= _windowSize) 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos += _windowSize; 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; len > 0; len--) 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos >= _windowSize) 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos = 0; 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer[_pos++] = _buffer[pos++]; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_pos >= _windowSize) 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Flush(); 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public void PutByte(byte b) 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer[_pos++] = b; 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_pos >= _windowSize) 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Flush(); 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public byte GetByte(uint distance) 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uint pos = _pos - distance - 1; 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos >= _windowSize) 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos += _windowSize; 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _buffer[pos]; 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 111