2025-05-07 11:20:40 +08:00

177 lines
4.7 KiB
C#

using System;
using System.IO;
namespace BestHTTP.Extensions
{
public class ReadOnlyBufferedStream : Stream
{
public bool CheckForDataAvailability { get; set; }
Stream stream;
public const int READBUFFER = 8192;
byte[] buf;
int available = 0;
int pos = 0;
public ReadOnlyBufferedStream(Stream nstream)
{
stream = nstream;
buf = VariableSizedBufferPool.Get(READBUFFER, true);
}
public override int Read(byte[] buffer, int offset, int size)
{
if (size <= available)
{
Array.Copy(buf, pos, buffer, offset, size);
available -= size;
pos += size;
return size;
}
else
{
int readcount = 0;
if (available > 0)
{
Array.Copy(buf, pos, buffer, offset, available);
offset += available;
readcount += available;
available = 0;
pos = 0;
}
while (true)
{
try
{
available = stream.Read(buf, 0, buf.Length);
pos = 0;
}
catch (Exception ex)
{
if (readcount > 0)
{
return readcount;
}
throw (ex);
}
if (available < 1)
{
if (readcount > 0)
{
return readcount;
}
return 0;
}
else
{
int toread = size - readcount;
if (toread <= available)
{
Array.Copy(buf, pos, buffer, offset, toread);
available -= toread;
pos += toread;
readcount += toread;
return readcount;
}
else
{
Array.Copy(buf, pos, buffer, offset, available);
offset += available;
readcount += available;
pos = 0;
available = 0;
}
}
}
}
}
public override int ReadByte()
{
if (available > 0)
{
available -= 1;
pos += 1;
return buf[pos - 1];
}
else
{
try
{
available = stream.Read(buf, 0, buf.Length);
pos = 0;
}
catch
{
return -1;
}
if (available < 1)
{
return -1;
}
else
{
available -= 1;
pos += 1;
return buf[pos - 1];
}
}
}
protected override void Dispose(bool disposing)
{
if (buf != null)
VariableSizedBufferPool.Release(buf);
buf = null;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { throw new NotImplementedException(); }
}
public override bool CanWrite
{
get { throw new NotImplementedException(); }
}
public override long Length
{
get { throw new NotImplementedException(); }
}
public override long Position
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override void Flush()
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
}