74 lines
1.9 KiB
C#
74 lines
1.9 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();
|
|
}
|
|
}
|
|
}
|