2013-04-28 11:25:37 +01:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SharpCompress.Compressor.LZMA.Utilites
|
|
|
|
|
|
{
|
2013-04-28 12:32:55 +01:00
|
|
|
|
internal class CrcCheckStream : Stream
|
2013-04-28 11:25:37 +01:00
|
|
|
|
{
|
|
|
|
|
|
private readonly uint mExpectedCRC;
|
|
|
|
|
|
private uint mCurrentCRC;
|
|
|
|
|
|
private bool mClosed;
|
|
|
|
|
|
|
|
|
|
|
|
private long[] mBytes = new long[256];
|
|
|
|
|
|
private long mLength;
|
|
|
|
|
|
|
|
|
|
|
|
public CrcCheckStream(uint crc)
|
|
|
|
|
|
{
|
|
|
|
|
|
mExpectedCRC = crc;
|
2013-04-28 12:23:41 +01:00
|
|
|
|
mCurrentCRC = CRC.kInitCRC;
|
2013-04-28 11:25:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (mCurrentCRC != mExpectedCRC)
|
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2013-04-28 12:32:55 +01:00
|
|
|
|
if (disposing && !mClosed)
|
2013-04-28 11:25:37 +01:00
|
|
|
|
{
|
|
|
|
|
|
mClosed = true;
|
2013-04-28 12:23:41 +01:00
|
|
|
|
mCurrentCRC = CRC.Finish(mCurrentCRC);
|
2013-04-28 11:25:37 +01:00
|
|
|
|
#if DEBUG
|
2013-04-28 12:32:55 +01:00
|
|
|
|
if (mCurrentCRC == mExpectedCRC)
|
2013-04-28 11:25:37 +01:00
|
|
|
|
System.Diagnostics.Debug.WriteLine("CRC ok: " + mExpectedCRC.ToString("x8"));
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debugger.Break();
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("bad CRC");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2013-04-28 12:32:55 +01:00
|
|
|
|
double lengthInv = 1.0/mLength;
|
2013-04-28 11:25:37 +01:00
|
|
|
|
double entropy = 0;
|
2013-04-28 12:32:55 +01:00
|
|
|
|
for (int i = 0; i < 256; i++)
|
2013-04-28 11:25:37 +01:00
|
|
|
|
{
|
2013-04-28 12:32:55 +01:00
|
|
|
|
if (mBytes[i] != 0)
|
2013-04-28 11:25:37 +01:00
|
|
|
|
{
|
2013-04-28 12:32:55 +01:00
|
|
|
|
double p = lengthInv*mBytes[i];
|
|
|
|
|
|
entropy -= p*Math.Log(p, 256);
|
2013-04-28 11:25:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2013-04-28 12:32:55 +01:00
|
|
|
|
System.Diagnostics.Debug.WriteLine("entropy: " + (int) (entropy*100) + "%");
|
2013-04-28 11:25:37 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
base.Dispose(disposing);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override bool CanRead
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return false; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override bool CanSeek
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return false; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override bool CanWrite
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return true; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void Flush()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override long Length
|
|
|
|
|
|
{
|
|
|
|
|
|
get { throw new NotSupportedException(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override long Position
|
|
|
|
|
|
{
|
|
|
|
|
|
get { throw new NotSupportedException(); }
|
|
|
|
|
|
set { throw new NotSupportedException(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override int Read(byte[] buffer, int offset, int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override long Seek(long offset, SeekOrigin origin)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void SetLength(long value)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
|
|
|
|
{
|
|
|
|
|
|
mLength += count;
|
2013-04-28 12:32:55 +01:00
|
|
|
|
for (int i = 0; i < count; i++)
|
2013-04-28 11:25:37 +01:00
|
|
|
|
mBytes[buffer[offset + i]]++;
|
|
|
|
|
|
|
2013-04-28 12:23:41 +01:00
|
|
|
|
mCurrentCRC = CRC.Update(mCurrentCRC, buffer, offset, count);
|
2013-04-28 11:25:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2013-04-28 12:32:55 +01:00
|
|
|
|
}
|