about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Harris <ben@tilde.team>2020-04-28 11:08:01 -0400
committerBen Harris <ben@tilde.team>2020-04-28 11:08:01 -0400
commit6a0b8dc22fc86a5de37278231f3f8418afc9b836 (patch)
tree2cac03089c4d15bfe5a66b30e2b2ee5be5255f49
parent70e2eb8e7debc342d46a9ca08d70725cb624e19d (diff)
Fix stateful decoder i think
-rw-r--r--IrcSharp.sln2
-rw-r--r--IrcTokens/Extensions.cs59
-rw-r--r--IrcTokens/Line.cs4
-rw-r--r--IrcTokens/StatefulDecoder.cs37
-rw-r--r--TokensSample/Client.cs (renamed from Sample/Client.cs)0
-rw-r--r--TokensSample/Program.cs (renamed from Sample/Program.cs)0
-rw-r--r--TokensSample/TokensSample.csproj (renamed from Sample/TokensSample.csproj)0
7 files changed, 65 insertions, 37 deletions
diff --git a/IrcSharp.sln b/IrcSharp.sln
index 030a2af..0573020 100644
--- a/IrcSharp.sln
+++ b/IrcSharp.sln
@@ -5,7 +5,7 @@ VisualStudioVersion = 16.0.30011.22
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IrcTokens", "IrcTokens\IrcTokens.csproj", "{9E812F45-B2CD-42D2-8378-EBEBF8697905}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TokensSample", "Sample\TokensSample.csproj", "{A45DA39B-6B47-4713-8049-3B36E0235B67}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TokensSample", "TokensSample\TokensSample.csproj", "{A45DA39B-6B47-4713-8049-3B36E0235B67}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IrcStates", "IrcStates\IrcStates.csproj", "{233E3CB4-61F1-4368-9139-7E9F4A58ED2D}"
 EndProject
diff --git a/IrcTokens/Extensions.cs b/IrcTokens/Extensions.cs
new file mode 100644
index 0000000..2eee7dc
--- /dev/null
+++ b/IrcTokens/Extensions.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace IrcTokens
+{
+    public static class Extensions
+    {
+        public static IEnumerable<byte[]> Split(this byte[] bytes, byte separator)
+        {
+            if (bytes == null || bytes.Length == 0) return new List<byte[]>();
+
+            var newLineIndices = bytes.Select((b, i) => b == separator ? i : -1).Where(i => i != -1).ToArray();
+            var lines          = new byte[newLineIndices.Length + 1][];
+            var currentIndex   = 0;
+            var arrIndex       = 0;
+
+            for (var i = 0; i < newLineIndices.Length && currentIndex < bytes.Length; ++i)
+            {
+                var n = new byte[newLineIndices[i] - currentIndex];
+                Array.Copy(bytes, currentIndex, n, 0, newLineIndices[i] - currentIndex);
+                currentIndex      = newLineIndices[i] + 1;
+                lines[arrIndex++] = n;
+            }
+
+            // Handle the last string at the end of the array if there is one.
+            if (currentIndex < bytes.Length)
+                lines[arrIndex] = bytes.Skip(currentIndex).ToArray();
+            else if (arrIndex == newLineIndices.Length)
+                // We had a separator character at the end of a string.  Rather than just allowing
+                // a null character, we'll replace the last element in the array with an empty string.
+                lines[arrIndex] = Array.Empty<byte>();
+
+            return lines.ToArray();
+        }
+
+        public static byte[] Trim(this IEnumerable<byte> bytes, byte separator)
+        {
+            if (bytes == null || !bytes.Any()) return Array.Empty<byte>();
+            var byteList = new List<byte>(bytes);
+            var i        = 0;
+
+            while (byteList[i] == separator)
+            {
+                byteList.RemoveAt(i);
+                i++;
+            }
+
+            i = byteList.Count - 1;
+            while (byteList[i] == separator)
+            {
+                byteList.RemoveAt(i);
+                i--;
+            }
+
+            return byteList.ToArray();
+        }
+    }
+}
diff --git a/IrcTokens/Line.cs b/IrcTokens/Line.cs
index f574e4e..d1a8286 100644
--- a/IrcTokens/Line.cs
+++ b/IrcTokens/Line.cs
@@ -104,7 +104,7 @@ namespace IrcTokens
         /// </summary>
         /// <param name="val">escaped string</param>
         /// <returns>unescaped string</returns>
-        public static string UnescapeTag(string val)
+        private static string UnescapeTag(string val)
         {
             var unescaped = new StringBuilder();
 
@@ -141,7 +141,7 @@ namespace IrcTokens
         /// </summary>
         /// <param name="val">string to escape</param>
         /// <returns>escaped string</returns>
-        public static string EscapeTag(string val)
+        private static string EscapeTag(string val)
         {
             for (var i = 0; i < TagUnescaped.Length; ++i)
                 val = val?.Replace(TagUnescaped[i], TagEscaped[i], StringComparison.Ordinal);
diff --git a/IrcTokens/StatefulDecoder.cs b/IrcTokens/StatefulDecoder.cs
index 2db32f2..62d1703 100644
--- a/IrcTokens/StatefulDecoder.cs
+++ b/IrcTokens/StatefulDecoder.cs
@@ -56,41 +56,10 @@ namespace IrcTokens
         {
             if (data == null || data.Length == 0) return null;
 
-            _buffer = _buffer.Concat(data).ToArray();
+            _buffer = _buffer == null ? Array.Empty<byte>() : _buffer.Concat(data).ToArray();
 
-            // simulate string.Split('\n') before decoding
-            var newLineIndices = _buffer.Select((b, i) => b == '\n' ? i : -1).Where(i => i != -1).ToArray();
-            var lines          = new List<byte[]>();
-
-            for (int i = 0, currentIndex = 0; i < newLineIndices.Length; ++i)
-            {
-                var n = new byte[newLineIndices[i] - currentIndex];
-                Array.Copy(_buffer, currentIndex, n, 0, newLineIndices[i] - currentIndex);
-                currentIndex = newLineIndices[i] + 1;
-                lines.Add(n);
-            }
-
-            var listLines = lines.Select(l => l.ToList()).ToList();
-
-            // simulate string.Trim('\r') before decoding
-            foreach (var line in listLines)
-            {
-                var i = 0;
-                while (line[i] == '\r')
-                {
-                    line.RemoveAt(i);
-                    i++;
-                }
-
-                i = line.Count - 1;
-                while (line[i] == '\r')
-                {
-                    line.RemoveAt(i);
-                    i--;
-                }
-            }
-
-            _buffer = listLines[^1].ToArray();
+            var listLines = _buffer.Split((byte) '\n').Select(l => l.Trim((byte) '\r')).ToList();
+            _buffer = listLines.Last();
 
             var decodeLines = new List<Line>();
             foreach (var line in listLines.SkipLast(1).Select(l => l.ToArray()))
diff --git a/Sample/Client.cs b/TokensSample/Client.cs
index 933cab7..933cab7 100644
--- a/Sample/Client.cs
+++ b/TokensSample/Client.cs
diff --git a/Sample/Program.cs b/TokensSample/Program.cs
index c3a0885..c3a0885 100644
--- a/Sample/Program.cs
+++ b/TokensSample/Program.cs
diff --git a/Sample/TokensSample.csproj b/TokensSample/TokensSample.csproj
index 7c66734..7c66734 100644
--- a/Sample/TokensSample.csproj
+++ b/TokensSample/TokensSample.csproj