ReadOnlyMemoryStream
using DotNext.Buffers;
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 SequencePosition position;
private ReadOnlySequence<byte> RemainingSequence => sequence.Slice(position);
public override bool CanSeek => true;
public override long Length => sequence.Length;
public override long Position {
get {
return sequence.GetOffset(position);
}
set {
if ((ulong)value > (ulong)sequence.Length)
throw new ArgumentOutOfRangeException("value");
position = sequence.GetPosition(value);
}
}
internal ReadOnlyMemoryStream(ReadOnlySequence<byte> sequence)
{
this.sequence = sequence;
position = sequence.Start;
}
[AsyncStateMachine(typeof(<CopyToAsync>d__12))]
public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken token)
{
<CopyToAsync>d__12 stateMachine = default(<CopyToAsync>d__12);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.destination = destination;
stateMachine.bufferSize = bufferSize;
stateMachine.token = token;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
public override void CopyTo(Stream destination, int bufferSize)
{
Stream.ValidateCopyToArguments(destination, bufferSize);
ReadOnlySequence<byte>.Enumerator enumerator = RemainingSequence.GetEnumerator();
while (enumerator.MoveNext()) {
destination.Write(enumerator.Current.Span);
}
position = sequence.End;
}
public override void SetLength(long value)
{
ReadOnlySequence<byte> readOnlySequence = sequence.Slice(0, value);
position = readOnlySequence.GetPosition(Math.Min(sequence.GetOffset(position), readOnlySequence.Length));
sequence = readOnlySequence;
}
public override int Read(Span<byte> buffer)
{
ReadOnlySequence<byte> source = RemainingSequence;
ref source.CopyTo(buffer, out int writtenCount);
position = sequence.GetPosition(writtenCount, position);
return writtenCount;
}
public override long Seek(long offset, SeekOrigin origin)
{
long num;
switch (origin) {
case SeekOrigin.Begin:
num = offset;
break;
case SeekOrigin.Current:
num = sequence.GetOffset(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");
position = sequence.GetPosition(num2);
return num2;
}
public override string ToString()
{
return sequence.ToString();
}
}
}