namespace IRCTokens; public static class EnumerableExtensions { public static IEnumerable Split(this byte[] bytes, byte separator) { if (bytes == null || bytes.Length == 0) return new List(); 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] = []; return lines.ToArray(); } public static byte[] Trim(this IEnumerable bytes, byte separator) { if (bytes == null) return []; var byteList = new List(bytes); var i = 0; if (!byteList.Any()) return byteList.ToArray(); while (byteList[i] == separator) { byteList.RemoveAt(i); i++; } i = byteList.Count - 1; while (byteList[i] == separator) { byteList.RemoveAt(i); i--; } return byteList.ToArray(); } #if !(REFERENCE_ASSEMBLY && (NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER)) /// /// Bypasses a specified number of contiguous elements from the end of the sequence and returns the remaining elements. /// /// Source sequence element type. /// Source sequence. /// /// The number of elements to skip from the end of the sequence before returning the remaining /// elements. /// Backported from netcore: /// https://github.com/dotnet/reactive/blob/ebab5fc37e8c0888f7b96107852a8794e9af1735/Ix.NET/Source/System.Interactive/System/Linq/Operators/SkipLast.cs /// /// Sequence bypassing the specified number of elements counting from the end of the source sequence. public static IEnumerable SkipLast(this IEnumerable source, int count) { if (source == null) throw new ArgumentNullException(nameof(source)); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); return SkipLastCore(source, count); } private static IEnumerable SkipLastCore(this IEnumerable source, int count) { var q = new Queue(); foreach (var x in source) { q.Enqueue(x); if (q.Count > count) { yield return q.Dequeue(); } } } #endif }