IRC parsing, tokenization, and state handling in C#
at tunit 67 lines 1.6 kB view raw
1using System.Text; 2 3namespace IRCTokens; 4 5public class StatefulEncoder 6{ 7 private List<Line> _bufferedLines; 8 private Encoding _encoding; 9 10 public StatefulEncoder() 11 { 12 Clear(); 13 } 14 15 public Encoding Encoding 16 { 17 get => _encoding ?? Encoding.GetEncoding(Encoding.UTF8.CodePage, EncoderFallback.ExceptionFallback, 18 DecoderFallback.ExceptionFallback); 19 set 20 { 21 if (value != null) 22 _encoding = Encoding.GetEncoding(value.CodePage, EncoderFallback.ExceptionFallback, 23 DecoderFallback.ExceptionFallback); 24 } 25 } 26 27 public byte[] PendingBytes { get; private set; } 28 29 public string Pending() 30 { 31 try 32 { 33 return Encoding.GetString(PendingBytes); 34 } 35 catch (DecoderFallbackException e) 36 { 37 Console.WriteLine(e); 38 throw; 39 } 40 } 41 42 public void Clear() 43 { 44 PendingBytes = []; 45 _bufferedLines = []; 46 } 47 48 public void Push(Line line) 49 { 50 if (line == null) throw new ArgumentNullException(nameof(line)); 51 52 PendingBytes = PendingBytes.Concat(Encoding.GetBytes($"{line.Format()}\r\n")).ToArray(); 53 _bufferedLines.Add(line); 54 } 55 56 public List<Line> Pop(int byteCount) 57 { 58 var sent = PendingBytes.Take(byteCount).Count(c => c == '\n'); 59 60 PendingBytes = PendingBytes.Skip(byteCount).ToArray(); 61 62 var sentLines = _bufferedLines.Take(sent).ToList(); 63 _bufferedLines = _bufferedLines.Skip(sent).ToList(); 64 65 return sentLines; 66 } 67}