ircsharp/IrcTokens/StatefulDecoder.cs

79 lines
2.3 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2020-04-20 21:24:59 +00:00
using System.Linq;
using System.Text;
namespace IrcTokens
{
public class StatefulDecoder
{
private byte[] _buffer;
private Encoding _encoding;
private Encoding _fallback;
2020-04-20 21:24:59 +00:00
2020-04-28 04:35:52 +00:00
public StatefulDecoder()
{
Clear();
}
public Encoding Encoding
{
2020-04-22 14:50:30 +00:00
get => _encoding ?? Encoding.GetEncoding(Encoding.UTF8.CodePage, EncoderFallback.ExceptionFallback,
2020-04-28 04:35:52 +00:00
DecoderFallback.ExceptionFallback);
2020-04-22 14:50:30 +00:00
set
{
if (value != null)
_encoding = Encoding.GetEncoding(value.CodePage, EncoderFallback.ExceptionFallback,
DecoderFallback.ReplacementFallback);
}
}
public Encoding Fallback
{
2020-04-22 14:50:30 +00:00
get => _fallback ?? Encoding.GetEncoding(Encoding.GetEncoding("iso-8859-1").CodePage,
EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback);
set
{
if (value != null)
_fallback = Encoding.GetEncoding(value.CodePage, EncoderFallback.ReplacementFallback,
2020-04-22 14:50:30 +00:00
DecoderFallback.ReplacementFallback);
}
}
public string Pending => Encoding.GetString(_buffer);
2020-04-20 21:24:59 +00:00
public void Clear()
{
_buffer = Array.Empty<byte>();
2020-04-20 21:24:59 +00:00
}
public List<Line> Push(string data)
{
return Push(Encoding.GetBytes(data));
}
public List<Line> Push(byte[] data)
{
2020-04-28 04:35:52 +00:00
if (data == null || data.Length == 0) return null;
2020-04-20 21:24:59 +00:00
2020-04-28 15:08:01 +00:00
_buffer = _buffer == null ? Array.Empty<byte>() : _buffer.Concat(data).ToArray();
2020-04-28 15:08:01 +00:00
var listLines = _buffer.Split((byte) '\n').Select(l => l.Trim((byte) '\r')).ToList();
_buffer = listLines.Last();
2020-04-28 05:52:24 +00:00
var decodeLines = new List<Line>();
foreach (var line in listLines.SkipLast(1).Select(l => l.ToArray()))
try
{
2020-04-28 05:52:24 +00:00
decodeLines.Add(new Line(Encoding.GetString(line)));
}
catch (DecoderFallbackException)
{
2020-04-28 05:52:24 +00:00
decodeLines.Add(new Line(Fallback.GetString(line)));
}
2020-04-28 05:52:24 +00:00
return decodeLines;
2020-04-20 21:24:59 +00:00
}
}
}