using System; using System.IO; namespace BizHawk.Common { /// /// 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. /// public class SwitcherStream : Stream { // switchstream method? flush old stream? private Stream _currStream; public SwitcherStream() { } /// /// if this is enabled, seeks to Begin,0 will get ignored; anything else will be an exception /// public bool DenySeekHack = false; public override bool CanRead { get { return _currStream.CanRead; } } public override bool CanSeek { get { return _currStream.CanSeek; } } public override bool CanWrite { get { return _currStream.CanWrite; } } public override long Length { get { return _currStream.Length; } } public override long Position { get { return _currStream.Position; } set { if (DenySeekHack) { if (value == 0) return; else throw new InvalidOperationException("Cannot set position to non-zero in a SwitcherStream with DenySeekHack=true"); } _currStream.Position = value; } } public void SetCurrStream(Stream str) { _currStream = str; } public override void Flush() { _currStream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { return _currStream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { if (DenySeekHack) { if (offset == 0 && origin == SeekOrigin.Begin) return 0; else throw new InvalidOperationException("Cannot call Seek with non-zero offset or non-Begin origin in a SwitcherStream with DenySeekHack=true"); } return _currStream.Seek(offset, origin); } public override void SetLength(long value) { _currStream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { _currStream.Write(buffer, offset, count); } } }