OpenLiveWriter/utilities/BlogServer/WebServer/SocketReader.cs

136 lines
2.5 KiB
C#

using System;
using System.Collections;
using System.IO;
using System.Net.Sockets;
using System.Text;
namespace BlogServer.WebServer
{
public class SocketReader : Stream
{
private readonly Socket socket;
private int expectedLength;
private int totalBytesRead = 0;
private readonly byte[] buffer;
private int pos;
private int len;
public SocketReader(Socket socket, int bufferSize) : this(socket, bufferSize, int.MaxValue)
{
}
public SocketReader(Socket socket, int bufferSize, int bytesRemaining)
{
this.socket = socket;
this.expectedLength = bytesRemaining;
this.buffer = new byte[bufferSize];
this.pos = 0;
this.len = 0;
}
#region Stream
public void SetBytesRemaining(int bytesRemaining)
{
int bytesInBuffer = len - pos;
expectedLength = totalBytesRead - bytesInBuffer + bytesRemaining;
}
public override void Flush()
{
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buf, int offset, int count)
{
if (pos >= len && Fill() <= 0)
{
return 0;
}
int bytesToCopy = Math.Min(count, len - pos);
Array.Copy(buffer, pos, buf, offset, bytesToCopy);
pos += bytesToCopy;
return bytesToCopy;
}
public override void Write(byte[] buf, int offset, int count)
{
throw new NotSupportedException();
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
#endregion
public string NextLine()
{
StringBuilder result = new StringBuilder();
int c;
while (-1 != (c = NextChar()))
{
result.Append((char)c);
if (c == '\n' && result.Length > 1 && result[result.Length - 2] == '\r')
break;
}
if (result.Length > 0)
return result.ToString();
else
return null;
}
public int NextChar()
{
if (pos < len || Fill() > 0)
return buffer[pos++];
return -1;
}
private int Fill()
{
this.pos = 0;
this.len = 0;
if (this.totalBytesRead >= this.expectedLength)
return 0;
this.len = socket.Receive(buffer);
this.totalBytesRead += len;
return this.len;
}
}
}