ircsharp/IrcTokens/StatefulEncoder.cs

78 lines
2.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IrcTokens
{
public class StatefulEncoder
{
private Encoding _encoding;
public Encoding Encoding
{
get => _encoding ?? Encoding.GetEncoding(Encoding.UTF8.CodePage, EncoderFallback.ExceptionFallback,
DecoderFallback.ExceptionFallback);
set
{
if (value != null)
{
_encoding = Encoding.GetEncoding(value.CodePage, EncoderFallback.ExceptionFallback,
DecoderFallback.ExceptionFallback);
}
}
}
private Queue<Line> _bufferedLines;
public byte[] PendingBytes { get; private set; }
public string Pending()
{
try
{
return Encoding.GetString(PendingBytes);
}
catch (DecoderFallbackException e)
{
Console.WriteLine(e);
throw;
}
}
public StatefulEncoder()
{
Clear();
}
public void Clear()
{
PendingBytes = Array.Empty<byte>();
_bufferedLines = new Queue<Line>();
}
public void Push(Line line)
{
if (line == null)
{
throw new ArgumentNullException(nameof(line));
}
PendingBytes = PendingBytes.Concat(Encoding.GetBytes($"{line.Format()}\r\n")).ToArray();
_bufferedLines.Enqueue(line);
}
public List<Line> Pop(int byteCount)
{
var sent = PendingBytes.Take(byteCount).Count(c => c == '\n');
PendingBytes = PendingBytes.Skip(byteCount).ToArray();
_bufferedLines = new Queue<Line>(_bufferedLines.Skip(sent));
return Enumerable.Range(0, sent)
.Select(_ => _bufferedLines.Dequeue())
.ToList();
}
}
}