2014-10-12 04:19:01 +00:00
using System ;
2013-11-22 09:33:56 +00:00
using System.IO ;
namespace BizHawk.Common
{
/// <summary>
/// This stream redirects all operations to another stream, specified by the user
/// You might think you can do this just by changing out the stream instance you operate on, but this was built to facilitate some features which were never built:
/// The ability to have the old stream automatically flushed, or for a derived class to manage two streams at a higher level and use these facilities to switch them
/// without this subclass's clients knowing about the existence of two streams.
/// Well, it could be useful, so here it is.
/// </summary>
public class SwitcherStream : Stream
{
2014-02-04 21:15:33 +00:00
// switchstream method? flush old stream?
private Stream _currStream ;
2013-11-22 09:33:56 +00:00
public SwitcherStream ( )
{
}
2014-10-12 04:19:01 +00:00
/// <summary>
/// if this is enabled, seeks to Begin,0 will get ignored; anything else will be an exception
/// </summary>
public bool DenySeekHack = false ;
2017-04-13 18:57:58 +00:00
public override bool CanRead = > _currStream . CanRead ;
2013-11-22 09:33:56 +00:00
2017-04-15 20:37:30 +00:00
public override bool CanSeek = > _currStream . CanSeek ;
2013-11-22 09:33:56 +00:00
2017-04-15 20:37:30 +00:00
public override bool CanWrite = > _currStream . CanWrite ;
2017-04-13 18:57:58 +00:00
2017-04-15 20:37:30 +00:00
public override long Length = > _currStream . Length ;
2017-04-13 18:57:58 +00:00
2017-04-15 20:37:30 +00:00
public override long Position
2013-11-22 09:33:56 +00:00
{
get
{
2014-02-04 21:15:33 +00:00
return _currStream . Position ;
2013-11-22 09:33:56 +00:00
}
2014-02-04 21:15:33 +00:00
2013-11-22 09:33:56 +00:00
set
{
2014-10-12 04:19:01 +00:00
if ( DenySeekHack )
{
2017-04-13 18:57:58 +00:00
if ( value = = 0 )
{
return ;
}
throw new InvalidOperationException ( "Cannot set position to non-zero in a SwitcherStream with DenySeekHack=true" ) ;
2014-10-12 04:19:01 +00:00
}
2017-04-13 18:57:58 +00:00
2014-10-12 04:19:01 +00:00
_currStream . Position = value ;
2013-11-22 09:33:56 +00:00
}
}
2014-02-04 21:15:33 +00:00
public void SetCurrStream ( Stream str )
{
_currStream = str ;
}
public override void Flush ( )
{
_currStream . Flush ( ) ;
}
2013-11-22 09:33:56 +00:00
public override int Read ( byte [ ] buffer , int offset , int count )
{
2014-02-04 21:15:33 +00:00
return _currStream . Read ( buffer , offset , count ) ;
2013-11-22 09:33:56 +00:00
}
public override long Seek ( long offset , SeekOrigin origin )
{
2014-10-12 04:19:01 +00:00
if ( DenySeekHack )
{
2017-04-13 18:57:58 +00:00
if ( offset = = 0 & & origin = = SeekOrigin . Begin )
{
return 0 ;
}
throw new InvalidOperationException ( "Cannot call Seek with non-zero offset or non-Begin origin in a SwitcherStream with DenySeekHack=true" ) ;
2014-10-12 04:19:01 +00:00
}
2017-04-13 18:57:58 +00:00
2014-02-04 21:15:33 +00:00
return _currStream . Seek ( offset , origin ) ;
2013-11-22 09:33:56 +00:00
}
public override void SetLength ( long value )
{
2014-02-04 21:15:33 +00:00
_currStream . SetLength ( value ) ;
2013-11-22 09:33:56 +00:00
}
public override void Write ( byte [ ] buffer , int offset , int count )
{
2014-02-04 21:15:33 +00:00
_currStream . Write ( buffer , offset , count ) ;
2013-11-22 09:33:56 +00:00
}
}
}