LzInWindow.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* This file is part of SevenZipSharp.
  2. SevenZipSharp is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU Lesser General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. SevenZipSharp is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU Lesser General Public License for more details.
  10. You should have received a copy of the GNU Lesser General Public License
  11. along with SevenZipSharp. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. using System;
  14. using System.IO;
  15. namespace SevenZip.Sdk.Compression.LZ
  16. {
  17. /// <summary>
  18. /// Input window class
  19. /// </summary>
  20. internal class InWindow
  21. {
  22. /// <summary>
  23. /// Size of Allocated memory block
  24. /// </summary>
  25. public UInt32 _blockSize;
  26. /// <summary>
  27. /// The pointer to buffer with data
  28. /// </summary>
  29. public Byte[] _bufferBase;
  30. /// <summary>
  31. /// Buffer offset value
  32. /// </summary>
  33. public UInt32 _bufferOffset;
  34. /// <summary>
  35. /// How many BYTEs must be kept buffer after _pos
  36. /// </summary>
  37. private UInt32 _keepSizeAfter;
  38. /// <summary>
  39. /// How many BYTEs must be kept in buffer before _pos
  40. /// </summary>
  41. private UInt32 _keepSizeBefore;
  42. private UInt32 _pointerToLastSafePosition;
  43. /// <summary>
  44. /// Offset (from _buffer) of curent byte
  45. /// </summary>
  46. public UInt32 _pos;
  47. private UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
  48. private Stream _stream;
  49. private bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
  50. /// <summary>
  51. /// Offset (from _buffer) of first not read byte from Stream
  52. /// </summary>
  53. public UInt32 _streamPos;
  54. public void MoveBlock()
  55. {
  56. UInt32 offset = (_bufferOffset) + _pos - _keepSizeBefore;
  57. // we need one additional byte, since MovePos moves on 1 byte.
  58. if (offset > 0)
  59. offset--;
  60. UInt32 numBytes = (_bufferOffset) + _streamPos - offset;
  61. // check negative offset ????
  62. for (UInt32 i = 0; i < numBytes; i++)
  63. _bufferBase[i] = _bufferBase[offset + i];
  64. _bufferOffset -= offset;
  65. }
  66. public virtual void ReadBlock()
  67. {
  68. if (_streamEndWasReached)
  69. return;
  70. while (true)
  71. {
  72. var size = (int) ((0 - _bufferOffset) + _blockSize - _streamPos);
  73. if (size == 0)
  74. return;
  75. int numReadBytes = _stream.Read(_bufferBase, (int) (_bufferOffset + _streamPos), size);
  76. if (numReadBytes == 0)
  77. {
  78. _posLimit = _streamPos;
  79. UInt32 pointerToPostion = _bufferOffset + _posLimit;
  80. if (pointerToPostion > _pointerToLastSafePosition)
  81. _posLimit = (_pointerToLastSafePosition - _bufferOffset);
  82. _streamEndWasReached = true;
  83. return;
  84. }
  85. _streamPos += (UInt32) numReadBytes;
  86. if (_streamPos >= _pos + _keepSizeAfter)
  87. _posLimit = _streamPos - _keepSizeAfter;
  88. }
  89. }
  90. private void Free()
  91. {
  92. _bufferBase = null;
  93. }
  94. public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
  95. {
  96. _keepSizeBefore = keepSizeBefore;
  97. _keepSizeAfter = keepSizeAfter;
  98. UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
  99. if (_bufferBase == null || _blockSize != blockSize)
  100. {
  101. Free();
  102. _blockSize = blockSize;
  103. _bufferBase = new Byte[_blockSize];
  104. }
  105. _pointerToLastSafePosition = _blockSize - keepSizeAfter;
  106. }
  107. public void SetStream(Stream stream)
  108. {
  109. _stream = stream;
  110. }
  111. public void ReleaseStream()
  112. {
  113. _stream = null;
  114. }
  115. public void Init()
  116. {
  117. _bufferOffset = 0;
  118. _pos = 0;
  119. _streamPos = 0;
  120. _streamEndWasReached = false;
  121. ReadBlock();
  122. }
  123. public void MovePos()
  124. {
  125. _pos++;
  126. if (_pos > _posLimit)
  127. {
  128. UInt32 pointerToPostion = _bufferOffset + _pos;
  129. if (pointerToPostion > _pointerToLastSafePosition)
  130. MoveBlock();
  131. ReadBlock();
  132. }
  133. }
  134. public Byte GetIndexByte(Int32 index)
  135. {
  136. return _bufferBase[_bufferOffset + _pos + index];
  137. }
  138. /// <summary>
  139. /// index + limit have not to exceed _keepSizeAfter
  140. /// </summary>
  141. /// <param name="index"></param>
  142. /// <param name="distance"></param>
  143. /// <param name="limit"></param>
  144. /// <returns></returns>
  145. public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
  146. {
  147. if (_streamEndWasReached)
  148. if ((_pos + index) + limit > _streamPos)
  149. limit = _streamPos - (UInt32) (_pos + index);
  150. distance++;
  151. // Byte *pby = _buffer + (size_t)_pos + index;
  152. UInt32 pby = _bufferOffset + _pos + (UInt32) index;
  153. UInt32 i;
  154. for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++) ;
  155. return i;
  156. }
  157. public UInt32 GetNumAvailableBytes()
  158. {
  159. return _streamPos - _pos;
  160. }
  161. public void ReduceOffsets(Int32 subValue)
  162. {
  163. _bufferOffset += (UInt32) subValue;
  164. _posLimit -= (UInt32) subValue;
  165. _pos -= (UInt32) subValue;
  166. _streamPos -= (UInt32) subValue;
  167. }
  168. }
  169. }