LibHac/libhac/Streams/SharedStream.cs
Alex Barney a68426751f Introduce multi-instance, thread-safe streams
Previously multiple streams could share the same base stream. This meant that you couldn't alternate between streams. If you read from one stream, the state of other streams sharing the same base stream would be messed up and would silently return bad data.

This commit introduces a SharedStream class that allows multiple SharedStreams to share the same base class and not interfere with each other.
2018-08-22 15:54:34 -05:00

75 lines
2.1 KiB
C#

using System;
using System.IO;
namespace libhac.Streams
{
public class SharedStream : Stream
{
private readonly SharedStreamSource _stream;
private readonly long _offset;
private long _position;
public SharedStream(SharedStreamSource source, long offset, long length)
{
_stream = source;
_offset = offset;
Length = length;
}
public override void Flush() => _stream.Flush();
public override int Read(byte[] buffer, int offset, int count)
{
long remaining = Length - Position;
if (remaining <= 0) return 0;
if (remaining < count) count = (int)remaining;
var bytesRead = _stream.Read(_offset + _position, buffer, offset, count);
_position += bytesRead;
return bytesRead;
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
Position = offset;
break;
case SeekOrigin.Current:
Position += offset;
break;
case SeekOrigin.End:
Position = Length - offset;
break;
}
return Position;
}
public override void SetLength(long value) => throw new NotImplementedException();
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(_offset + _position, buffer, offset, count);
_position += count;
}
public override bool CanRead => _stream.CanRead;
public override bool CanSeek => _stream.CanSeek;
public override bool CanWrite => _stream.CanWrite;
public override long Length { get; }
public override long Position
{
get => _position;
set
{
if (value < 0 || value >= Length)
throw new ArgumentOutOfRangeException(nameof(value));
_position = value;
}
}
}
}