public async Task <Result> Convert(CancellationToken token, Stream source, Stream destination, long size, bool skipZeroFilled = false) { var stopwatch = new Stopwatch(); stopwatch.Start(); source.Seek(0, SeekOrigin.Begin); destination.Seek(0, SeekOrigin.Begin); var dataSectorReader = new DataSectorReader(source, bufferSize: bufferSize); var bytesProcessed = 0L; long bytesRead = 0; SectorResult sectorResult; do { if (token.IsCancellationRequested) { return(new Result <Error>(new Error("Cancelled"))); } sectorResult = await dataSectorReader.ReadNext(); bytesRead += sectorResult.BytesRead; if (skipZeroFilled) { foreach (var sector in sectorResult.Sectors.Where(x => x.Start < size)) { destination.Seek(sector.Start, SeekOrigin.Begin); await destination.WriteAsync(sector.Data, 0, sector.Data.Length, token); } } else { var length = sectorResult.End > size ? size - sectorResult.Start : sectorResult.Data.Length; await destination.WriteAsync(sectorResult.Data, 0, System.Convert.ToInt32(length), token); } var sectorBytesProcessed = sectorResult.End >= size ? size - sectorResult.Start : sectorResult.BytesRead; bytesProcessed += sectorBytesProcessed; var bytesRemaining = size - bytesProcessed; var percentComplete = bytesProcessed == 0 ? 0 : Math.Round((double)100 / size * bytesProcessed, 1); var timeElapsed = stopwatch.Elapsed; var timeRemaining = TimeHelper.CalculateTimeRemaining(percentComplete, timeElapsed); var timeTotal = timeElapsed + timeRemaining; OnDataProcessed(percentComplete, bytesProcessed, bytesRemaining, size, timeElapsed, timeRemaining, timeTotal); } while (sectorResult.BytesRead == bufferSize && bytesRead < size && !sectorResult.EndOfSectors); return(new Result()); }
public async Task <Result> Verify(CancellationToken token, Stream source, Stream destination, long size) { var stopwatch = new Stopwatch(); stopwatch.Start(); source.Seek(0, SeekOrigin.Begin); destination.Seek(0, SeekOrigin.Begin); // var srcBuffer = new byte[bufferSize]; // var destBuffer = new byte[bufferSize]; // // var bytesProcessed = 0L; // int srcBytesRead; // int destBytesRead; // do // { // var chunkSize = Convert.ToInt32(bytesProcessed + bufferSize >= size ? size - bytesProcessed : bufferSize); // // srcBytesRead = await source.ReadAsync(srcBuffer, 0, chunkSize); // destBytesRead = await destination.ReadAsync(destBuffer, 0, chunkSize); // // if (srcBytesRead != destBytesRead) // { // return false; // } // // for (var i = 0; i < srcBytesRead; i++) // { // if (srcBuffer[i] != destBuffer[i]) // { // return false; // } // } // // bytesProcessed += chunkSize; // var bytesRemaining = size - bytesProcessed; // var percentComplete = bytesProcessed == 0 ? 0 : (double)100 / size * bytesProcessed; // var timeElapsed = stopwatch.Elapsed; // var timeRemaining = TimeHelper.CalculateTimeRemaining(percentComplete, timeElapsed); // var timeTotal = timeElapsed + timeRemaining; // // OnDataProcessed(percentComplete, bytesProcessed, bytesRemaining, size, timeElapsed, timeRemaining, timeTotal); // } while (srcBytesRead == bufferSize && destBytesRead == srcBytesRead); var srcBuffer = new byte[bufferSize]; var destBuffer = new byte[bufferSize]; int srcBytesRead; long offset = 0; do { if (token.IsCancellationRequested) { return(new Result <Error>(new Error("Cancelled"))); } var verifyBytes = Convert.ToInt32(offset + bufferSize > size ? size - offset : bufferSize); srcBytesRead = await source.ReadAsync(srcBuffer, 0, srcBuffer.Length, token); var destBytesRead = await destination.ReadAsync(destBuffer, 0, srcBuffer.Length, token); if (size < bufferSize) { verifyBytes = (int)size; } if (srcBytesRead != destBytesRead) { verifyBytes = Math.Min(srcBytesRead, destBytesRead); } if (verifyBytes < bufferSize && offset + verifyBytes != size) { return(new Result(new SizeNotEqualError(offset, size))); } for (int i = 0; i < verifyBytes; i++) { if (srcBuffer[i] == destBuffer[i]) { continue; } return(new Result(new ByteNotEqualError(offset + i, srcBuffer[i], destBuffer[i]))); } offset += verifyBytes; var bytesRemaining = size - offset; var percentComplete = offset == 0 ? 0 : Math.Round((double)100 / size * offset, 1); var timeElapsed = stopwatch.Elapsed; var timeRemaining = TimeHelper.CalculateTimeRemaining(percentComplete, timeElapsed); var timeTotal = timeElapsed + timeRemaining; OnDataProcessed(percentComplete, offset, bytesRemaining, size, timeElapsed, timeRemaining, timeTotal); } while (srcBytesRead == bufferSize && offset < size); return(new Result()); }