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