Пример #1
0
        public static int ByteLength(Array array)
        {
            // Is the array present?
            if (array == null)
            {
                throw new ArgumentNullException(nameof(array));
            }

            // Is it of primitive types?
            if (!array.GetCorElementTypeOfElementType().IsPrimitiveType())
            {
                throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(array));
            }

            nuint byteLength = (nuint)array.LongLength * (nuint)array.GetElementSize();

            // This API is explosed both as Buffer.ByteLength and also used indirectly in argument
            // checks for Buffer.GetByte/SetByte.
            //
            // If somebody called Get/SetByte on 2GB+ arrays, there is a decent chance that
            // the computation of the index has overflowed. Thus we intentionally always
            // throw on 2GB+ arrays in Get/SetByte argument checks (even for indicies <2GB)
            // to prevent people from running into a trap silently.

            return(checked ((int)byteLength));
        }
Пример #2
0
        // 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)
        {
            ArgumentNullException.ThrowIfNull(src);
            ArgumentNullException.ThrowIfNull(dst);

            nuint uSrcLen = src.NativeLength;

            if (src.GetType() != typeof(byte[]))
            {
                if (!src.GetCorElementTypeOfElementType().IsPrimitiveType())
                {
                    throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(src));
                }
                uSrcLen *= (nuint)src.GetElementSize();
            }

            nuint uDstLen = uSrcLen;

            if (src != dst)
            {
                uDstLen = dst.NativeLength;
                if (dst.GetType() != typeof(byte[]))
                {
                    if (!dst.GetCorElementTypeOfElementType().IsPrimitiveType())
                    {
                        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 MemoryMarshal.GetArrayDataReference(dst), uDstOffset), ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(src), uSrcOffset), uCount);
        }