LzOutWindow.cs 2.1 KB

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