182 lines
4.8 KiB
C#
182 lines
4.8 KiB
C#
|
using BestHTTP.PlatformSupport.Memory;
|
|||
|
using System;
|
|||
|
using System.IO;
|
|||
|
|
|||
|
namespace BestHTTP.Extensions
|
|||
|
{
|
|||
|
public sealed class ReadOnlyBufferedStream : Stream
|
|||
|
{
|
|||
|
Stream stream;
|
|||
|
public const int READBUFFER = 8192;
|
|||
|
byte[] buf;
|
|||
|
int available = 0;
|
|||
|
int pos = 0;
|
|||
|
|
|||
|
public ReadOnlyBufferedStream(Stream nstream)
|
|||
|
:this(nstream, READBUFFER)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public ReadOnlyBufferedStream(Stream nstream, int bufferSize)
|
|||
|
{
|
|||
|
stream = nstream;
|
|||
|
buf = BufferPool.Get(bufferSize, 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)
|
|||
|
BufferPool.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();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|