Refactor: Use delegates to report progress and status.

This commit is contained in:
2017-05-28 00:31:46 +01:00
parent 33d8945f1d
commit 8d3e4fe420
10 changed files with 345 additions and 45 deletions

View File

@@ -40,7 +40,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using DiscImageChef.Checksums; using DiscImageChef.Checksums;
using DiscImageChef.Console;
namespace DiscImageChef.Core namespace DiscImageChef.Core
{ {
@@ -69,6 +68,28 @@ namespace DiscImageChef.Core
public static class Benchmark public static class Benchmark
{ {
public static event InitProgressHandler InitProgressEvent;
public static event UpdateProgressHandler UpdateProgressEvent;
public static event EndProgressHandler EndProgressEvent;
public static void InitProgress()
{
if(InitProgressEvent != null)
InitProgressEvent();
}
public static void UpdateProgress(string text, int current, int maximum)
{
if(UpdateProgressEvent != null)
UpdateProgressEvent(string.Format(text, current, maximum), current, maximum);
}
public static void EndProgress()
{
if(EndProgressEvent != null)
EndProgressEvent();
}
public static BenchmarkResults Do(int bufferSize, int blockSize) public static BenchmarkResults Do(int bufferSize, int blockSize)
{ {
BenchmarkResults results = new BenchmarkResults(); BenchmarkResults results = new BenchmarkResults();
@@ -83,19 +104,18 @@ namespace DiscImageChef.Core
long mem; long mem;
object ctx; object ctx;
DicConsole.WriteLine();
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rWriting block {0} of {1} with random data.", i + 1, bufferSize / blockSize); UpdateProgress("Writing block {0} of {1} with random data.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
rnd.NextBytes(tmp); rnd.NextBytes(tmp);
ms.Write(tmp, 0, blockSize); ms.Write(tmp, 0, blockSize);
} }
EndProgress();
end = DateTime.Now; end = DateTime.Now;
DicConsole.WriteLine();
results.fillTime = (end - start).TotalSeconds; results.fillTime = (end - start).TotalSeconds;
results.fillSpeed = (bufferSize / 1048576) / (end - start).TotalSeconds; results.fillSpeed = (bufferSize / 1048576) / (end - start).TotalSeconds;
@@ -106,12 +126,14 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rReading block {0} of {1}.", i + 1, bufferSize / blockSize); UpdateProgress("Reading block {0} of {1}.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
} }
EndProgress();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
if(mem > results.maxMemory) if(mem > results.maxMemory)
@@ -119,7 +141,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.readTime = (end - start).TotalSeconds; results.readTime = (end - start).TotalSeconds;
results.readSpeed = (bufferSize / 1048576) / (end - start).TotalSeconds; results.readSpeed = (bufferSize / 1048576) / (end - start).TotalSeconds;
@@ -133,13 +154,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with Adler32.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with Adler32.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((Adler32Context)ctx).Update(tmp); ((Adler32Context)ctx).Update(tmp);
} }
EndProgress();
((Adler32Context)ctx).End(); ((Adler32Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -148,7 +171,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("Adler32", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("Adler32", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion Adler32 #endregion Adler32
@@ -163,13 +185,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with CRC16.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with CRC16.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((CRC16Context)ctx).Update(tmp); ((CRC16Context)ctx).Update(tmp);
} }
EndProgress();
((CRC16Context)ctx).End(); ((CRC16Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -178,7 +202,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("CRC16", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("CRC16", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion CRC16 #endregion CRC16
@@ -193,13 +216,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with CRC32.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with CRC32.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((CRC32Context)ctx).Update(tmp); ((CRC32Context)ctx).Update(tmp);
} }
EndProgress();
((CRC32Context)ctx).End(); ((CRC32Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -208,7 +233,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("CRC32", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("CRC32", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion CRC32 #endregion CRC32
@@ -223,13 +247,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with CRC64.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with CRC64.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((CRC64Context)ctx).Update(tmp); ((CRC64Context)ctx).Update(tmp);
} }
EndProgress();
((CRC64Context)ctx).End(); ((CRC64Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -238,7 +264,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("CRC64", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("CRC64", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion CRC64 #endregion CRC64
@@ -253,13 +278,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with MD5.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with MD5.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((MD5Context)ctx).Update(tmp); ((MD5Context)ctx).Update(tmp);
} }
EndProgress();
((MD5Context)ctx).End(); ((MD5Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -268,7 +295,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("MD5", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("MD5", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion MD5 #endregion MD5
@@ -283,13 +309,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with RIPEMD160.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with RIPEMD160.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((RIPEMD160Context)ctx).Update(tmp); ((RIPEMD160Context)ctx).Update(tmp);
} }
EndProgress();
((RIPEMD160Context)ctx).End(); ((RIPEMD160Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -298,7 +326,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("RIPEMD160", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("RIPEMD160", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion RIPEMD160 #endregion RIPEMD160
@@ -313,13 +340,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with SHA1.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with SHA1.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((SHA1Context)ctx).Update(tmp); ((SHA1Context)ctx).Update(tmp);
} }
EndProgress();
((SHA1Context)ctx).End(); ((SHA1Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -328,7 +357,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("SHA1", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("SHA1", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion SHA1 #endregion SHA1
@@ -343,13 +371,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with SHA256.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with SHA256.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((SHA256Context)ctx).Update(tmp); ((SHA256Context)ctx).Update(tmp);
} }
EndProgress();
((SHA256Context)ctx).End(); ((SHA256Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -358,7 +388,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("SHA256", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("SHA256", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion SHA256 #endregion SHA256
@@ -373,13 +402,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with SHA384.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with SHA384.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((SHA384Context)ctx).Update(tmp); ((SHA384Context)ctx).Update(tmp);
} }
EndProgress();
((SHA384Context)ctx).End(); ((SHA384Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -388,7 +419,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("SHA384", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("SHA384", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion SHA384 #endregion SHA384
@@ -403,13 +433,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with SHA512.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with SHA512.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((SHA512Context)ctx).Update(tmp); ((SHA512Context)ctx).Update(tmp);
} }
EndProgress();
((SHA512Context)ctx).End(); ((SHA512Context)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -418,7 +450,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("SHA512", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("SHA512", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion SHA512 #endregion SHA512
@@ -433,13 +464,15 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with SpamSum.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with SpamSum.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
((SpamSumContext)ctx).Update(tmp); ((SpamSumContext)ctx).Update(tmp);
} }
EndProgress();
((SpamSumContext)ctx).End(); ((SpamSumContext)ctx).End();
end = DateTime.Now; end = DateTime.Now;
mem = GC.GetTotalMemory(false); mem = GC.GetTotalMemory(false);
@@ -448,7 +481,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entries.Add("SpamSum", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.entries.Add("SpamSum", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds });
results.separateTime += (end - start).TotalSeconds; results.separateTime += (end - start).TotalSeconds;
#endregion SpamSum #endregion SpamSum
@@ -462,14 +494,16 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
start = DateTime.Now; start = DateTime.Now;
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rEntropying block {0} of {1}.", i + 1, bufferSize / blockSize); UpdateProgress("Entropying block {0} of {1}.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
foreach(byte b in tmp) foreach(byte b in tmp)
entTable[b]++; entTable[b]++;
} }
EndProgress();
double entropy = 0; double entropy = 0;
foreach(ulong l in entTable) foreach(ulong l in entTable)
{ {
@@ -485,7 +519,6 @@ namespace DiscImageChef.Core
if(mem < results.minMemory) if(mem < results.minMemory)
results.minMemory = mem; results.minMemory = mem;
DicConsole.WriteLine();
results.entropyTime = (end - start).TotalSeconds; results.entropyTime = (end - start).TotalSeconds;
results.entropySpeed = (bufferSize / 1048576) / (end - start).TotalSeconds; results.entropySpeed = (bufferSize / 1048576) / (end - start).TotalSeconds;
#endregion Entropy #endregion Entropy
@@ -493,16 +526,16 @@ namespace DiscImageChef.Core
#region Multitasking #region Multitasking
start = DateTime.Now; start = DateTime.Now;
Checksum allChecksums = new Checksum(); Checksum allChecksums = new Checksum();
InitProgress();
for(int i = 0; i < bufferSize / blockSize; i++) for(int i = 0; i < bufferSize / blockSize; i++)
{ {
DicConsole.Write("\rChecksumming block {0} of {1} with all algorithms at the same time.", i + 1, bufferSize / blockSize); UpdateProgress("Checksumming block {0} of {1} with all algorithms at the same time.", i + 1, bufferSize / blockSize);
byte[] tmp = new byte[blockSize]; byte[] tmp = new byte[blockSize];
ms.Read(tmp, 0, blockSize); ms.Read(tmp, 0, blockSize);
allChecksums.Update(tmp); allChecksums.Update(tmp);
} }
DicConsole.WriteLine(); EndProgress();
allChecksums.End(); allChecksums.End();
end = DateTime.Now; end = DateTime.Now;

View File

@@ -1,3 +1,11 @@
2017-05-28 Natalia Portillo <claunia@claunia.com>
* Sidecar.cs:
* Benchmark.cs:
* Delegates.cs:
* DiscImageChef.Core.csproj: Refactor: Use delegates to report
progress and status.
2017-05-27 Natalia Portillo <claunia@claunia.com> 2017-05-27 Natalia Portillo <claunia@claunia.com>
* Benchmark.cs: Refactor: Return result from core to CLI, show * Benchmark.cs: Refactor: Return result from core to CLI, show

View File

@@ -0,0 +1,96 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Delegates.cs
// Version : 1.0
// Author(s) : Natalia Portillo
//
// Component : Component
//
// Revision : $Revision$
// Last change by : $Author$
// Date : $Date$
//
// --[ Description ] ----------------------------------------------------------
//
// Description
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright (C) 2011-2015 Claunia.com
// ****************************************************************************/
// //$Id$
namespace DiscImageChef.Core
{
/// <summary>
/// Initializates a progress indicator (e.g. makes a progress bar visible)
/// </summary>
public delegate void InitProgressHandler();
/// <summary>
/// Updates a progress indicator with text
/// </summary>
public delegate void UpdateProgressHandler(string text, long current, long maximum);
/// <summary>
/// Pulses a progress indicator with indeterminate boundaries
/// </summary>
public delegate void PulseProgressHandler(string text);
/// <summary>
/// Uninitializates a progress indicator (e.g. adds a newline to the console)
/// </summary>
public delegate void EndProgressHandler();
/// <summary>
/// Initializates a secondary progress indicator (e.g. makes a progress bar visible)
/// </summary>
public delegate void InitProgressHandler2();
/// <summary>
/// Updates a secondary progress indicator with text
/// </summary>
public delegate void UpdateProgressHandler2(string text, long current, long maximum);
/// <summary>
/// Pulses a secondary progress indicator with indeterminate boundaries
/// </summary>
public delegate void PulseProgressHandler2(string text);
/// <summary>
/// Uninitializates a secondary progress indicator (e.g. adds a newline to the console)
/// </summary>
public delegate void EndProgressHandler2();
/// <summary>
/// Initializates two progress indicators (e.g. makes a progress bar visible)
/// </summary>
public delegate void InitTwoProgressHandler();
/// <summary>
/// Updates two progress indicators with text
/// </summary>
public delegate void UpdateTwoProgressHandler(string text, long current, long maximum, string text2, long current2, long maximum2);
/// <summary>
/// Pulses a progress indicator with indeterminate boundaries
/// </summary>
public delegate void PulseTwoProgressHandler(string text, string text2);
/// <summary>
/// Uninitializates a progress indicator (e.g. adds a newline to the console)
/// </summary>
public delegate void EndTwoProgressHandler();
/// <summary>
/// Updates a status indicator
/// </summary>
public delegate void UpdateStatusHandler(string text);
}

View File

@@ -53,6 +53,7 @@
<Compile Include="Filesystems.cs" /> <Compile Include="Filesystems.cs" />
<Compile Include="Sidecar.cs" /> <Compile Include="Sidecar.cs" />
<Compile Include="Benchmark.cs" /> <Compile Include="Benchmark.cs" />
<Compile Include="Delegates.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\DiscImageChef.Console\DiscImageChef.Console.csproj"> <ProjectReference Include="..\DiscImageChef.Console\DiscImageChef.Console.csproj">

View File

@@ -49,6 +49,56 @@ namespace DiscImageChef.Core
{ {
public static class Sidecar public static class Sidecar
{ {
public static event InitProgressHandler InitProgressEvent;
public static event UpdateProgressHandler UpdateProgressEvent;
public static event EndProgressHandler EndProgressEvent;
public static event InitProgressHandler2 InitProgressEvent2;
public static event UpdateProgressHandler2 UpdateProgressEvent2;
public static event EndProgressHandler2 EndProgressEvent2;
public static event UpdateStatusHandler UpdateStatusEvent;
public static void InitProgress()
{
if(InitProgressEvent != null)
InitProgressEvent();
}
public static void UpdateProgress(string text, long current, long maximum)
{
if(UpdateProgressEvent != null)
UpdateProgressEvent(string.Format(text, current, maximum), current, maximum);
}
public static void EndProgress()
{
if(EndProgressEvent != null)
EndProgressEvent();
}
public static void InitProgress2()
{
if(InitProgressEvent2 != null)
InitProgressEvent2();
}
public static void UpdateProgress2(string text, long current, long maximum)
{
if(UpdateProgressEvent2 != null)
UpdateProgressEvent2(string.Format(text, current, maximum), current, maximum);
}
public static void EndProgress2()
{
if(EndProgressEvent2 != null)
EndProgressEvent2();
}
public static void UpdateStatus(string text, params object[] args)
{
if(UpdateStatusEvent != null)
UpdateStatusEvent(string.Format(text, args));
}
public static CICMMetadataType Create(ImagePlugin image, string imagePath) public static CICMMetadataType Create(ImagePlugin image, string imagePath)
{ {
CICMMetadataType sidecar = new CICMMetadataType(); CICMMetadataType sidecar = new CICMMetadataType();
@@ -65,12 +115,13 @@ namespace DiscImageChef.Core
byte[] data; byte[] data;
long position = 0; long position = 0;
InitProgress();
while(position < (fi.Length - 1048576)) while(position < (fi.Length - 1048576))
{ {
data = new byte[1048576]; data = new byte[1048576];
fs.Read(data, 0, 1048576); fs.Read(data, 0, 1048576);
DicConsole.Write("\rHashing image file byte {0} of {1}", position, fi.Length); UpdateProgress("Hashing image file byte {0} of {1}", position, fi.Length);
imgChkWorker.Update(data); imgChkWorker.Update(data);
@@ -80,14 +131,14 @@ namespace DiscImageChef.Core
data = new byte[fi.Length - position]; data = new byte[fi.Length - position];
fs.Read(data, 0, (int)(fi.Length - position)); fs.Read(data, 0, (int)(fi.Length - position));
DicConsole.Write("\rHashing image file byte {0} of {1}", position, fi.Length); UpdateProgress("Hashing image file byte {0} of {1}", position, fi.Length);
imgChkWorker.Update(data); imgChkWorker.Update(data);
// For fast debugging, skip checksum // For fast debugging, skip checksum
//skipImageChecksum: //skipImageChecksum:
DicConsole.WriteLine(); EndProgress();
fs.Close(); fs.Close();
List<ChecksumType> imgChecksums = imgChkWorker.End(); List<ChecksumType> imgChecksums = imgChkWorker.End();
@@ -286,8 +337,10 @@ namespace DiscImageChef.Core
trksLst = new List<Schemas.TrackType>(); trksLst = new List<Schemas.TrackType>();
} }
InitProgress();
foreach(Track trk in tracks) foreach(Track trk in tracks)
{ {
UpdateProgress("Track {0} of {1}", trk.TrackSequence, tracks.Count);
Schemas.TrackType xmlTrk = new Schemas.TrackType(); Schemas.TrackType xmlTrk = new Schemas.TrackType();
switch(trk.TrackType) switch(trk.TrackType)
{ {
@@ -374,6 +427,7 @@ namespace DiscImageChef.Core
ulong sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); ulong sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1);
ulong doneSectors = 0; ulong doneSectors = 0;
InitProgress2();
while(doneSectors < sectors) while(doneSectors < sectors)
{ {
byte[] sector; byte[] sector;
@@ -381,13 +435,13 @@ namespace DiscImageChef.Core
if((sectors - doneSectors) >= sectorsToRead) if((sectors - doneSectors) >= sectorsToRead)
{ {
sector = image.ReadSectorsLong(doneSectors, sectorsToRead, (uint)xmlTrk.Sequence.TrackNumber); sector = image.ReadSectorsLong(doneSectors, sectorsToRead, (uint)xmlTrk.Sequence.TrackNumber);
DicConsole.Write("\rHashings sectors {0} to {2} of track {1} ({3} sectors)", doneSectors, xmlTrk.Sequence.TrackNumber, doneSectors + sectorsToRead, sectors); UpdateProgress2("Hashings sector {0} of {1}", (long)doneSectors, (long)(trk.TrackEndSector - trk.TrackStartSector + 1));
doneSectors += sectorsToRead; doneSectors += sectorsToRead;
} }
else else
{ {
sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), (uint)xmlTrk.Sequence.TrackNumber); sector = image.ReadSectorsLong(doneSectors, (uint)(sectors - doneSectors), (uint)xmlTrk.Sequence.TrackNumber);
DicConsole.Write("\rHashings sectors {0} to {2} of track {1} ({3} sectors)", doneSectors, xmlTrk.Sequence.TrackNumber, doneSectors + (sectors - doneSectors), sectors); UpdateProgress2("Hashings sector {0} of {1}", (long)doneSectors, (long)(trk.TrackEndSector - trk.TrackStartSector + 1));
doneSectors += (sectors - doneSectors); doneSectors += (sectors - doneSectors);
} }
@@ -398,7 +452,7 @@ namespace DiscImageChef.Core
xmlTrk.Checksums = trkChecksums.ToArray(); xmlTrk.Checksums = trkChecksums.ToArray();
DicConsole.WriteLine(); EndProgress2();
if(trk.TrackSubchannelType != TrackSubchannelType.None) if(trk.TrackSubchannelType != TrackSubchannelType.None)
{ {
@@ -435,6 +489,7 @@ namespace DiscImageChef.Core
sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1);
doneSectors = 0; doneSectors = 0;
InitProgress2();
while(doneSectors < sectors) while(doneSectors < sectors)
{ {
byte[] sector; byte[] sector;
@@ -442,13 +497,13 @@ namespace DiscImageChef.Core
if((sectors - doneSectors) >= sectorsToRead) if((sectors - doneSectors) >= sectorsToRead)
{ {
sector = image.ReadSectorsTag(doneSectors, sectorsToRead, (uint)xmlTrk.Sequence.TrackNumber, SectorTagType.CDSectorSubchannel); sector = image.ReadSectorsTag(doneSectors, sectorsToRead, (uint)xmlTrk.Sequence.TrackNumber, SectorTagType.CDSectorSubchannel);
DicConsole.Write("\rHashings subchannel sectors {0} to {2} of track {1} ({3} sectors)", doneSectors, xmlTrk.Sequence.TrackNumber, doneSectors + sectorsToRead, sectors); UpdateProgress2("Hashings subchannel sector {0} of {1}", (long)doneSectors, (long)(trk.TrackEndSector - trk.TrackStartSector + 1));
doneSectors += sectorsToRead; doneSectors += sectorsToRead;
} }
else else
{ {
sector = image.ReadSectorsTag(doneSectors, (uint)(sectors - doneSectors), (uint)xmlTrk.Sequence.TrackNumber, SectorTagType.CDSectorSubchannel); sector = image.ReadSectorsTag(doneSectors, (uint)(sectors - doneSectors), (uint)xmlTrk.Sequence.TrackNumber, SectorTagType.CDSectorSubchannel);
DicConsole.Write("\rHashings subchannel sectors {0} to {2} of track {1} ({3} sectors)", doneSectors, xmlTrk.Sequence.TrackNumber, doneSectors + (sectors - doneSectors), sectors); UpdateProgress2("Hashings subchannel sector {0} of {1}", (long)doneSectors, (long)(trk.TrackEndSector - trk.TrackStartSector + 1));
doneSectors += (sectors - doneSectors); doneSectors += (sectors - doneSectors);
} }
@@ -459,13 +514,13 @@ namespace DiscImageChef.Core
xmlTrk.SubChannel.Checksums = subChecksums.ToArray(); xmlTrk.SubChannel.Checksums = subChecksums.ToArray();
DicConsole.WriteLine(); EndProgress2();
} }
// For fast debugging, skip checksum // For fast debugging, skip checksum
//skipChecksum: //skipChecksum:
DicConsole.WriteLine("Checking filesystems on track {0} from sector {1} to {2}", xmlTrk.Sequence.TrackNumber, xmlTrk.StartSector, xmlTrk.EndSector); UpdateStatus("Checking filesystems on track {0} from sector {1} to {2}", xmlTrk.Sequence.TrackNumber, xmlTrk.StartSector, xmlTrk.EndSector);
List<Partition> partitions = new List<Partition>(); List<Partition> partitions = new List<Partition>();
@@ -572,6 +627,7 @@ namespace DiscImageChef.Core
trksLst.Add(xmlTrk); trksLst.Add(xmlTrk);
} }
EndProgress();
if(trksLst != null) if(trksLst != null)
sidecar.OpticalDisc[0].Track = trksLst.ToArray(); sidecar.OpticalDisc[0].Track = trksLst.ToArray();
@@ -734,7 +790,7 @@ namespace DiscImageChef.Core
// TODO: Detect it // TODO: Detect it
sidecar.BlockMedia[0].PhysicalBlockSize = (int)image.GetSectorSize(); sidecar.BlockMedia[0].PhysicalBlockSize = (int)image.GetSectorSize();
DicConsole.WriteLine("Checking filesystems..."); UpdateStatus("Checking filesystems...");
List<Partition> partitions = new List<Partition>(); List<Partition> partitions = new List<Partition>();

View File

@@ -1,3 +1,11 @@
2017-05-28 Natalia Portillo <claunia@claunia.com>
* Progress.cs:
* DiscImageChef.csproj:
* Commands/Benchmark.cs:
* Commands/CreateSidecar.cs:
Refactor: Use delegates to report progress and status.
2017-05-27 Natalia Portillo <claunia@claunia.com> 2017-05-27 Natalia Portillo <claunia@claunia.com>
* Commands/Benchmark.cs: * Commands/Benchmark.cs:

View File

@@ -41,6 +41,9 @@ namespace DiscImageChef.Commands
public static void doBenchmark(BenchmarkOptions options) public static void doBenchmark(BenchmarkOptions options)
{ {
Dictionary<string, double> checksumTimes = new Dictionary<string, double>(); Dictionary<string, double> checksumTimes = new Dictionary<string, double>();
Core.Benchmark.InitProgressEvent += Progress.InitProgress;
Core.Benchmark.UpdateProgressEvent += Progress.UpdateProgress;
Core.Benchmark.EndProgressEvent += Progress.EndProgress;
BenchmarkResults results = Core.Benchmark.Do(options.BufferSize * 1024 * 1024, options.BlockSize); BenchmarkResults results = Core.Benchmark.Do(options.BufferSize * 1024 * 1024, options.BlockSize);

View File

@@ -93,6 +93,14 @@ namespace DiscImageChef.Commands
Core.Statistics.AddMediaFormat(_imageFormat.GetImageFormat()); Core.Statistics.AddMediaFormat(_imageFormat.GetImageFormat());
Core.Statistics.AddFilter(inputFilter.Name); Core.Statistics.AddFilter(inputFilter.Name);
Sidecar.InitProgressEvent += Progress.InitProgress;
Sidecar.UpdateProgressEvent += Progress.UpdateProgress;
Sidecar.EndProgressEvent += Progress.EndProgress;
Sidecar.InitProgressEvent2 += Progress.InitProgress2;
Sidecar.UpdateProgressEvent2 += Progress.UpdateProgress2;
Sidecar.EndProgressEvent2 += Progress.EndProgress2;
Sidecar.UpdateStatusEvent += Progress.UpdateStatus;
CICMMetadataType sidecar = Sidecar.Create(_imageFormat, options.InputFile); CICMMetadataType sidecar = Sidecar.Create(_imageFormat, options.InputFile);
DicConsole.WriteLine("Writing metadata sidecar"); DicConsole.WriteLine("Writing metadata sidecar");

View File

@@ -67,6 +67,7 @@
<Compile Include="Commands\Statistics.cs" /> <Compile Include="Commands\Statistics.cs" />
<Compile Include="Commands\Ls.cs" /> <Compile Include="Commands\Ls.cs" />
<Compile Include="Commands\ExtractFiles.cs" /> <Compile Include="Commands\ExtractFiles.cs" />
<Compile Include="Progress.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>

86
DiscImageChef/Progress.cs Normal file
View File

@@ -0,0 +1,86 @@
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Progress.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Component
//
// --[ Description ] ----------------------------------------------------------
//
// Description
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2017 Natalia Portillo
// ****************************************************************************/
using DiscImageChef.Console;
namespace DiscImageChef
{
public static class Progress
{
public static void InitProgress()
{
}
public static void EndProgress()
{
DicConsole.WriteLine();
}
public static void UpdateProgress(string text, long current, long maximum)
{
DicConsole.Write("\r" + text);
}
public static void InitProgress2()
{
}
public static void EndProgress2()
{
DicConsole.WriteLine();
}
public static void UpdateProgress2(string text, long current, long maximum)
{
DicConsole.Write("\r" + text);
}
public static void InitTwoProgress()
{
}
public static void EndTwoProgress()
{
DicConsole.WriteLine();
}
public static void UpdateTwoProgress(string text, long current, long maximum, string text2, long current2, long maximum2)
{
DicConsole.Write("\r" + text + ": " + text2);
}
public static void UpdateStatus(string text)
{
DicConsole.WriteLine(text);
}
}
}