LzOutWindow.cs 3.6 KB

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