Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2019-10-18 19:23:34 +0300
committerMarek Safar <marek.safar@gmail.com>2019-10-22 16:46:29 +0300
commitd4a2f01064ac0c6d7f6ae3e2ceb8a1dd15b4139f (patch)
treebb5aeb5d5619349cbfed0b90f697804b36ac4f67 /netcore/System.Private.CoreLib/shared/System/Buffer.cs
parent8ea042648814148f3145dd96e99471e346a3980a (diff)
Rewrite Buffer.BlockCopy in C# (dotnet/coreclr#27216)
* Rewrite Buffer.BlockCopy in C# Fixes #27106 * Workaround to enable type check optimizations for BlockCopy only Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Diffstat (limited to 'netcore/System.Private.CoreLib/shared/System/Buffer.cs')
-rw-r--r--netcore/System.Private.CoreLib/shared/System/Buffer.cs48
1 files changed, 48 insertions, 0 deletions
diff --git a/netcore/System.Private.CoreLib/shared/System/Buffer.cs b/netcore/System.Private.CoreLib/shared/System/Buffer.cs
index 55fd11e164c..78d82738117 100644
--- a/netcore/System.Private.CoreLib/shared/System/Buffer.cs
+++ b/netcore/System.Private.CoreLib/shared/System/Buffer.cs
@@ -26,6 +26,54 @@ namespace System
{
public static partial class Buffer
{
+ // Copies from one primitive array to another primitive array without
+ // respecting types. This calls memmove internally. The count and
+ // offset parameters here are in bytes. If you want to use traditional
+ // array element indices and counts, use Array.Copy.
+ public static unsafe void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
+ {
+ if (src == null)
+ throw new ArgumentNullException(nameof(src));
+ if (dst == null)
+ throw new ArgumentNullException(nameof(dst));
+
+ nuint uSrcLen = (nuint)src.LongLength;
+ if (src.GetType() != typeof(byte[]))
+ {
+ if (!IsPrimitiveTypeArray(src))
+ throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(src));
+ uSrcLen *= (nuint)src.GetElementSize();
+ }
+
+ nuint uDstLen = uSrcLen;
+ if (src != dst)
+ {
+ uDstLen = (nuint)dst.LongLength;
+ if (dst.GetType() != typeof(byte[]))
+ {
+ if (!IsPrimitiveTypeArray(dst))
+ throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(dst));
+ uDstLen *= (nuint)dst.GetElementSize();
+ }
+ }
+
+ if (srcOffset < 0)
+ throw new ArgumentOutOfRangeException(nameof(srcOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32);
+ if (dstOffset < 0)
+ throw new ArgumentOutOfRangeException(nameof(dstOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32);
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_MustBeNonNegInt32);
+
+ nuint uCount = (nuint)count;
+ nuint uSrcOffset = (nuint)srcOffset;
+ nuint uDstOffset = (nuint)dstOffset;
+
+ if ((uSrcLen < uSrcOffset + uCount) || (uDstLen < uDstOffset + uCount))
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
+
+ Memmove(ref Unsafe.AddByteOffset(ref dst.GetRawArrayData(), uDstOffset), ref Unsafe.AddByteOffset(ref src.GetRawArrayData(), uSrcOffset), uCount);
+ }
+
public static int ByteLength(Array array)
{
// Is the array present?