@@ -870,17 +870,30 @@ public int GetLength(MemoryPoolIterator end)
870
870
871
871
public MemoryPoolIterator CopyTo ( byte [ ] array , int offset , int count , out int actual )
872
872
{
873
- // Note: Ensure for any changes in this function Consume is changed to match
874
873
if ( count == 0 || IsDefault )
875
874
{
876
875
actual = 0 ;
877
876
return this ;
878
877
}
878
+
879
879
if ( array == null )
880
880
{
881
881
return Consume ( count , out actual ) ;
882
882
}
883
883
884
+ Debug . Assert ( count + offset <= array . Length ) ;
885
+
886
+ #if NET451
887
+ return BlockCopyTo ( array , ref offset , count , out actual ) ;
888
+ #else
889
+ return MemoryCopyTo ( array , ref offset , count , out actual ) ;
890
+ #endif
891
+ }
892
+
893
+ #if NET451
894
+ private MemoryPoolIterator BlockCopyTo ( byte [ ] array , ref int offset , int count , out int actual )
895
+ {
896
+ // Note: Ensure for any changes in this function MemoryCopyTo & Consume are changed to match
884
897
var block = _block ;
885
898
var index = _index ;
886
899
var remaining = count ;
@@ -914,9 +927,51 @@ public MemoryPoolIterator CopyTo(byte[] array, int offset, int count, out int ac
914
927
}
915
928
}
916
929
}
930
+ #else
931
+ private unsafe MemoryPoolIterator MemoryCopyTo ( byte [ ] array , ref int offset , int count , out int actual )
932
+ {
933
+ // Note: Ensure for any changes in this function BlockCopyTo & Consume are changed to match
934
+ var block = _block ;
935
+ var index = _index ;
936
+ var remaining = count ;
937
+ fixed ( byte * pArray = & array [ 0 ] )
938
+ {
939
+ while ( true )
940
+ {
941
+ // Determine if we might attempt to copy data from block.Next before
942
+ // calculating "following" so we don't risk skipping data that could
943
+ // be added after block.End when we decide to copy from block.Next.
944
+ // block.End will always be advanced before block.Next is set.
945
+ var wasLastBlock = block . Next == null ;
946
+ var following = block . End - index ;
947
+ if ( remaining <= following )
948
+ {
949
+ actual = count ;
950
+ Buffer . MemoryCopy ( block . DataFixedPtr + index , pArray + offset , remaining , remaining ) ;
951
+ return new MemoryPoolIterator ( block , index + remaining ) ;
952
+ }
953
+ else if ( wasLastBlock )
954
+ {
955
+ actual = count - remaining + following ;
956
+ Buffer . MemoryCopy ( block . DataFixedPtr + index , pArray + offset , following , following ) ;
957
+ return new MemoryPoolIterator ( block , index + following ) ;
958
+ }
959
+ else
960
+ {
961
+ Buffer . MemoryCopy ( block . DataFixedPtr + index , pArray + offset , following , following ) ;
962
+ offset += following ;
963
+ remaining -= following ;
964
+ block = block . Next ;
965
+ index = block . Start ;
966
+ }
967
+ }
968
+ }
969
+ }
970
+ #endif
917
971
918
972
private MemoryPoolIterator Consume ( int count , out int actual )
919
973
{
974
+ // Note: Ensure for any changes in this function CopyToBlockCopy & CopyToMemoryCopy are changed to match
920
975
var block = _block ;
921
976
var index = _index ;
922
977
var remaining = count ;
0 commit comments