about summary refs log tree commit diff
path: root/IRCTokens/StatefulEncoder.cs
diff options
context:
space:
mode:
authorBen Harris <ben@tilde.team>2020-05-14 23:06:10 -0400
committerBen Harris <ben@tilde.team>2020-05-14 23:17:47 -0400
commit21f1e95fb8e935134a969bc3d729964d8d2aadfa (patch)
treedb2be27e9b5ac48e19f92b56cbad68ab59f7099e /IRCTokens/StatefulEncoder.cs
parent304df7805b9925c2edd992fd4177eef80197f807 (diff)
rename Irc to IRC
Diffstat (limited to 'IRCTokens/StatefulEncoder.cs')
-rw-r--r--IRCTokens/StatefulEncoder.cs71
1 files changed, 71 insertions, 0 deletions
diff --git a/IRCTokens/StatefulEncoder.cs b/IRCTokens/StatefulEncoder.cs
new file mode 100644
index 0000000..46949dd
--- /dev/null
+++ b/IRCTokens/StatefulEncoder.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace IRCTokens
+{
+    public class StatefulEncoder
+    {
+        private List<Line> _bufferedLines;
+        private Encoding _encoding;
+
+        public StatefulEncoder()
+        {
+            Clear();
+        }
+
+        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);
+            }
+        }
+
+        public byte[] PendingBytes { get; private set; }
+
+        public string Pending()
+        {
+            try
+            {
+                return Encoding.GetString(PendingBytes);
+            }
+            catch (DecoderFallbackException e)
+            {
+                Console.WriteLine(e);
+                throw;
+            }
+        }
+
+        public void Clear()
+        {
+            PendingBytes   = Array.Empty<byte>();
+            _bufferedLines = new List<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.Add(line);
+        }
+
+        public List<Line> Pop(int byteCount)
+        {
+            var sent = PendingBytes.Take(byteCount).Count(c => c == '\n');
+
+            PendingBytes = PendingBytes.Skip(byteCount).ToArray();
+
+            var sentLines = _bufferedLines.Take(sent).ToList();
+            _bufferedLines = _bufferedLines.Skip(sent).ToList();
+
+            return sentLines;
+        }
+    }
+}