Files
2026-04-10 13:58:15 +08:00

77 lines
2.0 KiB
C#

using System;
using System.IO;
using System.Runtime.InteropServices;
namespace PriFileFormat
{
public class SubStream: Stream
{
Stream baseStream;
long subStreamPosition;
long subStreamLength;
public SubStream (Stream baseStream, long subStreamPosition, long subStreamLength)
{
this.baseStream = baseStream;
this.subStreamPosition = subStreamPosition;
this.subStreamLength = subStreamLength;
}
public long SubStreamPosition => subStreamPosition;
public override bool CanRead => baseStream.CanRead;
public override bool CanSeek => baseStream.CanSeek;
public override bool CanWrite => false;
public override long Length => subStreamLength;
public override long Position
{
get { return baseStream.Position - subStreamPosition; }
set { baseStream.Position = subStreamPosition + value; }
}
public override void Flush ()
{
}
public override int Read (byte [] buffer, int offset, int count)
{
if (Position < 0)
throw new InvalidOperationException ("Cannot read when position is negative.");
if (Position + count > subStreamLength)
count = (int)(subStreamLength - Position);
return baseStream.Read (buffer, offset, count);
}
public override long Seek (long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
return baseStream.Seek (subStreamPosition + offset, SeekOrigin.Begin) - subStreamPosition;
case SeekOrigin.Current:
return baseStream.Seek (offset, SeekOrigin.Current) - subStreamPosition;
case SeekOrigin.End:
return baseStream.Seek (subStreamPosition + subStreamLength + offset, SeekOrigin.Begin) - subStreamPosition;
default:
throw new ArgumentException ("Invalid origin.", nameof (origin));
}
}
public override void SetLength (long value)
{
throw new NotSupportedException ();
}
public override void Write (byte [] buffer, int offset, int count)
{
throw new NotSupportedException ();
}
~SubStream () { baseStream = null; }
}
}