Skip to content

Instantly share code, notes, and snippets.

@rquackenbush
Created October 27, 2017 16:14
Show Gist options
  • Save rquackenbush/467be89de44e07933167b10815633c28 to your computer and use it in GitHub Desktop.
Save rquackenbush/467be89de44e07933167b10815633c28 to your computer and use it in GitHub Desktop.
SizeLimitingStream
using System;
using System.IO;
namespace CaptiveAire.Scada.Module.Base
{
/// <summary>
/// A stream that limits the length of the source stream. This is a fast forward only stream. No seeking allowed.
/// </summary>
public class SizeLimitingStream : Stream
{
private readonly Stream _source;
private readonly long _length;
private long _position;
public SizeLimitingStream(Stream source, long length)
{
_source = source;
_length = length;
}
public override void Flush()
{
_source.Flush();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
if (_position >= _length)
return 0;
int toRead = count;
if (toRead > (_length - _position))
{
toRead = (int)(_length - _position);
}
int actualRead = _source.Read(buffer, offset, toRead);
_position += actualRead;
return actualRead;
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override long Length
{
get { return _length; }
}
public override long Position
{
get { return _position; }
set { throw new NotSupportedException(); }
}
}
}
using System;
using System.IO;
using System.Linq;
using Xunit;
namespace CaptiveAire.Scada.Module.Base.Tests
{
public class SizeLimitingStreamTests
{
[Theory]
[InlineData(100, 50, 4096)]
[InlineData(100, 42, 2)]
[InlineData(100, 42, 1)]
[InlineData(100, 2, 7)]
[InlineData(5000, 200, 4096)]
public void Test(int sourceStreamSize, int limitSize, int readBufferSize)
{
var random = new Random();
var sourceData = new byte[sourceStreamSize];
random.NextBytes(sourceData);
using (var sourceStream = new MemoryStream(sourceData))
using (var sizeLimitingStream = new SizeLimitingStream(sourceStream, limitSize))
{
using (var targetStream = new MemoryStream())
{
//Copy the stream
sizeLimitingStream.CopyTo(targetStream, readBufferSize);
//Compare the data
Assert.Equal(
sourceData.Take(limitSize),
targetStream.ToArray());
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment