ReadOnlyMemoryStream
using System;
using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace DotNext.IO
{
internal sealed class ReadOnlyMemoryStream : ReadOnlyStream
{
private ReadOnlySequence<byte> sequence;
private long position;
public override bool CanSeek => true;
public override long Length => sequence.Length;
public override long Position {
get {
return position;
}
set {
if (value < 0 || value > sequence.Length)
throw new ArgumentOutOfRangeException("value");
position = value;
}
}
internal ReadOnlyMemoryStream(ReadOnlySequence<byte> sequence)
{
this.sequence = sequence;
position = 0;
}
[System.Runtime.CompilerServices.NullableContext(1)]
[AsyncStateMachine(typeof(<CopyToAsync>d__10))]
public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken token)
{
<CopyToAsync>d__10 stateMachine = default(<CopyToAsync>d__10);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.destination = destination;
stateMachine.token = token;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public override void CopyTo(Stream destination, int bufferSize)
{
SequencePosition sequencePosition = sequence.GetPosition(position);
ReadOnlyMemory<byte> memory;
while (sequence.TryGet(ref sequencePosition, out memory, true) && !memory.IsEmpty) {
destination.Write(memory.Span);
position += memory.Length;
}
}
public override void SetLength(long value)
{
sequence = sequence.Slice(0, value);
position = Math.Min(position, sequence.Length);
}
public override int Read(Span<byte> buffer)
{
long num = sequence.Length - position;
if (num <= 0 || buffer.Length == 0)
return 0;
int num2 = (int)Math.Min(buffer.Length, num);
ReadOnlySequence<byte> source = sequence.Slice(position, num2);
ref source.CopyTo(buffer);
position += num2;
return num2;
}
public override long Seek(long offset, SeekOrigin origin)
{
long num;
switch (origin) {
case SeekOrigin.Begin:
num = offset;
break;
case SeekOrigin.Current:
num = position + offset;
break;
case SeekOrigin.End:
num = sequence.Length + offset;
break;
default:
throw new ArgumentOutOfRangeException("origin");
}
long num2 = num;
if (num2 < 0)
throw new IOException();
if (num2 > sequence.Length)
throw new ArgumentOutOfRangeException("offset");
return position = num2;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public override string ToString()
{
return sequence.ToString();
}
}
}