⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memoryarray.cs

📁 对gif
💻 CS
📖 第 1 页 / 共 2 页
字号:
		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&lt;T&gt;"/>.
		/// </summary>
		/// <returns>A shallow copy of the <see cref="MemoryArray&lt;T&gt;"/>.</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&lt;T&gt;"/>.
		/// </summary>
		public int Count
		{
			get { return length; }
		}

		/// <summary>
		/// Gets a value indicating whether access to the <see cref="MemoryArray&lt;T&gt;"/>
		/// 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&lt;T&gt;"/>.
		/// </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&lt;T&gt;"/>.
		/// </summary>
		/// <returns>An <see cref="IEnumerator"/> for the <see cref="MemoryArray&lt;T&gt;"/>.</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&lt;T&gt;"/>.
		/// </summary>
		/// <returns>An <see cref="IEnumerator&lt;T&gt;"/> for the <see cref="MemoryArray&lt;T&gt;"/>.</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&lt;T&gt;"/> structure is equivalent to this
		/// <see cref="MemoryArray&lt;T&gt;"/> structure.
		/// </summary>
		/// <param name="obj">The structure to test.</param>
		/// <returns><b>true</b> if <paramref name="obj"/> is a <see cref="MemoryArray&lt;T&gt;"/>
		/// instance equivalent to this <see cref="MemoryArray&lt;T&gt;"/> 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&lt;T&gt;"/> structure is equivalent to this
		/// <see cref="MemoryArray&lt;T&gt;"/> 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&lt;T&gt;"/> 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&lt;T&gt;"/>.</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 + -