From 5235ea12bcc6d206fed35f17acf10f6ff9fe9312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Fri, 17 Mar 2023 01:40:56 +0100 Subject: [PATCH] RecyclableListExtensions.CopyTo fixed to not raise exceptions in some configurations. --- .../RecyclableListExtensions.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Recyclable.Collections/RecyclableListExtensions.cs b/Recyclable.Collections/RecyclableListExtensions.cs index d9a19a1..4b51d43 100644 --- a/Recyclable.Collections/RecyclableListExtensions.cs +++ b/Recyclable.Collections/RecyclableListExtensions.cs @@ -17,12 +17,17 @@ namespace Recyclable.Collections public static void CopyTo(this T[][] sourceMemoryBlocks, long startingIndex, int blockSize, long itemsCount, T[] destinationArray, int destinationArrayIndex) { + if (itemsCount <= 0) + { + return; + } + Span sourceBlockMemory; Span destinationArrayMemory; int startingBlockIndex = (int)(startingIndex / blockSize); - int lastBlockIndex = (int)((itemsCount / blockSize) + (itemsCount - (itemsCount / blockSize) > 0 ? 1 : 0)) - 1; - Span sourceMemoryBlocksSpan = new(sourceMemoryBlocks, startingBlockIndex, lastBlockIndex - startingBlockIndex + 1); - destinationArrayMemory = new Span(destinationArray, destinationArrayIndex, destinationArray.Length - destinationArrayIndex); + int lastBlockIndex = (int)((itemsCount / blockSize) + (itemsCount % blockSize > 0 ? 1 : 0)) - 1; + Span sourceMemoryBlocksSpan = new(sourceMemoryBlocks, startingBlockIndex, lastBlockIndex + 1); + destinationArrayMemory = new Span(destinationArray, destinationArrayIndex, (int)Math.Min(destinationArray.Length - destinationArrayIndex, itemsCount)); int memoryBlockIndex; for (memoryBlockIndex = 0; memoryBlockIndex < lastBlockIndex; memoryBlockIndex++) { @@ -31,9 +36,9 @@ namespace Recyclable.Collections destinationArrayMemory = destinationArrayMemory[blockSize..]; } - if (itemsCount % blockSize > 0) + if (itemsCount - (lastBlockIndex * blockSize) > 0) { - sourceBlockMemory = new(sourceMemoryBlocksSpan[lastBlockIndex], 0, (int)(itemsCount % blockSize)); + sourceBlockMemory = new(sourceMemoryBlocksSpan[lastBlockIndex], 0, (int)(itemsCount - (lastBlockIndex * blockSize))); sourceBlockMemory.CopyTo(destinationArrayMemory); } }