/****************************************************** * 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; } } }