69 lines
2.1 KiB
C#
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);
|
|
}
|
|
}
|