using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
namespace MarcelJKloubert.IO
{
/// <summary>
/// Ein Stream, der durchlaufen werden kann
/// </summary>
public sealed class EnumerableStream : Stream, IEnumerable<byte[]>
{
#region CLASS: StreamEnumerator
private class StreamEnumerator : IEnumerator<byte[]>
{
#region Felder
private byte[] _current = null;
private StreamEnumerable _parent = null;
#endregion
#region Konstruktoren
public StreamEnumerator(StreamEnumerable parent)
{
if (null == parent)
{
throw new ArgumentNullException("parent");
}
this._parent = parent;
}
#endregion
#region Eigenschaften
/// <summary>
///
/// </summary>
/// <see cref="System.Collections.Generic.IEnumerator<T>.Current"/>
public byte[] Current
{
get { return this._current; }
}
/// <summary>
///
/// </summary>
/// <see cref="System.Collections.IEnumerator.Current"/>
object IEnumerator.Current
{
get { return this.Current; }
}
/// <summary>
/// Gibt die Vaterinstanz zurück
/// </summary>
public StreamEnumerable Parent
{
get { return this._parent; }
}
#endregion
#region Methoden
/// <summary>
///
/// </summary>
/// <see cref="System.IDisposable.Dispose"/>
public void Dispose()
{ }
/// <summary>
///
/// </summary>
/// <see cref="System.Collections.Generic.IEnumerator<T>.MoveNext"/>
public bool MoveNext()
{
byte[] buffer = new byte[this.Parent.BufferSize];
int iBytesRead = this.Parent.Read(buffer, 0, buffer.Length);
if (iBytesRead > 0)
{
byte[] data = new byte[iBytesRead];
Array.Copy(buffer, data, iBytesRead);
this._current = data;
}
return iBytesRead > 0;
}
/// <summary>
///
/// </summary>
/// <see cref="System.Collections.Generic.IEnumerator<T>.Reset"/>
public void Reset()
{
if (this.Parent.CanSeek)
{
this.Parent.Position = 0;
}
this._current = null;
}
#endregion
}
#endregion
#region Felder
private Stream _baseStream = null;
private int _bufferSize = 0;
private bool _closeOnDispose = false;
#endregion
#region Konstruktoren
/// <summary>
///
/// </summary>
/// <param name="baseStream">Basisstream</param>
public StreamEnumerable(Stream baseStream) : this(baseStream, 4096)
{ }
/// <summary>
///
/// </summary>
/// <param name="baseStream">Basisstream</param>
public StreamEnumerable(Stream baseStream, int bufferSize) : this(baseStream, bufferSize, false)
{ }
/// <summary>
///
/// </summary>
/// <param name="baseStream">Basisstream</param>
/// <param name="closeAfterDispose">Speicher von Basisstream ebenfalls freigeben bei einem Dispose() (true) oder nicht (false)</param>
public StreamEnumerable(Stream baseStream, bool closeOnDispose) : this(baseStream, 4096, closeOnDispose)
{ }
/// <summary>
///
/// </summary>
/// <param name="baseStream">Basisstream</param>
/// <param name="bufferSize">Puffergrösse</param>
/// <param name="closeAfterDispose">Speicher von Basisstream ebenfalls freigeben bei einem Dispose() (true) oder nicht (false)</param>
public StreamEnumerable(Stream baseStream, int bufferSize, bool closeOnDispose)
{
if (null == baseStream)
{
throw new ArgumentNullException("baseStream");
}
if (bufferSize < 1)
{
throw new ArgumentOutOfRangeException("bufferSize");
}
this._baseStream = baseStream;
this._bufferSize = bufferSize;
this._closeOnDispose = closeOnDispose;
}
#endregion
#region Eigenschaften
/// <summary>
/// Gibt den Basisstream zurück
/// </summary>
public Stream BaseStream
{
get { return this._baseStream; }
}
/// <summary>
/// Gibt die Puffergrösse zurück
/// </summary>
public int BufferSize
{
get { return this._bufferSize; }
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.CanRead"/>
public override bool CanRead
{
get { return this.BaseStream.CanRead; }
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.CanSeek"/>
public override bool CanSeek
{
get { return this.BaseStream.CanSeek; }
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.CanWrite"/>
public override bool CanWrite
{
get { return this.BaseStream.CanWrite; }
}
/// <summary>
/// Gibt zurück, ob der Speicher des Basisstream ebenfalls bei einem Dispose() freigegeben wird (true) oder nicht (false)
/// </summary>
public bool CloseOnDispose
{
get { return this._closeOnDispose; }
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.Length"/>
public override long Length
{
get { return this.BaseStream.Length; }
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.Position"/>
public override long Position
{
get { return this.BaseStream.Position; }
set { this.BaseStream.Position = value; }
}
#endregion
#region Methoden
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.Dispose"/>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (this.CloseOnDispose)
{
this.BaseStream.Dispose();
}
}
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.Flush"/>
public override void Flush()
{
this.BaseStream.Flush();
}
/// <summary>
///
/// </summary>
/// <see cref="System.Collections.Generic.IEnumerable<T>.GetEnumerator"/>
public IEnumerator<byte[]> GetEnumerator()
{
return new StreamEnumerator(this);
}
/// <summary>
///
/// </summary>
/// <see cref="System.Collections.IEnumerable.GetEnumerator"/>
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.Read"/>
public override int Read(byte[] buffer, int offset, int count)
{
return this.BaseStream.Read(buffer, offset, count);
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.Seek"/>
public override long Seek(long offset, SeekOrigin origin)
{
return this.BaseStream.Seek(offset, origin);
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.SetLength"/>
public override void SetLength(long value)
{
this.BaseStream.SetLength(value);
}
/// <summary>
///
/// </summary>
/// <see cref="System.IO.Stream.Write"/>
public override void Write(byte[] buffer, int offset, int count)
{
this.BaseStream.Write(buffer, offset, count);
}
#endregion
}
}