Skip to content

Instantly share code, notes, and snippets.

@rdavisau
Created October 26, 2015 12:18
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save rdavisau/6e00bfe4a769ddc9338c to your computer and use it in GitHub Desktop.
Save rdavisau/6e00bfe4a769ddc9338c to your computer and use it in GitHub Desktop.
EnumerableStream.cs
/// <summary>
/// Provides a convenience method for constructing an EnumerableStream<T>.
/// </summary>
public static class EnumerableStream
{
public static EnumerableStream<T> Create<T>(IEnumerable<T> source, Func<T, List<byte>> serializer)
{
return new EnumerableStream<T>(source, serializer);
}
}
public class EnumerableStream<T> : Stream
{
private readonly IEnumerator<T> _source;
private readonly Func<T, IEnumerable<byte>> _serializer;
private readonly Queue<byte> _buf = new Queue<byte>();
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length => -1;
/// <summary>
/// Creates a new instance of <code>EnumerableStream</code>
/// </summary>
/// <param name="source">The source enumerable for the EnumerableStream</param>
/// <param name="serializer">A function that converts an instance of <code>T</code> to IEnumerable<byte></param>
public EnumerableStream(IEnumerable<T> source, Func<T, IEnumerable<byte>> serializer)
{
_source = source.GetEnumerator();
_serializer = serializer;
}
private bool SerializeNext()
{
if (!_source.MoveNext())
return false;
foreach (var b in _serializer(_source.Current))
_buf.Enqueue(b);
return true;
}
private byte? NextByte()
{
if (_buf.Any() || SerializeNext())
{
return _buf.Dequeue();
}
return null;
}
public override int Read(byte[] buffer, int offset, int count)
{
var read = 0;
while (read < count)
{
var mayb = NextByte();
if (mayb == null) break;
buffer[offset + read] = (byte) mayb;
read++;
}
return read;
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override void Flush()
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment