about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Harris <ben@tilde.team>2020-04-28 21:07:23 -0400
committerBen Harris <ben@tilde.team>2020-04-28 21:07:23 -0400
commit8403fd8d0fb0ac3c69e90f530fda331ea2ab639b (patch)
tree6504febcc485c6335b8cf5e333fa0437229b0704
parent6a0b8dc22fc86a5de37278231f3f8418afc9b836 (diff)
Fix example
-rw-r--r--IrcStates/Server.cs2
-rw-r--r--IrcTokens/Extensions.cs5
-rw-r--r--IrcTokens/StatefulDecoder.cs9
-rw-r--r--IrcTokens/StatefulEncoder.cs14
-rw-r--r--IrcTokens/Tests/StatefulDecoder.cs6
-rw-r--r--README.md29
-rw-r--r--TokensSample/Client.cs14
7 files changed, 50 insertions, 29 deletions
diff --git a/IrcStates/Server.cs b/IrcStates/Server.cs
index c20e041..b9e4ef4 100644
--- a/IrcStates/Server.cs
+++ b/IrcStates/Server.cs
@@ -57,7 +57,7 @@ namespace IrcStates
 
         public List<(Line, Emit)> Recv(byte[] data)
         {
-            var lines = _decoder.Push(data);
+            var lines = _decoder.Push(data, data.Length);
             if (lines == null) throw new ServerDisconnectedException();
 
             var emits = lines.Select(ParseTokens).ToList();
diff --git a/IrcTokens/Extensions.cs b/IrcTokens/Extensions.cs
index 2eee7dc..4b23774 100644
--- a/IrcTokens/Extensions.cs
+++ b/IrcTokens/Extensions.cs
@@ -36,10 +36,13 @@ namespace IrcTokens
 
         public static byte[] Trim(this IEnumerable<byte> bytes, byte separator)
         {
-            if (bytes == null || !bytes.Any()) return Array.Empty<byte>();
+            if (bytes == null) return Array.Empty<byte>();
+
             var byteList = new List<byte>(bytes);
             var i        = 0;
 
+            if (!byteList.Any()) return byteList.ToArray();
+
             while (byteList[i] == separator)
             {
                 byteList.RemoveAt(i);
diff --git a/IrcTokens/StatefulDecoder.cs b/IrcTokens/StatefulDecoder.cs
index 62d1703..b2bad5e 100644
--- a/IrcTokens/StatefulDecoder.cs
+++ b/IrcTokens/StatefulDecoder.cs
@@ -49,14 +49,15 @@ namespace IrcTokens
 
         public List<Line> Push(string data)
         {
-            return Push(Encoding.GetBytes(data));
+            var bytes = Encoding.GetBytes(data);
+            return Push(bytes, bytes.Length);
         }
 
-        public List<Line> Push(byte[] data)
+        public List<Line> Push(byte[] data, int bytesReceived)
         {
-            if (data == null || data.Length == 0) return null;
+            if (data == null) return null;
 
-            _buffer = _buffer == null ? Array.Empty<byte>() : _buffer.Concat(data).ToArray();
+            _buffer = _buffer == null ? Array.Empty<byte>() : _buffer.Concat(data.Take(bytesReceived)).ToArray();
 
             var listLines = _buffer.Split((byte) '\n').Select(l => l.Trim((byte) '\r')).ToList();
             _buffer = listLines.Last();
diff --git a/IrcTokens/StatefulEncoder.cs b/IrcTokens/StatefulEncoder.cs
index b486736..57f1b96 100644
--- a/IrcTokens/StatefulEncoder.cs
+++ b/IrcTokens/StatefulEncoder.cs
@@ -7,7 +7,7 @@ namespace IrcTokens
 {
     public class StatefulEncoder
     {
-        private Queue<Line> _bufferedLines;
+        private List<Line> _bufferedLines;
         private Encoding _encoding;
 
         public StatefulEncoder()
@@ -45,7 +45,7 @@ namespace IrcTokens
         public void Clear()
         {
             PendingBytes   = Array.Empty<byte>();
-            _bufferedLines = new Queue<Line>();
+            _bufferedLines = new List<Line>();
         }
 
         public void Push(Line line)
@@ -53,7 +53,7 @@ namespace IrcTokens
             if (line == null) throw new ArgumentNullException(nameof(line));
 
             PendingBytes = PendingBytes.Concat(Encoding.GetBytes($"{line.Format()}\r\n")).ToArray();
-            _bufferedLines.Enqueue(line);
+            _bufferedLines.Add(line);
         }
 
         public List<Line> Pop(int byteCount)
@@ -61,11 +61,11 @@ namespace IrcTokens
             var sent = PendingBytes.Take(byteCount).Count(c => c == '\n');
 
             PendingBytes   = PendingBytes.Skip(byteCount).ToArray();
-            _bufferedLines = new Queue<Line>(_bufferedLines.Take(sent));
+            
+            var sentLines = _bufferedLines.Take(sent).ToList();
+            _bufferedLines = _bufferedLines.Skip(sent).ToList();
 
-            return Enumerable.Range(0, sent)
-                .Select(_ => _bufferedLines.Dequeue())
-                .ToList();
+            return sentLines;
         }
     }
 }
diff --git a/IrcTokens/Tests/StatefulDecoder.cs b/IrcTokens/Tests/StatefulDecoder.cs
index da4009e..c5728a5 100644
--- a/IrcTokens/Tests/StatefulDecoder.cs
+++ b/IrcTokens/Tests/StatefulDecoder.cs
@@ -45,7 +45,8 @@ namespace IrcTokens.Tests
         {
             var iso8859 = Encoding.GetEncoding("iso-8859-1");
             _decoder = new IrcTokens.StatefulDecoder {Encoding = iso8859};
-            var lines = _decoder.Push(iso8859.GetBytes("PRIVMSG #channel :hello Ç\r\n"));
+            var bytes = iso8859.GetBytes("PRIVMSG #channel :hello Ç\r\n");
+            var lines = _decoder.Push(bytes, bytes.Length);
             var line  = new Line("PRIVMSG #channel :hello Ç");
             Assert.IsTrue(line.Equals(lines[0]));
         }
@@ -55,7 +56,8 @@ namespace IrcTokens.Tests
         {
             var latin1 = Encoding.GetEncoding("iso-8859-1");
             _decoder = new IrcTokens.StatefulDecoder {Encoding = null, Fallback = latin1};
-            var lines = _decoder.Push(latin1.GetBytes("PRIVMSG #channel hélló\r\n"));
+            var bytes = latin1.GetBytes("PRIVMSG #channel hélló\r\n");
+            var lines = _decoder.Push(bytes, bytes.Length);
             Assert.AreEqual(1, lines.Count);
             Assert.IsTrue(new Line("PRIVMSG #channel hélló").Equals(lines[0]));
         }
diff --git a/README.md b/README.md
index 8b15cbc..f04b443 100644
--- a/README.md
+++ b/README.md
@@ -29,38 +29,41 @@ see the full example in [Sample/Client.cs](Sample/Client.cs)
 
     public class Client
     {
-        private readonly Socket _socket;
+        private readonly byte[] _bytes;
         private readonly StatefulDecoder _decoder;
         private readonly StatefulEncoder _encoder;
-        private readonly byte[] _bytes;
+        private readonly Socket _socket;
 
         public Client()
         {
             _decoder = new StatefulDecoder();
             _encoder = new StatefulEncoder();
-            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
-            _bytes = new byte[1024];
+            _socket  = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
+            _bytes   = new byte[1024];
         }
 
         public void Start()
         {
             _socket.Connect("127.0.0.1", 6667);
+            while (!_socket.Connected) Thread.Sleep(1000);
 
-            Send(new Line {Command = "USER", Params = new List<string> {"username", "0", "*", "real name"}});
-            Send(new Line {Command = "NICK", Params = new List<string> {"statefulbot"}});
+            Send(new Line {Command = "NICK", Params = new List<string> {"tokensbot"}});
+            Send(new Line {Command = "USER", Params = new List<string> {"tokensbot", "0", "*", "real name"}});
 
             while (true)
             {
                 var bytesReceived = _socket.Receive(_bytes);
-                var lines = _decoder.Push(_bytes);
 
-                if (lines.Count == 0)
+                if (bytesReceived == 0)
                 {
                     Console.WriteLine("! disconnected");
                     _socket.Shutdown(SocketShutdown.Both);
+                    _socket.Close();
                     break;
                 }
 
+                var lines = _decoder.Push(_bytes, bytesReceived);
+
                 foreach (var line in lines)
                 {
                     Console.WriteLine($"< {line.Format()}");
@@ -71,7 +74,13 @@ see the full example in [Sample/Client.cs](Sample/Client.cs)
                             Send(new Line {Command = "PONG", Params = line.Params});
                             break;
                         case "001":
-                            Send(new Line {Command = "JOIN", Params = new List<string> {"#channel"}});
+                            Send(new Line {Command = "JOIN", Params = new List<string> {"#test"}});
+                            break;
+                        case "PRIVMSG":
+                            Send(new Line
+                            {
+                                Command = "PRIVMSG", Params = new List<string> {line.Params[0], "hello there"}
+                            });
                             break;
                     }
                 }
@@ -83,7 +92,7 @@ see the full example in [Sample/Client.cs](Sample/Client.cs)
             Console.WriteLine($"> {line.Format()}");
             _encoder.Push(line);
             while (_encoder.PendingBytes.Length > 0)
-                _encoder.Pop(_socket.Send(_encoder.PendingBytes));
+                _encoder.Pop(_socket.Send(_encoder.PendingBytes, SocketFlags.None));
         }
     }
 
diff --git a/TokensSample/Client.cs b/TokensSample/Client.cs
index 933cab7..1061986 100644
--- a/TokensSample/Client.cs
+++ b/TokensSample/Client.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Net.Sockets;
+using System.Threading;
 using IrcTokens;
 
 namespace TokensSample
@@ -23,6 +24,7 @@ namespace TokensSample
         public void Start()
         {
             _socket.Connect("127.0.0.1", 6667);
+            while (!_socket.Connected) Thread.Sleep(1000);
 
             Send(new Line {Command = "NICK", Params = new List<string> {"tokensbot"}});
             Send(new Line {Command = "USER", Params = new List<string> {"tokensbot", "0", "*", "real name"}});
@@ -35,11 +37,12 @@ namespace TokensSample
                 {
                     Console.WriteLine("! disconnected");
                     _socket.Shutdown(SocketShutdown.Both);
+                    _socket.Close();
                     break;
                 }
 
-                var lines = _decoder.Push(_bytes);
-                
+                var lines = _decoder.Push(_bytes, bytesReceived);
+
                 foreach (var line in lines)
                 {
                     Console.WriteLine($"< {line.Format()}");
@@ -53,7 +56,10 @@ namespace TokensSample
                             Send(new Line {Command = "JOIN", Params = new List<string> {"#test"}});
                             break;
                         case "PRIVMSG":
-                            Send(new Line {Command = "PRIVMSG", Params = new List<string> {line.Params[0], "hello there"}});
+                            Send(new Line
+                            {
+                                Command = "PRIVMSG", Params = new List<string> {line.Params[0], "hello there"}
+                            });
                             break;
                     }
                 }
@@ -65,7 +71,7 @@ namespace TokensSample
             Console.WriteLine($"> {line.Format()}");
             _encoder.Push(line);
             while (_encoder.PendingBytes.Length > 0)
-                _encoder.Pop(_socket.Send(_encoder.PendingBytes));
+                _encoder.Pop(_socket.Send(_encoder.PendingBytes, SocketFlags.None));
         }
     }
 }