Files

111 lines
3.0 KiB
C#
Raw Permalink Normal View History

2013-04-28 11:25:37 +01:00
using System;
using System.IO;
2013-04-28 12:23:41 +01:00
namespace SharpCompress.Compressor.LZMA
2013-04-07 10:58:58 +01:00
{
2013-04-28 11:25:37 +01:00
internal static class CRC
2013-04-07 10:58:58 +01:00
{
2013-04-28 11:25:37 +01:00
public const uint kInitCRC = 0xFFFFFFFF;
2013-04-28 13:01:29 +01:00
private static uint[] kTable = new uint[4 * 256];
2013-04-07 10:58:58 +01:00
static CRC()
{
2013-04-28 11:25:37 +01:00
const uint kCrcPoly = 0xEDB88320;
2013-04-28 12:32:55 +01:00
for (uint i = 0; i < 256; i++)
2013-04-07 10:58:58 +01:00
{
uint r = i;
2013-04-28 12:32:55 +01:00
for (int j = 0; j < 8; j++)
2013-04-28 11:25:37 +01:00
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
kTable[i] = r;
}
2013-04-28 12:32:55 +01:00
for (uint i = 256; i < kTable.Length; i++)
2013-04-28 11:25:37 +01:00
{
uint r = kTable[i - 256];
kTable[i] = kTable[r & 0xFF] ^ (r >> 8);
}
}
public static uint From(Stream stream, long length)
{
uint crc = kInitCRC;
byte[] buffer = new byte[Math.Min(length, 4 << 10)];
2013-04-28 12:32:55 +01:00
while (length > 0)
2013-04-28 11:25:37 +01:00
{
2013-04-28 13:01:29 +01:00
int delta = stream.Read(buffer, 0, (int)Math.Min(length, buffer.Length));
2013-04-28 12:32:55 +01:00
if (delta == 0)
2013-04-28 11:25:37 +01:00
throw new EndOfStreamException();
crc = Update(crc, buffer, 0, delta);
length -= delta;
2013-04-07 10:58:58 +01:00
}
2013-04-28 11:25:37 +01:00
return Finish(crc);
2013-04-07 10:58:58 +01:00
}
2013-04-28 11:25:37 +01:00
public static uint Finish(uint crc)
{
return ~crc;
}
2013-04-07 10:58:58 +01:00
2013-04-28 11:25:37 +01:00
public static uint Update(uint crc, byte bt)
{
return kTable[(crc & 0xFF) ^ bt] ^ (crc >> 8);
}
2013-04-07 10:58:58 +01:00
2013-04-28 11:25:37 +01:00
public static uint Update(uint crc, uint value)
2013-04-07 10:58:58 +01:00
{
2013-04-28 11:25:37 +01:00
crc ^= value;
return kTable[0x300 + (crc & 0xFF)]
2013-04-28 12:32:55 +01:00
^ kTable[0x200 + ((crc >> 8) & 0xFF)]
^ kTable[0x100 + ((crc >> 16) & 0xFF)]
^ kTable[0x000 + (crc >> 24)];
2013-04-07 10:58:58 +01:00
}
2013-04-28 11:25:37 +01:00
public static uint Update(uint crc, ulong value)
2013-04-07 10:58:58 +01:00
{
2013-04-28 13:01:29 +01:00
return Update(Update(crc, (uint)value), (uint)(value >> 32));
2013-04-07 10:58:58 +01:00
}
2013-04-28 11:25:37 +01:00
public static uint Update(uint crc, long value)
{
2013-04-28 13:01:29 +01:00
return Update(crc, (ulong)value);
2013-04-28 11:25:37 +01:00
}
2013-04-07 10:58:58 +01:00
2013-04-28 11:25:37 +01:00
public static uint Update(uint crc, byte[] buffer, int offset, int length)
2013-04-07 10:58:58 +01:00
{
2013-04-28 12:32:55 +01:00
for (int i = 0; i < length; i++)
2013-04-28 11:25:37 +01:00
crc = Update(crc, buffer[offset + i]);
return crc;
2013-04-07 10:58:58 +01:00
}
2013-04-28 13:01:29 +01:00
#if !PORTABLE && !NETFX_CORE
2013-04-28 11:25:37 +01:00
public static unsafe uint Update(uint crc, byte* buffer, int length)
2013-04-07 10:58:58 +01:00
{
2013-04-28 12:32:55 +01:00
while (length > 0 && ((int) buffer & 3) != 0)
2013-04-28 11:25:37 +01:00
{
crc = Update(crc, *buffer);
buffer++;
length--;
}
2013-04-28 12:32:55 +01:00
while (length >= 4)
2013-04-28 11:25:37 +01:00
{
2013-04-28 12:32:55 +01:00
crc = Update(crc, *(uint*) buffer);
2013-04-28 11:25:37 +01:00
buffer += 4;
length -= 4;
}
2013-04-28 12:32:55 +01:00
while (length > 0)
2013-04-28 11:25:37 +01:00
{
crc = Update(crc, *buffer);
length--;
}
return crc;
2013-04-07 10:58:58 +01:00
}
2013-04-28 11:25:37 +01:00
#endif
2013-04-07 10:58:58 +01:00
}
2013-04-28 12:32:55 +01:00
}