Helpers: Collapse extensions into one single file

This commit is contained in:
2024-04-15 13:04:49 +02:00
parent 5f8688f0cd
commit f53371ab19
3 changed files with 37 additions and 50 deletions

View File

@ -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);
}
} }
} }

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}
}