sockscape/server/Libraries/Kneesocks/ReadBuffer.cs

101 lines
2.9 KiB
C#
Raw Normal View History

2017-05-05 21:05:52 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
2017-06-16 21:00:01 +00:00
namespace Kneesocks {
2017-05-15 21:15:21 +00:00
internal class ReadBuffer {
private const int BufferSize = 1024;
2017-05-05 21:05:52 +00:00
private List<byte> Buffer;
private int ExpectedLength;
private string ExpectedString;
2017-08-21 21:03:32 +00:00
private readonly NetworkStream Source;
2017-05-05 21:05:52 +00:00
private DateTime StartTime;
2017-08-21 21:03:32 +00:00
public bool IsReading { get; private set; }
2017-05-05 21:05:52 +00:00
public ReadBuffer(NetworkStream source) {
Source = source;
2017-05-08 21:06:17 +00:00
Buffer = new List<byte>();
2017-05-05 21:05:52 +00:00
}
2017-08-21 21:03:32 +00:00
public TimeSpan ElapsedReadTime
=> DateTime.UtcNow - StartTime;
2017-05-05 21:05:52 +00:00
private byte[] CheckBuffer() {
byte[] returnValue = null;
if(ExpectedString != null) {
2017-08-21 21:03:32 +00:00
var location = Encoding.ASCII.GetString(Buffer.ToArray()).IndexOf(ExpectedString, StringComparison.InvariantCulture);
2017-05-05 21:05:52 +00:00
if(location != -1) {
var fullJump = location + ExpectedString.Length;
returnValue = Buffer.Take(fullJump).ToArray();
Buffer = Buffer.Skip(fullJump).ToList();
IsReading = false;
}
} else {
if(Buffer.Count >= ExpectedLength) {
returnValue = Buffer.Take(ExpectedLength).ToArray();
Buffer = Buffer.Skip(ExpectedLength).ToList();
IsReading = false;
}
}
return returnValue;
}
public byte[] AttemptRead() {
if(!IsReading)
return null;
if(!Source.CanRead)
return null;
2017-05-05 21:05:52 +00:00
byte[] returnValue;
if((returnValue = CheckBuffer()) != null)
return returnValue;
var buffer = new byte[BufferSize];
2017-05-05 21:05:52 +00:00
while(Source.DataAvailable) {
var readAmount = ExpectedString == null
? Math.Min(BufferSize, ExpectedLength - Buffer.Count)
: BufferSize;
2017-05-05 21:05:52 +00:00
var bytesRead = Source.Read(buffer, 0, readAmount);
Buffer.AddRange(bytesRead == BufferSize ? buffer : buffer.Take(bytesRead));
2017-05-05 21:05:52 +00:00
if((returnValue = CheckBuffer()) != null)
return returnValue;
}
return null;
}
public byte[] AttemptRead(int length) {
if(IsReading)
return null;
IsReading = true;
ExpectedLength = length;
ExpectedString = null;
2017-05-11 21:03:28 +00:00
StartTime = DateTime.UtcNow;
2017-05-05 21:05:52 +00:00
return AttemptRead();
}
public byte[] AttemptRead(string terminator) {
if(IsReading)
return null;
IsReading = true;
ExpectedString = terminator;
2017-05-11 21:03:28 +00:00
StartTime = DateTime.UtcNow;
2017-05-05 21:05:52 +00:00
return AttemptRead();
}
}
}