125 lines
3.7 KiB
C#
125 lines
3.7 KiB
C#
/* This file is part of SevenZipSharp.
|
|
|
|
SevenZipSharp is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SevenZipSharp is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using System.IO;
|
|
|
|
namespace SevenZip.Sdk.Compression.LZ
|
|
{
|
|
internal class OutWindow
|
|
{
|
|
private byte[] _buffer;
|
|
private uint _pos;
|
|
private Stream _stream;
|
|
private uint _streamPos;
|
|
private uint _windowSize;
|
|
public uint TrainSize;
|
|
|
|
public void Create(uint windowSize)
|
|
{
|
|
if (_windowSize != windowSize)
|
|
{
|
|
// System.GC.Collect();
|
|
_buffer = new byte[windowSize];
|
|
}
|
|
_windowSize = windowSize;
|
|
_pos = 0;
|
|
_streamPos = 0;
|
|
}
|
|
|
|
public void Init(Stream stream, bool solid)
|
|
{
|
|
ReleaseStream();
|
|
_stream = stream;
|
|
if (!solid)
|
|
{
|
|
_streamPos = 0;
|
|
_pos = 0;
|
|
TrainSize = 0;
|
|
}
|
|
}
|
|
|
|
public bool Train(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];
|
|
}
|
|
}
|
|
} |