mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
moved common stream classes to separate file.
This commit is contained in:
@@ -65,146 +65,4 @@ namespace GameRes.Formats.Cri
|
||||
throw new System.NotImplementedException ("SpcFormat.Write not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
public class SeekableStream : Stream
|
||||
{
|
||||
Stream m_source;
|
||||
Stream m_buffer;
|
||||
bool m_should_dispose;
|
||||
bool m_source_depleted;
|
||||
long m_read_pos;
|
||||
|
||||
public SeekableStream (Stream input, bool leave_open = false)
|
||||
{
|
||||
m_source = input;
|
||||
m_should_dispose = !leave_open;
|
||||
m_read_pos = 0;
|
||||
if (m_source.CanSeek)
|
||||
{
|
||||
m_buffer = m_source;
|
||||
m_source_depleted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buffer = new MemoryStream();
|
||||
m_source_depleted = false;
|
||||
}
|
||||
}
|
||||
|
||||
#region IO.Stream Members
|
||||
public override bool CanRead { get { return m_buffer.CanRead; } }
|
||||
public override bool CanSeek { get { return true; } }
|
||||
public override bool CanWrite { get { return false; } }
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!m_source_depleted)
|
||||
{
|
||||
m_buffer.Seek (0, SeekOrigin.End);
|
||||
m_source.CopyTo (m_buffer);
|
||||
m_source_depleted = true;
|
||||
}
|
||||
return m_buffer.Length;
|
||||
}
|
||||
}
|
||||
public override long Position
|
||||
{
|
||||
get { return m_read_pos; }
|
||||
set { m_read_pos = value; }
|
||||
}
|
||||
|
||||
public override int Read (byte[] buffer, int offset, int count)
|
||||
{
|
||||
int read, total_read = 0;
|
||||
if (m_source_depleted)
|
||||
{
|
||||
m_buffer.Position = m_read_pos;
|
||||
total_read = m_buffer.Read (buffer, offset, count);
|
||||
m_read_pos += total_read;
|
||||
return total_read;
|
||||
}
|
||||
if (m_read_pos < m_buffer.Length)
|
||||
{
|
||||
int available = (int)Math.Min (m_buffer.Length-m_read_pos, count);
|
||||
m_buffer.Position = m_read_pos;
|
||||
total_read = m_buffer.Read (buffer, offset, available);
|
||||
m_read_pos += total_read;
|
||||
count -= total_read;
|
||||
if (0 == count)
|
||||
return total_read;
|
||||
offset += total_read;
|
||||
}
|
||||
else if (count > 0)
|
||||
{
|
||||
m_buffer.Seek (0, SeekOrigin.End);
|
||||
while (m_read_pos > m_buffer.Length)
|
||||
{
|
||||
int available = (int)Math.Min (m_read_pos - m_buffer.Length, count);
|
||||
read = m_source.Read (buffer, offset, available);
|
||||
if (0 == read)
|
||||
{
|
||||
m_source_depleted = true;
|
||||
return 0;
|
||||
}
|
||||
m_buffer.Write (buffer, offset, read);
|
||||
}
|
||||
}
|
||||
read = m_source.Read (buffer, offset, count);
|
||||
m_read_pos += read;
|
||||
m_buffer.Write (buffer, offset, read);
|
||||
return total_read + read;
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
public override long Seek (long offset, SeekOrigin origin)
|
||||
{
|
||||
if (SeekOrigin.Begin == origin)
|
||||
m_read_pos = offset;
|
||||
else if (SeekOrigin.Current == origin)
|
||||
m_read_pos += offset;
|
||||
else
|
||||
m_read_pos = Length + offset;
|
||||
|
||||
return m_read_pos;
|
||||
}
|
||||
|
||||
public override void SetLength (long length)
|
||||
{
|
||||
throw new NotSupportedException ("SeekableStream.SetLength method is not supported");
|
||||
}
|
||||
|
||||
public override void Write (byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException ("SeekableStream.Write method is not supported");
|
||||
}
|
||||
|
||||
public override void WriteByte (byte value)
|
||||
{
|
||||
throw new NotSupportedException ("SeekableStream.WriteByte method is not supported");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
bool _disposed = false;
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (m_should_dispose)
|
||||
m_source.Dispose();
|
||||
if (m_buffer != m_source)
|
||||
m_buffer.Dispose();
|
||||
}
|
||||
_disposed = true;
|
||||
base.Dispose (disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user