// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Buffers;
using System.IO;
namespace EpicGames.Core
{
///
/// Stream which reads from a
///
public class ReadOnlySequenceStream : Stream
{
///
/// The buffer to read from
///
readonly ReadOnlySequence _source;
///
/// Remaining sequence to read
///
ReadOnlySequence _remaining;
///
/// Constructor
///
/// The memory to read from
public ReadOnlySequenceStream(ReadOnlySequence sequence)
{
_source = sequence;
_remaining = _source;
}
///
public override bool CanRead => true;
///
public override bool CanSeek => true;
///
public override bool CanWrite => false;
///
public override long Length => _source.Length;
///
public override long Position
{
get => _source.Length - _remaining.Length;
set => _remaining = _source.Slice(value);
}
///
public override void Flush()
{
}
///
public override int Read(Span buffer)
{
ReadOnlySpan firstSpan = _remaining.FirstSpan;
int copyLength = Math.Min(firstSpan.Length, buffer.Length);
firstSpan.Slice(0, copyLength).CopyTo(buffer);
_remaining = _remaining.Slice(copyLength);
return copyLength;
}
///
public override int Read(byte[] buffer, int offset, int count) => Read(buffer.AsSpan(offset, count));
///
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
Position = offset;
break;
case SeekOrigin.Current:
Position += offset;
break;
case SeekOrigin.End:
Position = Length + offset;
break;
default:
throw new ArgumentException(null, nameof(origin));
}
return Position;
}
///
public override void SetLength(long value) => throw new InvalidOperationException();
///
public override void Write(byte[] buffer, int offset, int count) => throw new InvalidOperationException();
}
}