ircsharp/IRCTokens/StatefulEncoder.cs

72 lines
1.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IRCTokens
{
public class StatefulEncoder
{
private List<Line> _bufferedLines;
private Encoding _encoding;
public StatefulEncoder()
{
Clear();
}
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);
}
}
public byte[] PendingBytes { get; private set; }
public string Pending()
{
try
{
return Encoding.GetString(PendingBytes);
}
catch (DecoderFallbackException e)
{
Console.WriteLine(e);
throw;
}
}
public void Clear()
{
PendingBytes = Array.Empty<byte>();
_bufferedLines = new List<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.Add(line);
}
public List<Line> Pop(int byteCount)
{
var sent = PendingBytes.Take(byteCount).Count(c => c == '\n');
PendingBytes = PendingBytes.Skip(byteCount).ToArray();
var sentLines = _bufferedLines.Take(sent).ToList();
_bufferedLines = _bufferedLines.Skip(sent).ToList();
return sentLines;
}
}
}