From 8403fd8d0fb0ac3c69e90f530fda331ea2ab639b Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Tue, 28 Apr 2020 21:07:23 -0400 Subject: Fix example --- IrcStates/Server.cs | 2 +- IrcTokens/Extensions.cs | 5 ++++- IrcTokens/StatefulDecoder.cs | 9 +++++---- IrcTokens/StatefulEncoder.cs | 14 +++++++------- IrcTokens/Tests/StatefulDecoder.cs | 6 ++++-- README.md | 29 +++++++++++++++++++---------- TokensSample/Client.cs | 14 ++++++++++---- 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 bytes, byte separator) { - if (bytes == null || !bytes.Any()) return Array.Empty(); + if (bytes == null) return Array.Empty(); + var byteList = new List(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 Push(string data) { - return Push(Encoding.GetBytes(data)); + var bytes = Encoding.GetBytes(data); + return Push(bytes, bytes.Length); } - public List Push(byte[] data) + public List Push(byte[] data, int bytesReceived) { - if (data == null || data.Length == 0) return null; + if (data == null) return null; - _buffer = _buffer == null ? Array.Empty() : _buffer.Concat(data).ToArray(); + _buffer = _buffer == null ? Array.Empty() : _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 _bufferedLines; + private List _bufferedLines; private Encoding _encoding; public StatefulEncoder() @@ -45,7 +45,7 @@ namespace IrcTokens public void Clear() { PendingBytes = Array.Empty(); - _bufferedLines = new Queue(); + _bufferedLines = new List(); } 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 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(_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 {"username", "0", "*", "real name"}}); - Send(new Line {Command = "NICK", Params = new List {"statefulbot"}}); + Send(new Line {Command = "NICK", Params = new List {"tokensbot"}}); + Send(new Line {Command = "USER", Params = new List {"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 {"#channel"}}); + Send(new Line {Command = "JOIN", Params = new List {"#test"}}); + break; + case "PRIVMSG": + Send(new Line + { + Command = "PRIVMSG", Params = new List {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 {"tokensbot"}}); Send(new Line {Command = "USER", Params = new List {"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 {"#test"}}); break; case "PRIVMSG": - Send(new Line {Command = "PRIVMSG", Params = new List {line.Params[0], "hello there"}}); + Send(new Line + { + Command = "PRIVMSG", Params = new List {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)); } } } -- cgit 1.4.1