📄 memoryarray.cs
字号:
public void CopyTo(Array array, int index)
{
if (!(array is T[]))
{
throw new InvalidCastException("array");
}
try
{
CopyTo((T[])array, 0, index, length);
}
catch (ArgumentOutOfRangeException ex)
{
throw new ArgumentException(ex.Message, ex);
}
}
/// <summary>
/// Copies a range of elements from the unmanaged array starting at the specified
/// <typeparamref name="sourceIndex"/> and pastes them to <paramref name="array"/>
/// starting at the specified <paramref name="destinationIndex"/>.
/// The length and the indexes are specified as 32-bit integers.
/// </summary>
/// <param name="array">The array that receives the data.</param>
/// <param name="sourceIndex">A 32-bit integer that represents the index
/// in the unmanaged array at which copying begins.</param>
/// <param name="destinationIndex">A 32-bit integer that represents the index in
/// the destination array at which storing begins.</param>
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="array"/> is a null reference (Nothing in Visual Basic).</exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="sourceIndex"/> is outside the range of valid indexes
/// for the unmanaged array or <paramref name="length"/> is greater than the number of elements
/// from <paramref name="index"/> to the end of the unmanaged array
/// <para>-or-</para>
/// <paramref name="destinationIndex"/> is outside the range of valid indexes
/// for the array or <paramref name="length"/> is greater than the number of elements
/// from <paramref name="index"/> to the end of the array.
/// </exception>
public void CopyTo(T[] array, int sourceIndex, int destinationIndex, int length)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if ((sourceIndex >= this.length) || (sourceIndex < 0))
{
throw new ArgumentOutOfRangeException("sourceIndex");
}
if ((destinationIndex >= array.Length) || (destinationIndex < 0))
{
throw new ArgumentOutOfRangeException("destinationIndex");
}
if ((sourceIndex + length > this.length) ||
(destinationIndex + length > array.Length) ||
(length < 1))
{
throw new ArgumentOutOfRangeException("length");
}
if (isOneBit || isFourBit)
{
for (int i = 0; i != length; i++)
{
array[destinationIndex++] = GetValueInternal(sourceIndex++);
}
}
else
{
GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
byte* dst = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(array, destinationIndex);
CopyMemory(dst, baseAddress + (size * sourceIndex), size * length);
handle.Free();
}
}
/// <summary>
/// Copies a range of elements from the array starting at the specified
/// <typeparamref name="sourceIndex"/> and pastes them to the unmanaged array
/// starting at the specified <paramref name="destinationIndex"/>.
/// The length and the indexes are specified as 32-bit integers.
/// </summary>
/// <param name="array">The array that holds the data.</param>
/// <param name="sourceIndex">A 32-bit integer that represents the index
/// in the array at which copying begins.</param>
/// <param name="destinationIndex">A 32-bit integer that represents the index in
/// the unmanaged array at which storing begins.</param>
/// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="array"/> is a null reference (Nothing in Visual Basic).</exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="sourceIndex"/> is outside the range of valid indexes
/// for the array or <paramref name="length"/> is greater than the number of elements
/// from <paramref name="index"/> to the end of the array
/// <para>-or-</para>
/// <paramref name="destinationIndex"/> is outside the range of valid indexes
/// for the unmanaged array or <paramref name="length"/> is greater than the number of elements
/// from <paramref name="index"/> to the end of the unmanaged array.
/// </exception>
public void CopyFrom(T[] array, int sourceIndex, int destinationIndex, int length)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if ((destinationIndex >= this.length) || (destinationIndex < 0))
{
throw new ArgumentOutOfRangeException("destinationIndex");
}
if ((sourceIndex >= array.Length) || (sourceIndex < 0))
{
throw new ArgumentOutOfRangeException("sourceIndex");
}
if ((destinationIndex + length > this.length) ||
(sourceIndex + length > array.Length) ||
(length < 1))
{
throw new ArgumentOutOfRangeException("length");
}
if (isOneBit || isFourBit)
{
for (int i = 0; i != length; i++)
{
SetValueInternal(array[sourceIndex++], destinationIndex++);
}
}
else
{
GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
byte* src = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(array, sourceIndex);
CopyMemory(baseAddress + (size * destinationIndex), src, size * length);
handle.Free();
}
}
/// <summary>
/// Returns the represented block of memory as an array of <see cref="Byte"/>.
/// </summary>
/// <returns>The represented block of memory.</returns>
public byte[] ToByteArray()
{
byte[] result;
if (isOneBit)
{
result = new byte[(length + 7) / 8];
}
else if (isFourBit)
{
result = new byte[(length + 3) / 4];
}
else
{
result = new byte[size * length];
}
fixed (byte* dst = result)
{
CopyMemory(dst, baseAddress, result.Length);
}
return result;
}
/// <summary>
/// Gets or sets the value at the specified position in the array.
/// </summary>
/// <param name="index">A 32-bit integer that represents the position
/// of the array element to get.</param>
/// <returns>The value at the specified position in the array.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="index"/> is outside the range of valid indexes
/// for the unmanaged array.</exception>
public T this[int index]
{
get
{
return GetValue(index);
}
set
{
SetValue(value, index);
}
}
/// <summary>
/// Gets or sets the values of the unmanaged array.
/// </summary>
public T[] Data
{
get
{
return GetValues(0, length);
}
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (value.Length != length)
{
throw new ArgumentOutOfRangeException("value.Lengt");
}
SetValues(value, 0);
}
}
/// <summary>
/// Gets the length of the unmanaged array.
/// </summary>
public int Length
{
get
{
return length;
}
}
/// <summary>
/// Gets the base address of the represented memory block.
/// </summary>
public IntPtr BaseAddress
{
get
{
return new IntPtr(baseAddress);
}
}
/// <summary>
/// Creates a shallow copy of the <see cref="MemoryArray<T>"/>.
/// </summary>
/// <returns>A shallow copy of the <see cref="MemoryArray<T>"/>.</returns>
public object Clone()
{
return new MemoryArray<T>(baseAddress, length);
}
/// <summary>
/// Gets a 32-bit integer that represents the total number of elements
/// in the <see cref="MemoryArray<T>"/>.
/// </summary>
public int Count
{
get { return length; }
}
/// <summary>
/// Gets a value indicating whether access to the <see cref="MemoryArray<T>"/>
/// is synchronized (thread safe).
/// </summary>
public bool IsSynchronized
{
get { return false; }
}
/// <summary>
/// Gets an object that can be used to synchronize access to the <see cref="MemoryArray<T>"/>.
/// </summary>
public object SyncRoot
{
get
{
if (syncRoot == null)
{
System.Threading.Interlocked.CompareExchange(ref syncRoot, new object(), null);
}
return syncRoot;
}
}
/// <summary>
/// Retrieves an object that can iterate through the individual
/// elements in this <see cref="MemoryArray<T>"/>.
/// </summary>
/// <returns>An <see cref="IEnumerator"/> for the <see cref="MemoryArray<T>"/>.</returns>
public IEnumerator GetEnumerator()
{
T[] values = GetValues(0, length);
for (int i = 0; i != values.Length; i++)
{
yield return values[i];
}
}
/// <summary>
/// Retrieves an object that can iterate through the individual
/// elements in this <see cref="MemoryArray<T>"/>.
/// </summary>
/// <returns>An <see cref="IEnumerator<T>"/> for the <see cref="MemoryArray<T>"/>.</returns>
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
T[] values = GetValues(0, length);
for (int i = 0; i != values.Length; i++)
{
yield return values[i];
}
}
/// <summary>
/// Tests whether the specified <see cref="MemoryArray<T>"/> structure is equivalent to this
/// <see cref="MemoryArray<T>"/> structure.
/// </summary>
/// <param name="obj">The structure to test.</param>
/// <returns><b>true</b> if <paramref name="obj"/> is a <see cref="MemoryArray<T>"/>
/// instance equivalent to this <see cref="MemoryArray<T>"/> structure; otherwise,
/// <b>false</b>.</returns>
public override bool Equals(object obj)
{
return ((obj is MemoryArray<T>) && Equals((MemoryArray<T>)obj));
}
/// <summary>
/// Tests whether the specified <see cref="MemoryArray<T>"/> structure is equivalent to this
/// <see cref="MemoryArray<T>"/> structure.
/// </summary>
/// <param name="other">The structure to test.</param>
/// <returns><b>true</b> if <paramref name="other"/> is equivalent to this
/// <see cref="MemoryArray<T>"/> structure; otherwise,
/// <b>false</b>.</returns>
public bool Equals(MemoryArray<T> other)
{
return ((this.baseAddress == other.baseAddress) && (this.length == other.length));
}
/// <summary>
/// Serves as a hash function for a particular type.
/// </summary>
/// <returns>A hash code for the current <see cref="MemoryArray<T>"/>.</returns>
public override int GetHashCode()
{
return (int)baseAddress ^ length;
}
/// <summary>
/// Copies a block of memory from one location to another.
/// </summary>
/// <param name="dest">Pointer to the starting address of the copy destination.</param>
/// <param name="src">Pointer to the starting address of the block of memory to be copied.</param>
/// <param name="len">Size of the block of memory to copy, in bytes.</param>
protected static unsafe void CopyMemory(byte* dest, byte* src, int len)
{
if (len >= 0x10)
{
do
{
*((int*)dest) = *((int*)src);
*((int*)(dest + 4)) = *((int*)(src + 4));
*((int*)(dest + 8)) = *((int*)(src + 8));
*((int*)(dest + 12)) = *((int*)(src + 12));
dest += 0x10;
src += 0x10;
}
while ((len -= 0x10) >= 0x10);
}
if (len > 0)
{
if ((len & 8) != 0)
{
*((int*)dest) = *((int*)src);
*((int*)(dest + 4)) = *((int*)(src + 4));
dest += 8;
src += 8;
}
if ((len & 4) != 0)
{
*((int*)dest) = *((int*)src);
dest += 4;
src += 4;
}
if ((len & 2) != 0)
{
*((short*)dest) = *((short*)src);
dest += 2;
src += 2;
}
if ((len & 1) != 0)
{
*dest = *src;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -