5 public static int ByteLength (Array array)
7 // note: the other methods in this class also use ByteLength to test for
8 // null and non-primitive arguments as a side-effect.
11 throw new ArgumentNullException ("array");
13 int length = _ByteLength (array);
15 throw new ArgumentException (Locale.GetText ("Object must be an array of primitives."));
20 public static byte GetByte (Array array, int index)
22 if (index < 0 || index >= ByteLength (array))
23 throw new ArgumentOutOfRangeException ("index");
25 return _GetByte (array, index);
28 public static void SetByte (Array array, int index, byte value)
30 if (index < 0 || index >= ByteLength (array))
31 throw new ArgumentOutOfRangeException ("index");
33 _SetByte (array, index, value);
36 public static void BlockCopy (Array src, int srcOffset, Array dst, int dstOffset, int count)
39 throw new ArgumentNullException ("src");
42 throw new ArgumentNullException ("dst");
45 throw new ArgumentOutOfRangeException ("srcOffset", Locale.GetText(
46 "Non-negative number required."));
49 throw new ArgumentOutOfRangeException ("dstOffset", Locale.GetText (
50 "Non-negative number required."));
53 throw new ArgumentOutOfRangeException ("count", Locale.GetText (
54 "Non-negative number required."));
56 // We do the checks in unmanaged code for performance reasons
57 bool res = InternalBlockCopy (src, srcOffset, dst, dstOffset, count);
59 // watch for integer overflow
60 if ((srcOffset > ByteLength (src) - count) || (dstOffset > ByteLength (dst) - count))
61 throw new ArgumentException (Locale.GetText (
62 "Offset and length were out of bounds for the array or count is greater than " +
63 "the number of elements from index to the end of the source collection."));
67 [CLSCompliantAttribute (false)]
68 public static unsafe void MemoryCopy (void* source, void* destination, long destinationSizeInBytes, long sourceBytesToCopy)
70 if (sourceBytesToCopy > destinationSizeInBytes) {
71 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.sourceBytesToCopy);
74 var src = (byte*)source;
75 var dst = (byte*)destination;
76 while (sourceBytesToCopy > int.MaxValue) {
77 Memcpy (dst, src, int.MaxValue);
78 sourceBytesToCopy -= int.MaxValue;
83 memcpy1 (dst, src, (int) sourceBytesToCopy);
86 [CLSCompliantAttribute (false)]
87 public static unsafe void MemoryCopy (void* source, void* destination, ulong destinationSizeInBytes, ulong sourceBytesToCopy)
89 if (sourceBytesToCopy > destinationSizeInBytes) {
90 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.sourceBytesToCopy);
93 var src = (byte*)source;
94 var dst = (byte*)destination;
95 while (sourceBytesToCopy > int.MaxValue) {
96 Memcpy (dst, src, int.MaxValue);
97 sourceBytesToCopy -= int.MaxValue;
102 Memcpy (dst, src, (int) sourceBytesToCopy);
105 internal static unsafe void memcpy4 (byte *dest, byte *src, int size) {
106 /*while (size >= 32) {
107 // using long is better than int and slower than double
108 // FIXME: enable this only on correct alignment or on platforms
109 // that can tolerate unaligned reads/writes of doubles
110 ((double*)dest) [0] = ((double*)src) [0];
111 ((double*)dest) [1] = ((double*)src) [1];
112 ((double*)dest) [2] = ((double*)src) [2];
113 ((double*)dest) [3] = ((double*)src) [3];
119 ((int*)dest) [0] = ((int*)src) [0];
120 ((int*)dest) [1] = ((int*)src) [1];
121 ((int*)dest) [2] = ((int*)src) [2];
122 ((int*)dest) [3] = ((int*)src) [3];
128 ((int*)dest) [0] = ((int*)src) [0];
134 ((byte*)dest) [0] = ((byte*)src) [0];
140 internal static unsafe void memcpy2 (byte *dest, byte *src, int size) {
142 ((short*)dest) [0] = ((short*)src) [0];
143 ((short*)dest) [1] = ((short*)src) [1];
144 ((short*)dest) [2] = ((short*)src) [2];
145 ((short*)dest) [3] = ((short*)src) [3];
151 ((short*)dest) [0] = ((short*)src) [0];
157 ((byte*)dest) [0] = ((byte*)src) [0];
159 static unsafe void memcpy1 (byte *dest, byte *src, int size) {
161 ((byte*)dest) [0] = ((byte*)src) [0];
162 ((byte*)dest) [1] = ((byte*)src) [1];
163 ((byte*)dest) [2] = ((byte*)src) [2];
164 ((byte*)dest) [3] = ((byte*)src) [3];
165 ((byte*)dest) [4] = ((byte*)src) [4];
166 ((byte*)dest) [5] = ((byte*)src) [5];
167 ((byte*)dest) [6] = ((byte*)src) [6];
168 ((byte*)dest) [7] = ((byte*)src) [7];
174 ((byte*)dest) [0] = ((byte*)src) [0];
175 ((byte*)dest) [1] = ((byte*)src) [1];
181 ((byte*)dest) [0] = ((byte*)src) [0];
184 internal static unsafe void Memcpy (byte *dest, byte *src, int size) {
185 // FIXME: if pointers are not aligned, try to align them
186 // so a faster routine can be used. Handle the case where
187 // the pointers can't be reduced to have the same alignment
188 // (just ignore the issue on x86?)
189 if ((((int)dest | (int)src) & 3) != 0) {
190 if (((int)dest & 1) != 0 && ((int)src & 1) != 0 && size >= 1) {
196 if (((int)dest & 2) != 0 && ((int)src & 2) != 0 && size >= 2) {
197 ((short*)dest) [0] = ((short*)src) [0];
202 if ((((int)dest | (int)src) & 1) != 0) {
203 memcpy1 (dest, src, size);
206 if ((((int)dest | (int)src) & 2) != 0) {
207 memcpy2 (dest, src, size);
211 memcpy4 (dest, src, size);