Xamarin Public Jenkins (auto-signing) ef583813eb Imported Upstream version 6.4.0.137
Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
2019-07-26 19:53:28 +00:00

69 lines
2.1 KiB
C#

using System.Runtime;
using System.Runtime.CompilerServices;
using Internal.Runtime.CompilerServices;
#if BIT64
using nuint = System.UInt64;
#else
using nuint = System.UInt32;
#endif
namespace System
{
partial class Buffer
{
public static 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 ("dst");
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);
if (!IsPrimitiveTypeArray (src))
throw new ArgumentException (SR.Arg_MustBePrimArray, nameof (src));
if (!IsPrimitiveTypeArray (dst))
throw new ArgumentException (SR.Arg_MustBePrimArray, nameof (dst));
var uCount = (nuint) count;
var uSrcOffset = (nuint) srcOffset;
var uDstOffset = (nuint) dstOffset;
var uSrcLen = (nuint) ByteLength (src);
var uDstLen = (nuint) ByteLength (dst);
if (uSrcLen < uSrcOffset + uCount)
throw new ArgumentException (SR.Argument_InvalidOffLen, "");
if (uDstLen < uDstOffset + uCount)
throw new ArgumentException (SR.Argument_InvalidOffLen, "");
if (uCount != 0) {
unsafe {
fixed (byte* pSrc = &src.GetRawArrayData (), pDst = &dst.GetRawArrayData ()) {
Memmove (pDst + uDstOffset, pSrc + uSrcOffset, uCount);
}
}
}
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
static extern int _ByteLength (Array array);
static bool IsPrimitiveTypeArray (Array array)
{
// TODO: optimize
return array.GetType ().GetElementType ()!.IsPrimitive;
}
internal static unsafe void Memcpy (byte* dest, byte* src, int len) => Memmove (dest, src, (nuint) len);
[MethodImpl (MethodImplOptions.InternalCall)]
static extern unsafe void __Memmove (byte* dest, byte* src, nuint len);
}
}