Files
UmaViewer/Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs
T
1605296300@qq.com 7607c8b4d2 add acb&awb support
2022-09-07 01:22:44 +08:00

117 lines
3.3 KiB
C#

using System;
using System.IO;
namespace CriWareFormats
{
public class SpliceStream : Stream
{
private readonly Stream innerStream;
private readonly long realPosition;
private long internalPosition;
private readonly object positionLock = new object();
public SpliceStream(Stream sourceStream, long offset, long length)
{
innerStream = sourceStream;
realPosition = offset;
internalPosition = 0;
Length = length;
}
public override bool CanRead => true;
public override bool CanSeek => true;
public override bool CanWrite => false;
public override long Length { get; }
public override long Position
{
get
{
lock (positionLock)
{
return internalPosition;
}
}
set
{
lock (positionLock)
{
long checkValue = value + realPosition;
if (value < 0 || value >= Length) throw new ArgumentOutOfRangeException(nameof(value));
internalPosition = value;
if (innerStream.CanSeek) innerStream.Position = checkValue;
}
}
}
public override void Flush()
{
throw new NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
lock (positionLock)
{
if (innerStream.CanRead)
{
long restore = innerStream.Position;
innerStream.Position = realPosition + internalPosition;
int read = innerStream.Read(buffer, offset, count);
internalPosition += read;
innerStream.Position = restore;
return read;
}
else return 0;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
lock (positionLock)
{
switch (origin)
{
case SeekOrigin.Begin:
if (offset >= Length) throw new ArgumentOutOfRangeException(nameof(offset));
internalPosition = offset;
break;
case SeekOrigin.Current:
if (internalPosition + offset >= Length) throw new ArgumentOutOfRangeException(nameof(offset));
internalPosition += offset;
break;
case SeekOrigin.End:
if (internalPosition - offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));
internalPosition = Length;
internalPosition -= offset;
break;
default:
break;
}
return internalPosition;
}
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
}