using System;
using System.IO;
using B2.Framework.IO;
namespace B2.Service.Common.UpdateFile
{
///
/// Von diesem Stream kann nur gelesen werden.
/// Start und Ende wird mittels Event mitgeteilt.
///
public class DownloadStream : MemoryStream
{
private bool _started;
private readonly bool _canWrite;
private readonly T _userState;
public event EventHandler> DownloadCompleted;
public event EventHandler> DownloadStarted;
public DownloadStream(Stream stream, T userState)
{
_userState = userState;
_canWrite = true;
StreamHelper.CopyStream(stream, this);
_canWrite = false;
ResetDownload();
}
public DownloadStream(Stream stream)
: this(stream, default(T))
{
}
private void InvokeDownloadStarted(DownloadStreamEventArgs e)
{
var handler = DownloadStarted;
if (handler != null)
handler(this, e);
}
private void InvokeDownloadCompleted(DownloadStreamEventArgs e)
{
var handler = DownloadCompleted;
if (handler != null)
handler(this, e);
}
public override int Read(byte[] buffer, int offset, int count)
{
if (!_started)
{
_started = true;
InvokeDownloadStarted(new DownloadStreamEventArgs(_userState));
}
int read = base.Read(buffer, offset, count);
if (read < 1)
{
InvokeDownloadCompleted(new DownloadStreamEventArgs(_userState));
}
return read;
}
public override int ReadByte()
{
if (!_started)
{
_started = true;
InvokeDownloadStarted(new DownloadStreamEventArgs(_userState));
}
int read = base.ReadByte();
if (read < 1)
{
InvokeDownloadCompleted(new DownloadStreamEventArgs(_userState));
}
return read;
}
public override long Seek(long offset, SeekOrigin loc)
{
long position = Position;
long newPosition = base.Seek(offset, loc);
if (newPosition != 0)
{
Position = position;
throw new InvalidOperationException("Seeking within stream is not supported. Only set to 0 is supported.");
}
_started = false;
return Position;
}
public override bool CanWrite
{
get { return _canWrite; }
}
public override long Position
{
get
{
return base.Position;
}
set
{
if (value == 0)
_started = false;
else
throw new InvalidOperationException("Seeking within stream is not supported. Only set to 0 is supported.");
base.Position = value;
}
}
public void ResetDownload()
{
Seek(0, SeekOrigin.Begin);
_started = false;
}
}
public class DownloadStreamEventArgs : EventArgs
{
public T UserState { get; set; }
public DownloadStreamEventArgs(T userState)
{
UserState = userState;
}
}
}