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