misc/libphysfs/lzma/CS/7zip/Compress/LZ/LzInWindow.cs
changeset 13881 99b265e0d1d0
parent 13880 5f819b90d479
child 13882 b172a5d40eee
equal deleted inserted replaced
13880:5f819b90d479 13881:99b265e0d1d0
     1 // LzInWindow.cs
       
     2 
       
     3 using System;
       
     4 
       
     5 namespace SevenZip.Compression.LZ
       
     6 {
       
     7 	public class InWindow
       
     8 	{
       
     9 		public Byte[] _bufferBase = null; // pointer to buffer with data
       
    10 		System.IO.Stream _stream;
       
    11 		UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
       
    12 		bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
       
    13 
       
    14 		UInt32 _pointerToLastSafePosition;
       
    15 
       
    16 		public UInt32 _bufferOffset;
       
    17 
       
    18 		public UInt32 _blockSize; // Size of Allocated memory block
       
    19 		public UInt32 _pos; // offset (from _buffer) of curent byte
       
    20 		UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
       
    21 		UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
       
    22 		public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
       
    23 
       
    24 		public void MoveBlock()
       
    25 		{
       
    26 			UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;
       
    27 			// we need one additional byte, since MovePos moves on 1 byte.
       
    28 			if (offset > 0)
       
    29 				offset--;
       
    30 			
       
    31 			UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset;
       
    32 
       
    33 			// check negative offset ????
       
    34 			for (UInt32 i = 0; i < numBytes; i++)
       
    35 				_bufferBase[i] = _bufferBase[offset + i];
       
    36 			_bufferOffset -= offset;
       
    37 		}
       
    38 
       
    39 		public virtual void ReadBlock()
       
    40 		{
       
    41 			if (_streamEndWasReached)
       
    42 				return;
       
    43 			while (true)
       
    44 			{
       
    45 				int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);
       
    46 				if (size == 0)
       
    47 					return;
       
    48 				int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size);
       
    49 				if (numReadBytes == 0)
       
    50 				{
       
    51 					_posLimit = _streamPos;
       
    52 					UInt32 pointerToPostion = _bufferOffset + _posLimit;
       
    53 					if (pointerToPostion > _pointerToLastSafePosition)
       
    54 						_posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);
       
    55 
       
    56 					_streamEndWasReached = true;
       
    57 					return;
       
    58 				}
       
    59 				_streamPos += (UInt32)numReadBytes;
       
    60 				if (_streamPos >= _pos + _keepSizeAfter)
       
    61 					_posLimit = _streamPos - _keepSizeAfter;
       
    62 			}
       
    63 		}
       
    64 
       
    65 		void Free() { _bufferBase = null; }
       
    66 
       
    67 		public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
       
    68 		{
       
    69 			_keepSizeBefore = keepSizeBefore;
       
    70 			_keepSizeAfter = keepSizeAfter;
       
    71 			UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
       
    72 			if (_bufferBase == null || _blockSize != blockSize)
       
    73 			{
       
    74 				Free();
       
    75 				_blockSize = blockSize;
       
    76 				_bufferBase = new Byte[_blockSize];
       
    77 			}
       
    78 			_pointerToLastSafePosition = _blockSize - keepSizeAfter;
       
    79 		}
       
    80 
       
    81 		public void SetStream(System.IO.Stream stream) { _stream = stream; }
       
    82 		public void ReleaseStream() { _stream = null; }
       
    83 
       
    84 		public void Init()
       
    85 		{
       
    86 			_bufferOffset = 0;
       
    87 			_pos = 0;
       
    88 			_streamPos = 0;
       
    89 			_streamEndWasReached = false;
       
    90 			ReadBlock();
       
    91 		}
       
    92 
       
    93 		public void MovePos()
       
    94 		{
       
    95 			_pos++;
       
    96 			if (_pos > _posLimit)
       
    97 			{
       
    98 				UInt32 pointerToPostion = _bufferOffset + _pos;
       
    99 				if (pointerToPostion > _pointerToLastSafePosition)
       
   100 					MoveBlock();
       
   101 				ReadBlock();
       
   102 			}
       
   103 		}
       
   104 
       
   105 		public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; }
       
   106 
       
   107 		// index + limit have not to exceed _keepSizeAfter;
       
   108 		public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
       
   109 		{
       
   110 			if (_streamEndWasReached)
       
   111 				if ((_pos + index) + limit > _streamPos)
       
   112 					limit = _streamPos - (UInt32)(_pos + index);
       
   113 			distance++;
       
   114 			// Byte *pby = _buffer + (size_t)_pos + index;
       
   115 			UInt32 pby = _bufferOffset + _pos + (UInt32)index;
       
   116 
       
   117 			UInt32 i;
       
   118 			for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
       
   119 			return i;
       
   120 		}
       
   121 
       
   122 		public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; }
       
   123 
       
   124 		public void ReduceOffsets(Int32 subValue)
       
   125 		{
       
   126 			_bufferOffset += (UInt32)subValue;
       
   127 			_posLimit -= (UInt32)subValue;
       
   128 			_pos -= (UInt32)subValue;
       
   129 			_streamPos -= (UInt32)subValue;
       
   130 		}
       
   131 	}
       
   132 }