diff options
Diffstat (limited to 'IrcTokens/StatefulEncoder.cs')
-rw-r--r-- | IrcTokens/StatefulEncoder.cs | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/IrcTokens/StatefulEncoder.cs b/IrcTokens/StatefulEncoder.cs index 0c8b5f9..17295eb 100644 --- a/IrcTokens/StatefulEncoder.cs +++ b/IrcTokens/StatefulEncoder.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,30 +7,67 @@ namespace IrcTokens { public class StatefulEncoder { - private string _buffer; - public EncodingInfo Encoding { get; set; } - private List<Line> _bufferedLines; + private Encoding _encoding; - public string Pending => _buffer; + 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() { - _buffer = ""; - _bufferedLines.Clear(); + PendingBytes = Array.Empty<byte>(); + _bufferedLines = new Queue<Line>(); } public void Push(Line line) { - _buffer += $"{line.Format()}\r\n"; - _bufferedLines.Add(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 = _buffer.Substring(byteCount).Count(c => c == '\n'); - _buffer = _buffer.Substring(byteCount); - _bufferedLines = _bufferedLines.Skip(sent).ToList(); - return _bufferedLines.Take(sent).ToList(); + 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(); } } } |