Switch-Toolbox/Switch_Toolbox_Library/IO/SubStream.cs
KillzXGaming 9e3556a5f9 More additions that seem ready for use,
Basic NCCH support, only romfs previewing for easy ripping and testing for file formats. Writing back and more improvements planned soon.
Save BTI files back.
Add structure based parsing from Kuriimu's IO extension. This will be expanded upon later to parse offsets and other things easier.
2019-08-09 18:21:16 -04:00

64 lines
2.3 KiB
C#

using System;
using System.IO;
namespace Toolbox.Library.IO
{
//From
//https://github.com/IcySon55/Kuriimu/blob/master/src/Kontract/IO/SubStream.cs
/// <summary>
/// Represenents a stream taked from another given an offset and length
/// Used for archives with streams left open
/// </summary>
public class SubStream : Stream
{
Stream baseStream;
readonly long length;
readonly long baseOffset;
public SubStream(Stream baseStream, long offset, long length)
{
if (baseStream == null) throw new ArgumentNullException("baseStream");
if (!baseStream.CanRead) throw new ArgumentException("baseStream.CanRead is false");
if (!baseStream.CanSeek) throw new ArgumentException("baseStream.CanSeek is false");
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
if (offset + length > baseStream.Length) throw new ArgumentOutOfRangeException("length");
this.baseStream = baseStream;
this.length = length;
baseOffset = offset;
}
public override int Read(byte[] buffer, int offset, int count)
{
baseStream.Position = baseOffset + offset + Position;
int read = baseStream.Read(buffer, offset, (int)Math.Min(count, length - Position));
Position += read;
return read;
}
public override long Length => length;
public override bool CanRead => true;
public override bool CanWrite => false;
public override bool CanSeek => true;
public override long Position { get; set; }
public override void Flush() => baseStream.Flush();
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin: return Position = offset;
case SeekOrigin.Current: return Position += offset;
case SeekOrigin.End: return Position = length + offset;
}
throw new ArgumentException("origin is invalid");
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
}