From 8d3e4fe420e931eda461f745ba87c903d4c56da8 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 28 May 2017 00:31:46 +0100 Subject: [PATCH] Refactor: Use delegates to report progress and status. --- DiscImageChef.Core/Benchmark.cs | 101 ++++++++++++------- DiscImageChef.Core/ChangeLog | 8 ++ DiscImageChef.Core/Delegates.cs | 96 ++++++++++++++++++ DiscImageChef.Core/DiscImageChef.Core.csproj | 1 + DiscImageChef.Core/Sidecar.cs | 78 ++++++++++++-- DiscImageChef/ChangeLog | 8 ++ DiscImageChef/Commands/Benchmark.cs | 3 + DiscImageChef/Commands/CreateSidecar.cs | 8 ++ DiscImageChef/DiscImageChef.csproj | 1 + DiscImageChef/Progress.cs | 86 ++++++++++++++++ 10 files changed, 345 insertions(+), 45 deletions(-) create mode 100644 DiscImageChef.Core/Delegates.cs create mode 100644 DiscImageChef/Progress.cs diff --git a/DiscImageChef.Core/Benchmark.cs b/DiscImageChef.Core/Benchmark.cs index bbbe373f..4ba3a189 100644 --- a/DiscImageChef.Core/Benchmark.cs +++ b/DiscImageChef.Core/Benchmark.cs @@ -40,7 +40,6 @@ using System; using System.Collections.Generic; using System.IO; using DiscImageChef.Checksums; -using DiscImageChef.Console; namespace DiscImageChef.Core { @@ -69,6 +68,28 @@ namespace DiscImageChef.Core 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) { BenchmarkResults results = new BenchmarkResults(); @@ -83,19 +104,18 @@ namespace DiscImageChef.Core long mem; object ctx; - DicConsole.WriteLine(); - start = DateTime.Now; + InitProgress(); 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]; rnd.NextBytes(tmp); ms.Write(tmp, 0, blockSize); } + EndProgress(); end = DateTime.Now; - DicConsole.WriteLine(); results.fillTime = (end - start).TotalSeconds; results.fillSpeed = (bufferSize / 1048576) / (end - start).TotalSeconds; @@ -106,12 +126,14 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); } + EndProgress(); end = DateTime.Now; mem = GC.GetTotalMemory(false); if(mem > results.maxMemory) @@ -119,7 +141,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.readTime = (end - start).TotalSeconds; results.readSpeed = (bufferSize / 1048576) / (end - start).TotalSeconds; @@ -133,13 +154,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((Adler32Context)ctx).Update(tmp); } + EndProgress(); ((Adler32Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -148,7 +171,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("Adler32", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion Adler32 @@ -163,13 +185,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((CRC16Context)ctx).Update(tmp); } + EndProgress(); ((CRC16Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -178,7 +202,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("CRC16", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion CRC16 @@ -193,13 +216,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((CRC32Context)ctx).Update(tmp); } + EndProgress(); ((CRC32Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -208,7 +233,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("CRC32", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion CRC32 @@ -223,13 +247,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((CRC64Context)ctx).Update(tmp); } + EndProgress(); ((CRC64Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -238,7 +264,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("CRC64", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion CRC64 @@ -253,13 +278,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((MD5Context)ctx).Update(tmp); } + EndProgress(); ((MD5Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -268,7 +295,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("MD5", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion MD5 @@ -283,13 +309,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((RIPEMD160Context)ctx).Update(tmp); } + EndProgress(); ((RIPEMD160Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -298,7 +326,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("RIPEMD160", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion RIPEMD160 @@ -313,13 +340,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((SHA1Context)ctx).Update(tmp); } + EndProgress(); ((SHA1Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -328,7 +357,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("SHA1", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion SHA1 @@ -343,13 +371,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((SHA256Context)ctx).Update(tmp); } + EndProgress(); ((SHA256Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -358,7 +388,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("SHA256", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion SHA256 @@ -373,13 +402,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((SHA384Context)ctx).Update(tmp); } + EndProgress(); ((SHA384Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -388,7 +419,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("SHA384", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion SHA384 @@ -403,13 +433,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((SHA512Context)ctx).Update(tmp); } + EndProgress(); ((SHA512Context)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -418,7 +450,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("SHA512", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion SHA512 @@ -433,13 +464,15 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); ((SpamSumContext)ctx).Update(tmp); } + EndProgress(); ((SpamSumContext)ctx).End(); end = DateTime.Now; mem = GC.GetTotalMemory(false); @@ -448,7 +481,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entries.Add("SpamSum", new BenchmarkEntry() { timeSpan = (end - start).TotalSeconds, speed = (bufferSize / 1048576) / (end - start).TotalSeconds }); results.separateTime += (end - start).TotalSeconds; #endregion SpamSum @@ -462,14 +494,16 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; start = DateTime.Now; + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); foreach(byte b in tmp) entTable[b]++; } + EndProgress(); double entropy = 0; foreach(ulong l in entTable) { @@ -485,7 +519,6 @@ namespace DiscImageChef.Core if(mem < results.minMemory) results.minMemory = mem; - DicConsole.WriteLine(); results.entropyTime = (end - start).TotalSeconds; results.entropySpeed = (bufferSize / 1048576) / (end - start).TotalSeconds; #endregion Entropy @@ -493,16 +526,16 @@ namespace DiscImageChef.Core #region Multitasking start = DateTime.Now; Checksum allChecksums = new Checksum(); - + InitProgress(); 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]; ms.Read(tmp, 0, blockSize); allChecksums.Update(tmp); } - DicConsole.WriteLine(); + EndProgress(); allChecksums.End(); end = DateTime.Now; diff --git a/DiscImageChef.Core/ChangeLog b/DiscImageChef.Core/ChangeLog index 47b61ff5..fe9062e5 100644 --- a/DiscImageChef.Core/ChangeLog +++ b/DiscImageChef.Core/ChangeLog @@ -1,3 +1,11 @@ +2017-05-28 Natalia Portillo + + * Sidecar.cs: + * Benchmark.cs: + * Delegates.cs: + * DiscImageChef.Core.csproj: Refactor: Use delegates to report + progress and status. + 2017-05-27 Natalia Portillo * Benchmark.cs: Refactor: Return result from core to CLI, show diff --git a/DiscImageChef.Core/Delegates.cs b/DiscImageChef.Core/Delegates.cs new file mode 100644 index 00000000..db7afc28 --- /dev/null +++ b/DiscImageChef.Core/Delegates.cs @@ -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 . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ + +namespace DiscImageChef.Core +{ + /// + /// Initializates a progress indicator (e.g. makes a progress bar visible) + /// + public delegate void InitProgressHandler(); + /// + /// Updates a progress indicator with text + /// + public delegate void UpdateProgressHandler(string text, long current, long maximum); + /// + /// Pulses a progress indicator with indeterminate boundaries + /// + public delegate void PulseProgressHandler(string text); + /// + /// Uninitializates a progress indicator (e.g. adds a newline to the console) + /// + public delegate void EndProgressHandler(); + + /// + /// Initializates a secondary progress indicator (e.g. makes a progress bar visible) + /// + public delegate void InitProgressHandler2(); + /// + /// Updates a secondary progress indicator with text + /// + public delegate void UpdateProgressHandler2(string text, long current, long maximum); + /// + /// Pulses a secondary progress indicator with indeterminate boundaries + /// + public delegate void PulseProgressHandler2(string text); + /// + /// Uninitializates a secondary progress indicator (e.g. adds a newline to the console) + /// + public delegate void EndProgressHandler2(); + + /// + /// Initializates two progress indicators (e.g. makes a progress bar visible) + /// + public delegate void InitTwoProgressHandler(); + /// + /// Updates two progress indicators with text + /// + public delegate void UpdateTwoProgressHandler(string text, long current, long maximum, string text2, long current2, long maximum2); + /// + /// Pulses a progress indicator with indeterminate boundaries + /// + public delegate void PulseTwoProgressHandler(string text, string text2); + /// + /// Uninitializates a progress indicator (e.g. adds a newline to the console) + /// + public delegate void EndTwoProgressHandler(); + + /// + /// Updates a status indicator + /// + public delegate void UpdateStatusHandler(string text); +} diff --git a/DiscImageChef.Core/DiscImageChef.Core.csproj b/DiscImageChef.Core/DiscImageChef.Core.csproj index 5f3bd65a..0ed3f1b3 100644 --- a/DiscImageChef.Core/DiscImageChef.Core.csproj +++ b/DiscImageChef.Core/DiscImageChef.Core.csproj @@ -53,6 +53,7 @@ + diff --git a/DiscImageChef.Core/Sidecar.cs b/DiscImageChef.Core/Sidecar.cs index 0b3821d1..ece78569 100644 --- a/DiscImageChef.Core/Sidecar.cs +++ b/DiscImageChef.Core/Sidecar.cs @@ -49,6 +49,56 @@ namespace DiscImageChef.Core { 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) { CICMMetadataType sidecar = new CICMMetadataType(); @@ -65,12 +115,13 @@ namespace DiscImageChef.Core byte[] data; long position = 0; + InitProgress(); while(position < (fi.Length - 1048576)) { data = new byte[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); @@ -80,14 +131,14 @@ namespace DiscImageChef.Core data = new byte[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); // For fast debugging, skip checksum //skipImageChecksum: - DicConsole.WriteLine(); + EndProgress(); fs.Close(); List imgChecksums = imgChkWorker.End(); @@ -286,8 +337,10 @@ namespace DiscImageChef.Core trksLst = new List(); } + InitProgress(); foreach(Track trk in tracks) { + UpdateProgress("Track {0} of {1}", trk.TrackSequence, tracks.Count); Schemas.TrackType xmlTrk = new Schemas.TrackType(); switch(trk.TrackType) { @@ -374,6 +427,7 @@ namespace DiscImageChef.Core ulong sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); ulong doneSectors = 0; + InitProgress2(); while(doneSectors < sectors) { byte[] sector; @@ -381,13 +435,13 @@ namespace DiscImageChef.Core if((sectors - doneSectors) >= sectorsToRead) { 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; } else { 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); } @@ -398,7 +452,7 @@ namespace DiscImageChef.Core xmlTrk.Checksums = trkChecksums.ToArray(); - DicConsole.WriteLine(); + EndProgress2(); if(trk.TrackSubchannelType != TrackSubchannelType.None) { @@ -435,6 +489,7 @@ namespace DiscImageChef.Core sectors = (ulong)(xmlTrk.EndSector - xmlTrk.StartSector + 1); doneSectors = 0; + InitProgress2(); while(doneSectors < sectors) { byte[] sector; @@ -442,13 +497,13 @@ namespace DiscImageChef.Core if((sectors - doneSectors) >= sectorsToRead) { 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; } else { 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); } @@ -459,13 +514,13 @@ namespace DiscImageChef.Core xmlTrk.SubChannel.Checksums = subChecksums.ToArray(); - DicConsole.WriteLine(); + EndProgress2(); } // For fast debugging, skip checksum //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 partitions = new List(); @@ -572,6 +627,7 @@ namespace DiscImageChef.Core trksLst.Add(xmlTrk); } + EndProgress(); if(trksLst != null) sidecar.OpticalDisc[0].Track = trksLst.ToArray(); @@ -734,7 +790,7 @@ namespace DiscImageChef.Core // TODO: Detect it sidecar.BlockMedia[0].PhysicalBlockSize = (int)image.GetSectorSize(); - DicConsole.WriteLine("Checking filesystems..."); + UpdateStatus("Checking filesystems..."); List partitions = new List(); diff --git a/DiscImageChef/ChangeLog b/DiscImageChef/ChangeLog index 618d04bb..0b026fda 100644 --- a/DiscImageChef/ChangeLog +++ b/DiscImageChef/ChangeLog @@ -1,3 +1,11 @@ +2017-05-28 Natalia Portillo + + * Progress.cs: + * DiscImageChef.csproj: + * Commands/Benchmark.cs: + * Commands/CreateSidecar.cs: + Refactor: Use delegates to report progress and status. + 2017-05-27 Natalia Portillo * Commands/Benchmark.cs: diff --git a/DiscImageChef/Commands/Benchmark.cs b/DiscImageChef/Commands/Benchmark.cs index 6229f3d7..933fb71f 100644 --- a/DiscImageChef/Commands/Benchmark.cs +++ b/DiscImageChef/Commands/Benchmark.cs @@ -41,6 +41,9 @@ namespace DiscImageChef.Commands public static void doBenchmark(BenchmarkOptions options) { Dictionary checksumTimes = new Dictionary(); + 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); diff --git a/DiscImageChef/Commands/CreateSidecar.cs b/DiscImageChef/Commands/CreateSidecar.cs index 9d030982..b2ade204 100644 --- a/DiscImageChef/Commands/CreateSidecar.cs +++ b/DiscImageChef/Commands/CreateSidecar.cs @@ -93,6 +93,14 @@ namespace DiscImageChef.Commands Core.Statistics.AddMediaFormat(_imageFormat.GetImageFormat()); 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); DicConsole.WriteLine("Writing metadata sidecar"); diff --git a/DiscImageChef/DiscImageChef.csproj b/DiscImageChef/DiscImageChef.csproj index 52192a6d..c6e9654e 100644 --- a/DiscImageChef/DiscImageChef.csproj +++ b/DiscImageChef/DiscImageChef.csproj @@ -67,6 +67,7 @@ + diff --git a/DiscImageChef/Progress.cs b/DiscImageChef/Progress.cs new file mode 100644 index 00000000..f1449cc3 --- /dev/null +++ b/DiscImageChef/Progress.cs @@ -0,0 +1,86 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Progress.cs +// Author(s) : Natalia Portillo +// +// 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 . +// +// ---------------------------------------------------------------------------- +// 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); + } + } +}