/// <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); }
/// <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); } } }