예제 #1
0
        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());
        }
예제 #2
0
        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());
        }