109 lines
3.6 KiB
C#
109 lines
3.6 KiB
C#
/******************************************************
|
|
* ROMVault2 is written by Gordon J. *
|
|
* Contact gordon@romvault.com *
|
|
* Copyright 2014 *
|
|
******************************************************/
|
|
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Threading;
|
|
using ROMVault2.SupportedFiles.Zip.ZLib;
|
|
|
|
namespace ROMVault2.SupportedFiles.Files
|
|
{
|
|
public static class UnCompFiles
|
|
{
|
|
private const int Buffersize = 4096 * 1024;
|
|
private static readonly byte[] Buffer0;
|
|
private static readonly byte[] Buffer1;
|
|
|
|
static UnCompFiles()
|
|
{
|
|
Buffer0 = new byte[Buffersize];
|
|
Buffer1 = new byte[Buffersize];
|
|
}
|
|
|
|
public static int CheckSumRead(string filename, bool testDeep, out byte[] crc, out byte[] bMD5, out byte[] bSHA1)
|
|
{
|
|
bMD5 = null;
|
|
bSHA1 = null;
|
|
crc = null;
|
|
|
|
Stream ds = null;
|
|
CRC32Hash crc32 = new CRC32Hash();
|
|
|
|
MD5 md5 = null;
|
|
if (testDeep) md5 = MD5.Create();
|
|
SHA1 sha1 = null;
|
|
if (testDeep) sha1 = SHA1.Create();
|
|
|
|
try
|
|
{
|
|
int errorCode = IO.FileStream.OpenFileRead(filename, out ds);
|
|
if (errorCode != 0)
|
|
return errorCode;
|
|
|
|
long sizetogo = ds.Length;
|
|
|
|
// Pre load the first buffer0
|
|
int sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
|
|
ds.Read(Buffer0, 0, sizeNext);
|
|
int sizebuffer = sizeNext;
|
|
sizetogo -= sizeNext;
|
|
bool whichBuffer = true;
|
|
|
|
while (sizebuffer > 0)
|
|
{
|
|
sizeNext = sizetogo > Buffersize ? Buffersize : (int)sizetogo;
|
|
|
|
Thread t0 = null;
|
|
if (sizeNext > 0)
|
|
{
|
|
t0 = new Thread(() => { ds.Read(whichBuffer ? Buffer1 : Buffer0, 0, sizeNext); });
|
|
t0.Start();
|
|
}
|
|
|
|
byte[] buffer = whichBuffer ? Buffer0 : Buffer1;
|
|
Thread t1 = new Thread(() => { crc32.TransformBlock(buffer, 0, sizebuffer, null, 0); });
|
|
t1.Start();
|
|
if (testDeep)
|
|
{
|
|
Thread t2 = new Thread(() => { md5.TransformBlock(buffer, 0, sizebuffer, null, 0); });
|
|
Thread t3 = new Thread(() => { sha1.TransformBlock(buffer, 0, sizebuffer, null, 0); });
|
|
t2.Start();
|
|
t3.Start();
|
|
t2.Join();
|
|
t3.Join();
|
|
}
|
|
if (t0 != null)
|
|
t0.Join();
|
|
t1.Join();
|
|
|
|
sizebuffer = sizeNext;
|
|
sizetogo -= sizeNext;
|
|
whichBuffer = !whichBuffer;
|
|
}
|
|
|
|
crc32.TransformFinalBlock(Buffer0, 0, 0);
|
|
if (testDeep) md5.TransformFinalBlock(Buffer0, 0, 0);
|
|
if (testDeep) sha1.TransformFinalBlock(Buffer0, 0, 0);
|
|
|
|
ds.Close();
|
|
}
|
|
catch
|
|
{
|
|
if (ds != null)
|
|
ds.Close();
|
|
|
|
return 0x17;
|
|
}
|
|
|
|
crc = crc32.Hash;
|
|
if (testDeep) bMD5 = md5.Hash;
|
|
if (testDeep) bSHA1 = sha1.Hash;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|