// 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(); } }