sockscape/server_old/Libraries/Kneesocks/ReadBuffer.cs

101 lines
2.9 KiB
C#
Raw Normal View History

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