// Decompiled with JetBrains decompiler // Type: SEGATools.Stream.SubStream // Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08 // MVID: D631183F-57B1-40A1-B502-5364D288307A // Assembly location: SEGATools.dll using System; using System.IO; namespace SEGATools.Stream { public class SubStream : System.IO.Stream { private System.IO.Stream sourceStream; private long startOffset; private long length; private bool disposeSourceStream; private bool disposed; public SubStream(System.IO.Stream source, long offset, long length, bool autoReleaseSource) { if (offset < 0L) throw new ArgumentOutOfRangeException(nameof (offset)); if (length < 0L) throw new ArgumentOutOfRangeException(nameof (length)); this.disposed = false; this.sourceStream = source; this.startOffset = offset; this.length = length; this.disposeSourceStream = autoReleaseSource; this.Seek(0L, SeekOrigin.Begin); } public override bool CanWrite => !this.disposed && this.sourceStream != null && this.sourceStream.CanWrite; public override bool CanSeek => !this.disposed && this.sourceStream != null && this.sourceStream.CanSeek; public override bool CanRead => !this.disposed && this.sourceStream != null && this.sourceStream.CanRead; public override long Length => this.length; public override long Position { get => this.sourceStream.Position - this.startOffset; set => this.Seek(value, SeekOrigin.Begin); } public override long Seek(long offset, SeekOrigin origin) { this.CheckCanSeek(); switch (origin) { case SeekOrigin.Begin: return this.sourceStream.Seek(this.startOffset + offset, origin) - this.startOffset; case SeekOrigin.Current: return this.sourceStream.Seek(offset, origin) - this.startOffset; case SeekOrigin.End: return this.sourceStream.Seek(this.startOffset + this.length + offset, SeekOrigin.Begin) - this.startOffset; default: throw new ArgumentException(string.Format("invalid origin \"{0}\": only Begin, Current and End are valid values", (object) origin), nameof (origin)); } } public override int Read(byte[] buffer, int offset, int count) { this.CheckBufferArguments(buffer, offset, count); this.CheckCanRead(); int count1 = (int) Math.Min((long) count, this.startOffset + this.length - this.Position); return this.sourceStream.Read(buffer, offset, count1); } public override void Write(byte[] buffer, int offset, int count) { this.CheckBufferArguments(buffer, offset, count); this.CheckCanWrite(); if (this.Length - this.Position < (long) count) throw new ArgumentException(); this.sourceStream.Write(buffer, offset, count); } public override void WriteByte(byte value) { this.CheckCanWrite(); if (this.Length - this.Position < 1L) throw new ArgumentException(); this.sourceStream.WriteByte(value); } public override void Close() { if (this.sourceStream == null || !this.disposeSourceStream) return; this.sourceStream.Close(); } public override void SetLength(long value) => throw new NotSupportedException(); public override void Flush() => throw new NotSupportedException(); private void CheckBufferArguments(byte[] buffer, int offset, int count) { if (buffer == null) throw new ArgumentNullException(nameof (buffer)); if (offset < 0) throw new ArgumentOutOfRangeException(nameof (offset)); if (count < 0) throw new ArgumentOutOfRangeException(nameof (count)); if (offset + count > buffer.Length) throw new ArgumentException(); } private void CheckCanWrite() { if (!this.CanWrite) throw new NotSupportedException(); if (this.disposed) throw new ObjectDisposedException(nameof (SubStream)); } private void CheckCanRead() { if (!this.CanRead) throw new NotSupportedException(); if (this.disposed) throw new ObjectDisposedException(nameof (SubStream)); } private void CheckCanSeek() { if (!this.CanSeek) throw new NotSupportedException(); if (this.disposed) throw new ObjectDisposedException(nameof (SubStream)); } public new virtual void Dispose() { this.Dispose(true); GC.SuppressFinalize((object) this); } protected new virtual void Dispose(bool disposing) { if (this.disposed) return; if (disposing) this.Close(); this.disposed = true; } } }