CrcCheckStream.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. namespace SharpCompress.Compressors.LZMA.Utilites
  5. {
  6. internal class CrcCheckStream : Stream
  7. {
  8. private readonly uint _mExpectedCrc;
  9. private uint _mCurrentCrc;
  10. private bool _mClosed;
  11. private readonly long[] _mBytes = new long[256];
  12. private long _mLength;
  13. public CrcCheckStream(uint crc)
  14. {
  15. _mExpectedCrc = crc;
  16. _mCurrentCrc = Crc.INIT_CRC;
  17. }
  18. protected override void Dispose(bool disposing)
  19. {
  20. if (_mCurrentCrc != _mExpectedCrc)
  21. {
  22. throw new InvalidOperationException();
  23. }
  24. try
  25. {
  26. if (disposing && !_mClosed)
  27. {
  28. _mClosed = true;
  29. _mCurrentCrc = Crc.Finish(_mCurrentCrc);
  30. #if DEBUG
  31. if (_mCurrentCrc == _mExpectedCrc)
  32. {
  33. Debug.WriteLine("CRC ok: " + _mExpectedCrc.ToString("x8"));
  34. }
  35. else
  36. {
  37. Debugger.Break();
  38. Debug.WriteLine("bad CRC");
  39. }
  40. double lengthInv = 1.0 / _mLength;
  41. double entropy = 0;
  42. for (int i = 0; i < 256; i++)
  43. {
  44. if (_mBytes[i] != 0)
  45. {
  46. double p = lengthInv * _mBytes[i];
  47. entropy -= p * Math.Log(p, 256);
  48. }
  49. }
  50. Debug.WriteLine("entropy: " + (int)(entropy * 100) + "%");
  51. #endif
  52. }
  53. }
  54. finally
  55. {
  56. base.Dispose(disposing);
  57. }
  58. }
  59. public override bool CanRead => false;
  60. public override bool CanSeek => false;
  61. public override bool CanWrite => true;
  62. public override void Flush()
  63. {
  64. }
  65. public override long Length => throw new NotSupportedException();
  66. public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
  67. public override int Read(byte[] buffer, int offset, int count)
  68. {
  69. throw new InvalidOperationException();
  70. }
  71. public override long Seek(long offset, SeekOrigin origin)
  72. {
  73. throw new NotSupportedException();
  74. }
  75. public override void SetLength(long value)
  76. {
  77. throw new NotSupportedException();
  78. }
  79. public override void Write(byte[] buffer, int offset, int count)
  80. {
  81. _mLength += count;
  82. for (int i = 0; i < count; i++)
  83. {
  84. _mBytes[buffer[offset + i]]++;
  85. }
  86. _mCurrentCrc = Crc.Update(_mCurrentCrc, buffer, offset, count);
  87. }
  88. }
  89. }