IRC parsing, tokenization, and state handling in C#
at ircrobots 62 lines 2.2 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5namespace IRCTokens 6{ 7 public static class EnumerableExtensions 8 { 9 public static IEnumerable<byte[]> Split(this byte[] bytes, byte separator) 10 { 11 if (bytes == null || bytes.Length == 0) return new List<byte[]>(); 12 13 var newLineIndices = bytes.Select((b, i) => b == separator ? i : -1).Where(i => i != -1).ToArray(); 14 var lines = new byte[newLineIndices.Length + 1][]; 15 var currentIndex = 0; 16 var arrIndex = 0; 17 18 for (var i = 0; i < newLineIndices.Length && currentIndex < bytes.Length; ++i) 19 { 20 var n = new byte[newLineIndices[i] - currentIndex]; 21 Array.Copy(bytes, currentIndex, n, 0, newLineIndices[i] - currentIndex); 22 currentIndex = newLineIndices[i] + 1; 23 lines[arrIndex++] = n; 24 } 25 26 // Handle the last string at the end of the array if there is one. 27 if (currentIndex < bytes.Length) 28 lines[arrIndex] = bytes.Skip(currentIndex).ToArray(); 29 else if (arrIndex == newLineIndices.Length) 30 // We had a separator character at the end of a string. Rather than just allowing 31 // a null character, we'll replace the last element in the array with an empty string. 32 lines[arrIndex] = Array.Empty<byte>(); 33 34 return lines.ToArray(); 35 } 36 37 public static byte[] Trim(this IEnumerable<byte> bytes, byte separator) 38 { 39 if (bytes == null) return Array.Empty<byte>(); 40 41 var byteList = new List<byte>(bytes); 42 var i = 0; 43 44 if (!byteList.Any()) return byteList.ToArray(); 45 46 while (byteList[i] == separator) 47 { 48 byteList.RemoveAt(i); 49 i++; 50 } 51 52 i = byteList.Count - 1; 53 while (byteList[i] == separator) 54 { 55 byteList.RemoveAt(i); 56 i--; 57 } 58 59 return byteList.ToArray(); 60 } 61 } 62}