WindowStream
Exposes a predetermined slice of a larger stream using the same Stream interface.
There should not be access to the base stream while this facade is in use.
using Azure.Core.Pipeline;
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace Azure.Storage.Shared
{
internal abstract class WindowStream : Stream
{
private class UnseekableWindowStream : WindowStream
{
private long ;
private long { get; }
public override bool => false;
public override long {
get {
throw new NotSupportedException();
}
}
public override long {
get {
throw new NotSupportedException();
}
set {
throw new NotSupportedException();
}
}
public UnseekableWindowStream(Stream stream, long maxWindowLength)
: base(stream)
{
MaxLength = maxWindowLength;
}
public override long (long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void (long value)
{
throw new NotSupportedException();
}
protected override int (int count)
{
return (int)Math.Min(count, MaxLength - _position);
}
protected override void (int resultRead)
{
_position += resultRead;
}
}
private class SeekableWindowStream : WindowStream
{
private readonly long ;
public override bool => true;
public override long { get; }
public override long {
get {
return base.InnerStream.Position - _baseStreamStartingPosition;
}
set {
base.InnerStream.Position = _baseStreamStartingPosition + value;
}
}
public SeekableWindowStream(Stream stream, long maxWindowLength)
: base(stream)
{
Length = Math.Min(stream.Length - stream.Position, maxWindowLength);
_baseStreamStartingPosition = stream.Position;
}
public override long (long offset, SeekOrigin origin)
{
switch (origin) {
case SeekOrigin.Begin:
base.InnerStream.Seek(_baseStreamStartingPosition + offset, SeekOrigin.Begin);
break;
case SeekOrigin.Current:
base.InnerStream.Seek(base.InnerStream.Position + offset, SeekOrigin.Current);
break;
case SeekOrigin.End:
base.InnerStream.Seek(_baseStreamStartingPosition + Length - base.InnerStream.Length + offset, SeekOrigin.End);
break;
}
return Position;
}
public override void (long value)
{
throw new NotSupportedException();
}
protected override int (int count)
{
return (int)Math.Min(count, Length - Position);
}
protected override void (int resultRead)
{
}
}
private Stream { get; }
public override bool => true;
public override bool => false;
private WindowStream(Stream stream)
{
InnerStream = stream;
}
public static Stream (Stream stream, long maxWindowLength)
{
if (stream.CanSeek)
return new SeekableWindowStream(stream, maxWindowLength);
return new UnseekableWindowStream(stream, maxWindowLength);
}
public override void ()
{
throw new NotSupportedException();
}
public override void (byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override void (byte value)
{
throw new NotSupportedException();
}
public override int ()
{
if (AdjustCount(1) <= 0)
return -1;
int num = InnerStream.ReadByte();
if (num != -1)
ReportInnerStreamRead(1);
return num;
}
public override int (byte[] buffer, int offset, int count)
{
return ReadInternal(buffer, offset, count, false, default(CancellationToken)).EnsureCompleted();
}
[AsyncStateMachine(typeof(<ReadAsync>d__14))]
public override Task<int> (byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
<ReadAsync>d__14 stateMachine = default(<ReadAsync>d__14);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
stateMachine.<>4__this = this;
stateMachine.buffer = buffer;
stateMachine.offset = offset;
stateMachine.count = count;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<ReadInternal>d__15))]
private Task<int> (byte[] buffer, int offset, int count, bool async, CancellationToken cancellationToken)
{
<ReadInternal>d__15 stateMachine = default(<ReadInternal>d__15);
stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
stateMachine.<>4__this = this;
stateMachine.buffer = buffer;
stateMachine.offset = offset;
stateMachine.count = count;
stateMachine.async = async;
stateMachine.cancellationToken = cancellationToken;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
protected abstract int (int );
protected abstract void (int );
}
}