예제 #1
0
        /// <summary>
        /// Function to convert an array into a <see cref="GorgonNativeBuffer{T}"/>.
        /// </summary>
        /// <typeparam name="T">The type of data in the array. Must be an unmanaged value type.</typeparam>
        /// <param name="array">The array to turn into a native buffer.</param>
        /// <param name="index">[Optional] The index in the array that represents the beginning of the native buffer.</param>
        /// <param name="count">[Optional] The number of items in the array that will be contained in the buffer.</param>
        /// <returns>A new <see cref="GorgonNativeBuffer{T}"/> containing the <paramref name="array"/> data.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="array"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="index"/> is less than 0.</exception>
        /// <exception cref="ArgumentException">Thrown when the <paramref name="index"/> + <paramref name="count"/> are equal to or greater than the length of <paramref name="array"/>.</exception>
        /// <remarks>
        /// <para>
        /// This method copies the contents of an array into a <see cref="GorgonNativeBuffer{T}"/> so that the data can be used with native code.
        /// </para>
        /// <para>
        /// If the <paramref name="index"/> is not supplied, then the beginning of the <paramref name="array"/> is used as the start of the buffer, and if the <paramref name="count"/> parameter is not
        /// supplied, then the length of the <paramref name="array"/> (minus the <paramref name="index"/>) is used.
        /// </para>
        /// <para>
        /// <note type="warning">
        /// This method <b>copies</b> the data from the array into the buffer. This may have a negative impact on performance and memory usage.
        /// </note>
        /// </para>
        /// </remarks>
        public static GorgonNativeBuffer <T> ToNativeBuffer <T>(this T[] array, int index = 0, int?count = null)
            where T : unmanaged
        {
            if (count == null)
            {
                count = array.Length - index;
            }

            GorgonNativeBuffer <T> .ValidateArrayParams(array, index, count.Value);

            var result = new GorgonNativeBuffer <T>(count.Value);

            unsafe
            {
                fixed(T *srcPtr = &array[index])
                {
                    Unsafe.CopyBlock((T *)result, srcPtr, (uint)(Unsafe.SizeOf <T>() * count.Value));
                }
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Function to copy the contents of an array into a <see cref="GorgonNativeBuffer{T}"/>.
        /// </summary>
        /// <typeparam name="T">The type of data in the array and buffer. Must be an unmanaged value type.</typeparam>
        /// <param name="array">The array to copy from.</param>
        /// <param name="buffer">The buffer that will receive the data.</param>
        /// <param name="arrayIndex">[Optional] The index in the array to start copying from.</param>
        /// <param name="count">[Optional] The number of items to copy.</param>
        /// <param name="bufferIndex">[Optional] The index in the buffer to start writing into.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="array"/>, or <paramref name="buffer"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="arrayIndex"/>, or the <paramref name="bufferIndex"/> parameter is less than 0.</exception>
        /// <exception cref="ArgumentException">
        /// <para>Thrown when the <paramref name="arrayIndex"/> + <paramref name="count"/> is too big for the <paramref name="array"/>.</para>
        /// <para>-or-</para>
        /// <para>Thrown when the <paramref name="bufferIndex"/> + <paramref name="count"/> is too big for the <paramref name="buffer"/>.</para>
        /// </exception>
        /// <remarks>
        /// <para>
        /// If the <paramref name="count"/> parameter is ommitted, then the full length of the source buffer, minus the <paramref name="arrayIndex"/> is used. Ensure that there is enough space in the
        /// <paramref name="buffer"/> to accomodate the amount of data required.
        /// </para>
        /// </remarks>
        public static void CopyTo <T>(this T[] array, GorgonNativeBuffer <T> buffer, int arrayIndex = 0, int?count = null, int bufferIndex = 0)
            where T : unmanaged
        {
            if (array == null)
            {
                throw new ArgumentNullException(nameof(array));
            }

            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (count == null)
            {
                count = array.Length - arrayIndex;
            }

            GorgonNativeBuffer <T> .ValidateArrayParams(array, arrayIndex, count.Value);

            if (bufferIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bufferIndex), Resources.GOR_ERR_DATABUFF_OFFSET_TOO_SMALL);
            }

            if (bufferIndex + count.Value > buffer.Length)
            {
                throw new ArgumentException(string.Format(Resources.GOR_ERR_DATABUFF_SIZE_OFFSET_TOO_LARGE, bufferIndex, count));
            }

            unsafe
            {
                fixed(T *srcPtr = &array[arrayIndex])
                fixed(T * destPtr = &buffer[bufferIndex])
                {
                    Unsafe.CopyBlock(destPtr, srcPtr, (uint)count.Value);
                }
            }
        }