Helpers: Collapse extensions into one single file
This commit is contained in:
@ -1,5 +1,8 @@
|
|||||||
using System.IO;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers {
|
namespace Elwig.Helpers {
|
||||||
@ -59,5 +62,38 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long>? progress = null, CancellationToken cancellationToken = default) {
|
||||||
|
ArgumentNullException.ThrowIfNull(source);
|
||||||
|
if (!source.CanRead) throw new ArgumentException("Has to be readable", nameof(source));
|
||||||
|
ArgumentNullException.ThrowIfNull(destination);
|
||||||
|
if (!destination.CanWrite) throw new ArgumentException("Has to be writable", nameof(destination));
|
||||||
|
ArgumentOutOfRangeException.ThrowIfNegative(bufferSize);
|
||||||
|
|
||||||
|
var buffer = new byte[bufferSize];
|
||||||
|
long totalBytesRead = 0;
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0) {
|
||||||
|
await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
|
||||||
|
totalBytesRead += bytesRead;
|
||||||
|
progress?.Report(totalBytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task DownloadAsync(this HttpClient client, string requestUri, Stream destination, IProgress<double>? progress = null, CancellationToken cancellationToken = default) {
|
||||||
|
using var response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
var contentLength = response.Content.Headers.ContentLength;
|
||||||
|
|
||||||
|
using var download = await response.Content.ReadAsStreamAsync(cancellationToken);
|
||||||
|
if (progress == null || !contentLength.HasValue) {
|
||||||
|
await download.CopyToAsync(destination, cancellationToken);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var relativeProgress = new Progress<long>(totalBytes => progress.Report((double)totalBytes / contentLength.Value));
|
||||||
|
await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken);
|
||||||
|
progress.Report(100.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers {
|
|
||||||
public static class HttpClientExtensions {
|
|
||||||
public static async Task DownloadAsync(this HttpClient client, string requestUri, Stream destination, IProgress<double>? progress = null, CancellationToken cancellationToken = default) {
|
|
||||||
using var response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
|
||||||
var contentLength = response.Content.Headers.ContentLength;
|
|
||||||
|
|
||||||
using var download = await response.Content.ReadAsStreamAsync(cancellationToken);
|
|
||||||
if (progress == null || !contentLength.HasValue) {
|
|
||||||
await download.CopyToAsync(destination, cancellationToken);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var relativeProgress = new Progress<long>(totalBytes => progress.Report((double)totalBytes / contentLength.Value));
|
|
||||||
await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken);
|
|
||||||
progress.Report(100.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers {
|
|
||||||
public static class StreamExtensions {
|
|
||||||
public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long>? progress = null, CancellationToken cancellationToken = default) {
|
|
||||||
ArgumentNullException.ThrowIfNull(source);
|
|
||||||
if (!source.CanRead) throw new ArgumentException("Has to be readable", nameof(source));
|
|
||||||
ArgumentNullException.ThrowIfNull(destination);
|
|
||||||
if (!destination.CanWrite) throw new ArgumentException("Has to be writable", nameof(destination));
|
|
||||||
ArgumentOutOfRangeException.ThrowIfNegative(bufferSize);
|
|
||||||
|
|
||||||
var buffer = new byte[bufferSize];
|
|
||||||
long totalBytesRead = 0;
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0) {
|
|
||||||
await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
|
|
||||||
totalBytesRead += bytesRead;
|
|
||||||
progress?.Report(totalBytesRead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user