diff --git a/PatchSync.SDK/Client/IDownloadProgress.cs b/PatchSync.SDK/Client/IDownloadProgress.cs new file mode 100644 index 0000000..47d94ed --- /dev/null +++ b/PatchSync.SDK/Client/IDownloadProgress.cs @@ -0,0 +1,8 @@ +namespace PatchSync.SDK.Client; + +public interface IDownloadProgress +{ + public long TotalSize { get; } + public long TotalDownloaded { get; } + public double Speed { get; } +} diff --git a/PatchSync.SDK/Client/PatchSyncClient.cs b/PatchSync.SDK/Client/PatchSyncClient.cs index 8f25f8c..5549b28 100644 --- a/PatchSync.SDK/Client/PatchSyncClient.cs +++ b/PatchSync.SDK/Client/PatchSyncClient.cs @@ -49,7 +49,11 @@ public async Task GetSignatureFile(int originalFileSize, string r return signatureFile; } - public async IAsyncEnumerable DownloadDeltaPatchFileAsync(string relativeUri, IEnumerable<(int Start ,int End)> ranges, IProgress<(double Progress, double Speed)> progress = null) + public async IAsyncEnumerable DownloadDeltaPatchFileAsync( + string relativeUri, + IEnumerable<(long Start, long End)> ranges, + IProgress progress = null + ) { long totalSize = 0; using var httpClient = HttpHandler.CreateHttpClient(); @@ -65,7 +69,7 @@ public async IAsyncEnumerable DownloadDeltaPatchFileAsync(string relativ httpClient.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(); foreach (var range in ranges) { - totalSize += range.End - range.Start + 1;; + totalSize += range.End - range.Start + 1; httpClient.DefaultRequestHeaders.Range.Ranges.Add( new System.Net.Http.Headers.RangeItemHeaderValue(range.Start, range.End) ); @@ -76,7 +80,10 @@ public async IAsyncEnumerable DownloadDeltaPatchFileAsync(string relativ // Throw if not successful response.EnsureSuccessStatusCode(); - var progressInfo = new ProgressInfo(); + var progressInfo = new ProgressInfo + { + TotalSize = totalSize + }; if (response.Content.Headers.ContentType?.MediaType.Equals( "multipart/byteranges", StringComparison.OrdinalIgnoreCase @@ -88,7 +95,7 @@ public async IAsyncEnumerable DownloadDeltaPatchFileAsync(string relativ { foreach (var content in multipart) { - await CopyToStreamAsync(content, memoryStream, progressInfo, totalSize, progress); + await CopyToStreamAsync(content, memoryStream, progressInfo, progress); memoryStream.Seek(0, SeekOrigin.Begin); // Reset memory stream position for reading yield return memoryStream; memoryStream.SetLength(0); // Clear memory stream for next part @@ -101,7 +108,7 @@ public async IAsyncEnumerable DownloadDeltaPatchFileAsync(string relativ } } - private static async Task CopyToStreamAsync(HttpContent content, Stream destination, ProgressInfo progressInfo, long totalSize, IProgress<(double Progress, double Speed)> progress) + private static async Task CopyToStreamAsync(HttpContent content, Stream destination, ProgressInfo progressInfo, IProgress progress) { #if NET6_0_OR_GREATER byte[] buffer = GC.AllocateUninitializedArray(81920); @@ -123,7 +130,7 @@ private static async Task CopyToStreamAsync(HttpContent content, Stream destinat speed = progressInfo.TotalRead / progressInfo.Stopwatch.Elapsed.TotalSeconds; } - progress?.Report(((double)progressInfo.TotalRead / totalSize, speed)); + progress?.Report(new DownloadProgress(progressInfo.TotalSize, progressInfo.TotalRead, speed)); } } @@ -132,7 +139,15 @@ public void ValidateFiles(string baseFolder, Func callback) => private class ProgressInfo { + public long TotalSize { get; set; } public long TotalRead { get; set; } public Stopwatch Stopwatch { get; } = new(); } + + private class DownloadProgress(long totalSize, long totalDownloaded, double speed) : IDownloadProgress + { + public long TotalSize { get; } = totalSize; + public long TotalDownloaded { get; } = totalDownloaded; + public double Speed { get; } = speed; + } }