namespace IRCTokens; public static class EnumerableExtensions { public static IEnumerable Split(this byte[] bytes, byte separator) { if (bytes == null || bytes.Length == 0) { return []; } 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(); } // 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. else if (arrIndex == newLineIndices.Length) { 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. /// Backported from netcore /// /// Source sequence element type. /// Source sequence. /// /// The number of elements to skip from the end of the sequence before returning the remaining elements. /// /// 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 }