2017-05-19 20:28:49 +01:00
|
|
|
// /***************************************************************************
|
2016-09-05 17:37:31 +01:00
|
|
|
// The Disc Image Chef
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Filename : OffsetStream.cs
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
//
|
|
|
|
|
// Component : Filters.
|
|
|
|
|
//
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Provides a stream that's a subset of another stream.
|
|
|
|
|
//
|
|
|
|
|
// --[ License ] --------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// This library is free software; you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU Lesser General Public License as
|
|
|
|
|
// published by the Free Software Foundation; either version 2.1 of the
|
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This library is distributed in the hope that it will be useful, but
|
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2017-12-19 03:50:57 +00:00
|
|
|
// Copyright © 2011-2018 Natalia Portillo
|
2016-09-05 17:37:31 +01:00
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Security.AccessControl;
|
|
|
|
|
using Microsoft.Win32.SafeHandles;
|
|
|
|
|
|
|
|
|
|
namespace DiscImageChef.Filters
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a stream that is a subset of another stream.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class OffsetStream : Stream
|
|
|
|
|
{
|
|
|
|
|
readonly Stream baseStream;
|
|
|
|
|
readonly long streamStart;
|
|
|
|
|
readonly long streamEnd;
|
|
|
|
|
|
|
|
|
|
public OffsetStream(Stream stream, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = stream;
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize,
|
|
|
|
|
FileOptions options, long start, long end)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode, access, share, bufferSize, options);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(SafeFileHandle handle, FileAccess access, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(handle, access);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(SafeFileHandle handle, FileAccess access, int bufferSize, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(handle, access, bufferSize);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public OffsetStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync, long start,
|
|
|
|
|
long end)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(handle, access, bufferSize, isAsync);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public OffsetStream(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize,
|
|
|
|
|
FileOptions options, long start, long end)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode, rights, share, bufferSize, options);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public OffsetStream(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize,
|
|
|
|
|
FileOptions options, FileSecurity fileSecurity, long start, long end)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode, rights, share, bufferSize, options, fileSecurity);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize,
|
|
|
|
|
bool useAsync, long start, long end)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode, access, share, bufferSize, useAsync);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, long start,
|
|
|
|
|
long end)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode, access, share, bufferSize);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(string path, FileMode mode, FileAccess access, FileShare share, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode, access, share);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(string path, FileMode mode, FileAccess access, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode, access);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(string path, FileMode mode, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new FileStream(path, mode);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public OffsetStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible, long start,
|
|
|
|
|
long end)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new MemoryStream(buffer, index, count, writable, publiclyVisible);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(byte[] buffer, int index, int count, bool writable, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new MemoryStream(buffer, index, count, writable);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(byte[] buffer, int index, int count, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new MemoryStream(buffer, index, count);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(byte[] buffer, bool writable, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new MemoryStream(buffer, writable);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public OffsetStream(byte[] buffer, long start, long end)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Start can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end < 0) throw new ArgumentOutOfRangeException(nameof(end), "End can't be a negative number.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
streamStart = start;
|
|
|
|
|
streamEnd = end;
|
|
|
|
|
|
|
|
|
|
baseStream = new MemoryStream(buffer);
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
if(end > baseStream.Length) throw new ArgumentOutOfRangeException(nameof(end), "End is after stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~OffsetStream()
|
|
|
|
|
{
|
|
|
|
|
baseStream.Close();
|
|
|
|
|
baseStream.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-22 16:17:40 +00:00
|
|
|
public override bool CanRead => baseStream.CanRead;
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-22 16:17:40 +00:00
|
|
|
public override bool CanSeek => baseStream.CanSeek;
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-22 16:17:40 +00:00
|
|
|
public override bool CanWrite => baseStream.CanWrite;
|
2016-09-05 17:37:31 +01:00
|
|
|
|
2017-12-22 16:17:40 +00:00
|
|
|
public override long Length => streamEnd - streamStart + 1;
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
public override long Position
|
|
|
|
|
{
|
2017-12-22 16:17:40 +00:00
|
|
|
get => baseStream.Position - streamStart;
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(value + streamStart > streamEnd) throw new IOException("Cannot set position past stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
baseStream.Position = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback,
|
|
|
|
|
object state)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(baseStream.Position + count > streamEnd) throw new IOException("Cannot read past stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
return baseStream.BeginRead(buffer, offset, count, callback, state);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback,
|
|
|
|
|
object state)
|
2016-09-05 17:37:31 +01:00
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(baseStream.Position + count > streamEnd) throw new IOException("Cannot write past stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
return baseStream.BeginWrite(buffer, offset, count, callback, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Close()
|
|
|
|
|
{
|
|
|
|
|
baseStream.Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected new void Dispose()
|
|
|
|
|
{
|
|
|
|
|
baseStream.Dispose();
|
|
|
|
|
base.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int EndRead(IAsyncResult asyncResult)
|
|
|
|
|
{
|
|
|
|
|
return baseStream.EndRead(asyncResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void EndWrite(IAsyncResult asyncResult)
|
|
|
|
|
{
|
|
|
|
|
baseStream.EndWrite(asyncResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int ReadByte()
|
|
|
|
|
{
|
2016-09-06 23:21:10 +01:00
|
|
|
return baseStream.Position == streamEnd + 1 ? -1 : baseStream.ReadByte();
|
2016-09-05 17:37:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void WriteByte(byte value)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(baseStream.Position + 1 > streamEnd) throw new IOException("Cannot write past stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
baseStream.WriteByte(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Flush()
|
|
|
|
|
{
|
|
|
|
|
baseStream.Flush();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int Read(byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(baseStream.Position + count > streamEnd + 1) throw new IOException("Cannot read past stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
return baseStream.Read(buffer, offset, count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override long Seek(long offset, SeekOrigin origin)
|
|
|
|
|
{
|
|
|
|
|
switch(origin)
|
|
|
|
|
{
|
|
|
|
|
case SeekOrigin.Begin:
|
2017-12-19 20:33:03 +00:00
|
|
|
if(offset + streamStart > streamEnd) throw new IOException("Cannot seek past stream end.");
|
|
|
|
|
|
2016-09-05 17:37:31 +01:00
|
|
|
return baseStream.Seek(offset + streamStart, SeekOrigin.Begin) - streamStart;
|
|
|
|
|
case SeekOrigin.End:
|
|
|
|
|
if(offset - (baseStream.Length - streamEnd) < streamStart)
|
|
|
|
|
throw new IOException("Cannot seek before stream start.");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
2016-09-05 17:37:31 +01:00
|
|
|
return baseStream.Seek(offset - (baseStream.Length - streamEnd), SeekOrigin.End) - streamStart;
|
|
|
|
|
default:
|
2017-12-19 20:33:03 +00:00
|
|
|
if(offset + baseStream.Position > streamEnd) throw new IOException("Cannot seek past stream end.");
|
|
|
|
|
|
2016-09-05 17:37:31 +01:00
|
|
|
return baseStream.Seek(offset, SeekOrigin.Current) - streamStart;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void SetLength(long value)
|
|
|
|
|
{
|
|
|
|
|
throw new NotSupportedException("Growing OffsetStream is not supported.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
2017-12-19 20:33:03 +00:00
|
|
|
if(baseStream.Position + count > streamEnd) throw new IOException("Cannot write past stream end.");
|
2016-09-05 17:37:31 +01:00
|
|
|
|
|
|
|
|
baseStream.Write(buffer, offset, count);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
}
|