2021-09-27 12:42:46 +00:00
|
|
|
using System;
|
2022-06-29 13:18:04 +00:00
|
|
|
using System.Buffers;
|
2021-09-27 12:42:46 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
2021-12-27 05:13:28 +00:00
|
|
|
using System.Text.Json;
|
2021-09-27 12:42:46 +00:00
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
2021-12-27 05:13:28 +00:00
|
|
|
using Wabbajack.DTOs.JsonConverters;
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
namespace Wabbajack.Common;
|
|
|
|
|
|
|
|
public static class StreamExtensions
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
public static async Task CopyToLimitAsync(this Stream frm, Stream tw, int limit, CancellationToken token)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2022-06-29 13:18:04 +00:00
|
|
|
using var buff = MemoryPool<byte>.Shared.Rent(1024 * 128);
|
|
|
|
var buffMemory = buff.Memory;
|
2021-10-23 16:51:17 +00:00
|
|
|
while (limit > 0 && !token.IsCancellationRequested)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2022-06-29 13:18:04 +00:00
|
|
|
var toRead = Math.Min(buffMemory.Length, limit);
|
|
|
|
var read = await frm.ReadAsync(buffMemory[..toRead], token);
|
2021-10-23 16:51:17 +00:00
|
|
|
if (read == 0)
|
|
|
|
throw new Exception("End of stream before end of limit");
|
2022-06-29 13:18:04 +00:00
|
|
|
await tw.WriteAsync(buffMemory[..read], token);
|
2021-10-23 16:51:17 +00:00
|
|
|
limit -= read;
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
await tw.FlushAsync(token);
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static async Task CopyToWithStatusAsync(this Stream input, long maxSize, Stream output,
|
|
|
|
CancellationToken token)
|
|
|
|
{
|
|
|
|
var buffer = new byte[1024 * 1024];
|
|
|
|
if (maxSize == 0) maxSize = 1;
|
|
|
|
long totalRead = 0;
|
|
|
|
var remain = maxSize;
|
|
|
|
while (true)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
var toRead = Math.Min(buffer.Length, remain);
|
|
|
|
var read = await input.ReadAsync(buffer.AsMemory(0, (int) toRead), token);
|
|
|
|
remain -= read;
|
|
|
|
if (read == 0) break;
|
|
|
|
totalRead += read;
|
|
|
|
await output.WriteAsync(buffer.AsMemory(0, read), token);
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
await output.FlushAsync(token);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async Task<byte[]> ReadAllAsync(this Stream stream)
|
|
|
|
{
|
|
|
|
var ms = new MemoryStream();
|
|
|
|
await stream.CopyToAsync(ms);
|
|
|
|
return ms.ToArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static string ReadAllText(this Stream stream)
|
|
|
|
{
|
|
|
|
using var sr = new StreamReader(stream);
|
|
|
|
return sr.ReadToEnd();
|
|
|
|
}
|
|
|
|
|
2021-12-27 05:13:28 +00:00
|
|
|
public static async Task<T> FromJson<T>(this Stream stream, DTOSerializer? dtos = null)
|
|
|
|
{
|
|
|
|
return (await JsonSerializer.DeserializeAsync<T>(stream, dtos?.Options))!;
|
|
|
|
}
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static async IAsyncEnumerable<string> ReadLinesAsync(this Stream stream)
|
|
|
|
{
|
|
|
|
using var sr = new StreamReader(stream);
|
|
|
|
while (true)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
var data = await sr.ReadLineAsync();
|
|
|
|
if (data == null) break;
|
|
|
|
yield return data!;
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|