Streams
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace Org.BouncyCastle.Utilities.IO
{
public static class Streams
{
private static readonly int MaxStackAlloc = Platform.Is64BitProcess ? 4096 : 1024;
public static int DefaultBufferSize => MaxStackAlloc;
public static void CopyTo(Stream source, Stream destination)
{
CopyTo(source, destination, DefaultBufferSize);
}
public unsafe static void CopyTo(Stream source, Stream destination, int bufferSize)
{
Span<byte> span = (bufferSize > MaxStackAlloc) ? ((Span<byte>)new byte[bufferSize]) : new Span<byte>(stackalloc byte[(int)(uint)bufferSize], bufferSize);
Span<byte> buffer = span;
int length;
while ((length = source.Read(buffer)) != 0) {
destination.Write(buffer.Slice(0, length));
}
}
public static Task CopyToAsync(Stream source, Stream destination)
{
return CopyToAsync(source, destination, DefaultBufferSize);
}
public static Task CopyToAsync(Stream source, Stream destination, int bufferSize)
{
return CopyToAsync(source, destination, bufferSize, CancellationToken.None);
}
public static Task CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken)
{
return CopyToAsync(source, destination, DefaultBufferSize, cancellationToken);
}
[AsyncStateMachine(typeof(<CopyToAsync>d__8))]
public static Task CopyToAsync(Stream source, Stream destination, int bufferSize, CancellationToken cancellationToken)
{
<CopyToAsync>d__8 stateMachine = default(<CopyToAsync>d__8);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.source = source;
stateMachine.destination = destination;
stateMachine.bufferSize = bufferSize;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public static void Drain(Stream inStr)
{
CopyTo(inStr, Stream.Null, DefaultBufferSize);
}
public static void PipeAll(Stream inStr, Stream outStr)
{
PipeAll(inStr, outStr, DefaultBufferSize);
}
public static void PipeAll(Stream inStr, Stream outStr, int bufferSize)
{
CopyTo(inStr, outStr, bufferSize);
}
public static long PipeAllLimited(Stream inStr, long limit, Stream outStr)
{
return PipeAllLimited(inStr, limit, outStr, DefaultBufferSize);
}
public static long PipeAllLimited(Stream inStr, long limit, Stream outStr, int bufferSize)
{
LimitedInputStream limitedInputStream = new LimitedInputStream(inStr, limit);
CopyTo(limitedInputStream, outStr, bufferSize);
return limit - limitedInputStream.CurrentLimit;
}
public static byte[] ReadAll(Stream inStr)
{
MemoryStream memoryStream = new MemoryStream();
PipeAll(inStr, memoryStream);
return memoryStream.ToArray();
}
public static byte[] ReadAll(MemoryStream inStr)
{
return inStr.ToArray();
}
public static byte[] ReadAllLimited(Stream inStr, int limit)
{
MemoryStream memoryStream = new MemoryStream();
PipeAllLimited(inStr, limit, memoryStream);
return memoryStream.ToArray();
}
public static ValueTask<int> ReadAsync(Stream source, Memory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
{
if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> segment))
return new ValueTask<int>(source.ReadAsync(segment.Array, segment.Offset, segment.Count, cancellationToken));
byte[] array = new byte[buffer.Length];
return ReadAsyncCompletion(source.ReadAsync(array, 0, buffer.Length, cancellationToken), array, buffer);
}
[AsyncStateMachine(typeof(<ReadAsyncCompletion>d__18))]
internal static ValueTask<int> ReadAsyncCompletion(Task<int> readTask, byte[] localBuffer, Memory<byte> localDestination)
{
<ReadAsyncCompletion>d__18 stateMachine = default(<ReadAsyncCompletion>d__18);
stateMachine.<>t__builder = AsyncValueTaskMethodBuilder<int>.Create();
stateMachine.readTask = readTask;
stateMachine.localBuffer = localBuffer;
stateMachine.localDestination = localDestination;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public static int ReadFully(Stream inStr, byte[] buf)
{
return ReadFully(inStr, buf, 0, buf.Length);
}
public static int ReadFully(Stream inStr, byte[] buf, int off, int len)
{
int i;
int num;
for (i = 0; i < len; i += num) {
num = inStr.Read(buf, off + i, len - i);
if (num < 1)
break;
}
return i;
}
public static int ReadFully(Stream inStr, Span<byte> buffer)
{
int i;
int num2;
for (i = 0; i < buffer.Length; i += num2) {
int num = i;
num2 = inStr.Read(buffer.Slice(num, buffer.Length - num));
if (num2 < 1)
break;
}
return i;
}
public static void ValidateBufferArguments(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
int num = buffer.Length - offset;
if ((offset | num) < 0)
throw new ArgumentOutOfRangeException("offset");
int num2 = num - count;
if ((count | num2) < 0)
throw new ArgumentOutOfRangeException("count");
}
[AsyncStateMachine(typeof(<WriteAsyncCompletion>d__23))]
internal static Task WriteAsyncCompletion(Task writeTask, byte[] localBuffer)
{
<WriteAsyncCompletion>d__23 stateMachine = default(<WriteAsyncCompletion>d__23);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.writeTask = writeTask;
stateMachine.localBuffer = localBuffer;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
internal static Task WriteAsyncDirect(Stream destination, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled(cancellationToken);
destination.Write(buffer, offset, count);
return Task.CompletedTask;
}
public static ValueTask WriteAsync(Stream destination, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
{
if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> segment))
return new ValueTask(destination.WriteAsync(segment.Array, segment.Offset, segment.Count, cancellationToken));
byte[] array = buffer.ToArray();
return new ValueTask(WriteAsyncCompletion(destination.WriteAsync(array, 0, buffer.Length, cancellationToken), array));
}
[AsyncStateMachine(typeof(<WriteAsyncCompletion>d__26))]
internal static ValueTask WriteAsyncCompletion(ValueTask writeTask, byte[] localBuffer)
{
<WriteAsyncCompletion>d__26 stateMachine = default(<WriteAsyncCompletion>d__26);
stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create();
stateMachine.writeTask = writeTask;
stateMachine.localBuffer = localBuffer;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
internal static ValueTask WriteAsyncDirect(Stream destination, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
{
if (cancellationToken.IsCancellationRequested)
return ValueTask.FromCanceled(cancellationToken);
destination.Write(buffer.Span);
return ValueTask.CompletedTask;
}
public static int WriteBufTo(MemoryStream buf, byte[] output, int offset)
{
if (buf.TryGetBuffer(out ArraySegment<byte> buffer)) {
buffer.CopyTo(output, offset);
return buffer.Count;
}
int num = Convert.ToInt32(buf.Length);
buf.WriteTo(new MemoryStream(output, offset, num));
return num;
}
}
}