Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Buffer.cs
Go to the documentation of this file.
4
5namespace System;
6
7public static class Buffer
8{
9 [StructLayout(LayoutKind.Sequential, Size = 16)]
10 private struct Block16
11 {
12 }
13
14 [StructLayout(LayoutKind.Sequential, Size = 64)]
15 private struct Block64
16 {
17 }
18
19 [MethodImpl(MethodImplOptions.NoInlining)]
20 internal unsafe static void _ZeroMemory(ref byte b, nuint byteLength)
21 {
22 fixed (byte* b2 = &b)
23 {
24 __ZeroMemory(b2, byteLength);
25 }
26 }
27
28 [DllImport("QCall", CharSet = CharSet.Unicode)]
29 private unsafe static extern void __ZeroMemory(void* b, nuint byteLength);
30
31 internal static void BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount)
32 {
33 if (byteCount <= 16384)
34 {
36 }
37 else
38 {
40 }
41 }
42
43 [MethodImpl(MethodImplOptions.NoInlining)]
44 private static void _BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount)
45 {
46 if (Unsafe.AreSame(ref source, ref destination))
47 {
48 return;
49 }
50 if ((nuint)(nint)Unsafe.ByteOffset(ref source, ref destination) >= byteCount)
51 {
52 do
53 {
54 byteCount -= 16384;
56 destination = ref Unsafe.AddByteOffset(ref destination, 16384u);
57 source = ref Unsafe.AddByteOffset(ref source, 16384u);
58 }
59 while (byteCount > 16384);
60 }
61 else
62 {
63 do
64 {
65 byteCount -= 16384;
66 __BulkMoveWithWriteBarrier(ref Unsafe.AddByteOffset(ref destination, byteCount), ref Unsafe.AddByteOffset(ref source, byteCount), 16384u);
67 }
68 while (byteCount > 16384);
69 }
71 }
72
73 [MethodImpl(MethodImplOptions.InternalCall)]
74 private static extern void __BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount);
75
76 [DllImport("QCall", CharSet = CharSet.Unicode)]
77 private unsafe static extern void __Memmove(byte* dest, byte* src, nuint len);
78
79 internal unsafe static void Memcpy(byte* dest, byte* src, int len)
80 {
81 Memmove(ref *dest, ref *src, (uint)len);
82 }
83
84 internal unsafe static void Memcpy(byte* pDest, int destIndex, byte[] src, int srcIndex, int len)
85 {
86 Memmove(ref pDest[(uint)destIndex], ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(src), (nint)(uint)srcIndex), (uint)len);
87 }
88
89 [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 internal static void Memmove<T>(ref T destination, ref T source, nuint elementCount)
91 {
92 if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
93 {
94 Memmove(ref Unsafe.As<T, byte>(ref destination), ref Unsafe.As<T, byte>(ref source), elementCount * (nuint)Unsafe.SizeOf<T>());
95 }
96 else
97 {
98 BulkMoveWithWriteBarrier(ref Unsafe.As<T, byte>(ref destination), ref Unsafe.As<T, byte>(ref source), elementCount * (nuint)Unsafe.SizeOf<T>());
99 }
100 }
101
102 public static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
103 {
104 if (src == null)
105 {
106 throw new ArgumentNullException("src");
107 }
108 if (dst == null)
109 {
110 throw new ArgumentNullException("dst");
111 }
112 nuint num = src.NativeLength;
113 if (src.GetType() != typeof(byte[]))
114 {
115 if (!src.GetCorElementTypeOfElementType().IsPrimitiveType())
116 {
117 throw new ArgumentException(SR.Arg_MustBePrimArray, "src");
118 }
119 num *= src.GetElementSize();
120 }
121 nuint num2 = num;
122 if (src != dst)
123 {
124 num2 = dst.NativeLength;
125 if (dst.GetType() != typeof(byte[]))
126 {
127 if (!dst.GetCorElementTypeOfElementType().IsPrimitiveType())
128 {
129 throw new ArgumentException(SR.Arg_MustBePrimArray, "dst");
130 }
131 num2 *= dst.GetElementSize();
132 }
133 }
134 if (srcOffset < 0)
135 {
137 }
138 if (dstOffset < 0)
139 {
141 }
142 if (count < 0)
143 {
145 }
146 nuint num3 = (nuint)count;
147 nuint num4 = (nuint)srcOffset;
148 nuint num5 = (nuint)dstOffset;
149 if (num < num4 + num3 || num2 < num5 + num3)
150 {
152 }
153 Memmove(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(dst), num5), ref Unsafe.AddByteOffset(ref MemoryMarshal.GetArrayDataReference(src), num4), num3);
154 }
155
156 public static int ByteLength(Array array)
157 {
158 if (array == null)
159 {
160 throw new ArgumentNullException("array");
161 }
162 if (!array.GetCorElementTypeOfElementType().IsPrimitiveType())
163 {
164 throw new ArgumentException(SR.Arg_MustBePrimArray, "array");
165 }
166 nuint num = array.NativeLength * array.GetElementSize();
167 return checked((int)num);
168 }
169
170 public static byte GetByte(Array array, int index)
171 {
172 if ((uint)index >= (uint)ByteLength(array))
173 {
175 }
177 }
178
179 public static void SetByte(Array array, int index, byte value)
180 {
181 if ((uint)index >= (uint)ByteLength(array))
182 {
184 }
186 }
187
188 internal unsafe static void ZeroMemory(byte* dest, nuint len)
189 {
191 }
192
193 [MethodImpl(MethodImplOptions.AggressiveInlining)]
194 [CLSCompliant(false)]
195 public unsafe static void MemoryCopy(void* source, void* destination, long destinationSizeInBytes, long sourceBytesToCopy)
196 {
197 if (sourceBytesToCopy > destinationSizeInBytes)
198 {
200 }
201 Memmove(ref *(byte*)destination, ref *(byte*)source, checked((nuint)sourceBytesToCopy));
202 }
203
204 [MethodImpl(MethodImplOptions.AggressiveInlining)]
205 [CLSCompliant(false)]
206 public unsafe static void MemoryCopy(void* source, void* destination, ulong destinationSizeInBytes, ulong sourceBytesToCopy)
207 {
208 if (sourceBytesToCopy > destinationSizeInBytes)
209 {
211 }
212 Memmove(ref *(byte*)destination, ref *(byte*)source, checked((nuint)sourceBytesToCopy));
213 }
214
215 internal static void Memmove(ref byte dest, ref byte src, nuint len)
216 {
217 if ((nuint)(nint)Unsafe.ByteOffset(ref src, ref dest) >= len && (nuint)(nint)Unsafe.ByteOffset(ref dest, ref src) >= len)
218 {
219 ref byte source = ref Unsafe.Add(ref src, (nint)len);
220 ref byte source2 = ref Unsafe.Add(ref dest, (nint)len);
221 if (len > 16)
222 {
223 if (len > 64)
224 {
225 if (len > 2048)
226 {
227 goto IL_01db;
228 }
229 nuint num = len >> 6;
230 do
231 {
232 Unsafe.As<byte, Block64>(ref dest) = Unsafe.As<byte, Block64>(ref src);
233 dest = ref Unsafe.Add(ref dest, 64);
234 src = ref Unsafe.Add(ref src, 64);
235 num--;
236 }
237 while (num != 0);
238 len %= 64;
239 if (len <= 16)
240 {
241 Unsafe.As<byte, Block16>(ref Unsafe.Add(ref source2, -16)) = Unsafe.As<byte, Block16>(ref Unsafe.Add(ref source, -16));
242 return;
243 }
244 }
245 Unsafe.As<byte, Block16>(ref dest) = Unsafe.As<byte, Block16>(ref src);
246 if (len > 32)
247 {
248 Unsafe.As<byte, Block16>(ref Unsafe.Add(ref dest, 16)) = Unsafe.As<byte, Block16>(ref Unsafe.Add(ref src, 16));
249 if (len > 48)
250 {
251 Unsafe.As<byte, Block16>(ref Unsafe.Add(ref dest, 32)) = Unsafe.As<byte, Block16>(ref Unsafe.Add(ref src, 32));
252 }
253 }
254 Unsafe.As<byte, Block16>(ref Unsafe.Add(ref source2, -16)) = Unsafe.As<byte, Block16>(ref Unsafe.Add(ref source, -16));
255 }
256 else if ((len & 0x18) != 0)
257 {
258 Unsafe.As<byte, long>(ref dest) = Unsafe.As<byte, long>(ref src);
259 Unsafe.As<byte, long>(ref Unsafe.Add(ref source2, -8)) = Unsafe.As<byte, long>(ref Unsafe.Add(ref source, -8));
260 }
261 else if ((len & 4) != 0)
262 {
263 Unsafe.As<byte, int>(ref dest) = Unsafe.As<byte, int>(ref src);
264 Unsafe.As<byte, int>(ref Unsafe.Add(ref source2, -4)) = Unsafe.As<byte, int>(ref Unsafe.Add(ref source, -4));
265 }
266 else if (len != 0)
267 {
268 dest = src;
269 if ((len & 2) != 0)
270 {
271 Unsafe.As<byte, short>(ref Unsafe.Add(ref source2, -2)) = Unsafe.As<byte, short>(ref Unsafe.Add(ref source, -2));
272 }
273 }
274 return;
275 }
276 if (Unsafe.AreSame(ref dest, ref src))
277 {
278 return;
279 }
280 goto IL_01db;
281 IL_01db:
282 _Memmove(ref dest, ref src, len);
283 }
284
285 [MethodImpl(MethodImplOptions.NoInlining)]
286 private unsafe static void _Memmove(ref byte dest, ref byte src, nuint len)
287 {
288 fixed (byte* dest2 = &dest)
289 {
290 fixed (byte* src2 = &src)
291 {
292 __Memmove(dest2, src2, len);
293 }
294 }
295 }
296}
CorElementType GetCorElementTypeOfElementType()
nuint NativeLength
Definition Array.cs:432
static void Memmove< T >(ref T destination, ref T source, nuint elementCount)
Definition Buffer.cs:90
static unsafe void ZeroMemory(byte *dest, nuint len)
Definition Buffer.cs:188
static void BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount)
Definition Buffer.cs:31
static unsafe void Memcpy(byte *pDest, int destIndex, byte[] src, int srcIndex, int len)
Definition Buffer.cs:84
static unsafe void MemoryCopy(void *source, void *destination, long destinationSizeInBytes, long sourceBytesToCopy)
Definition Buffer.cs:195
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static unsafe void __Memmove(byte *dest, byte *src, nuint len)
static void _BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount)
Definition Buffer.cs:44
static void SetByte(Array array, int index, byte value)
Definition Buffer.cs:179
static void Memmove(ref byte dest, ref byte src, nuint len)
Definition Buffer.cs:215
static unsafe void __ZeroMemory(void *b, nuint byteLength)
static unsafe void _ZeroMemory(ref byte b, nuint byteLength)
Definition Buffer.cs:20
static byte GetByte(Array array, int index)
Definition Buffer.cs:170
static int ByteLength(Array array)
Definition Buffer.cs:156
static void __BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount)
static unsafe void MemoryCopy(void *source, void *destination, ulong destinationSizeInBytes, ulong sourceBytesToCopy)
Definition Buffer.cs:206
static unsafe void Memcpy(byte *dest, byte *src, int len)
Definition Buffer.cs:79
static unsafe void _Memmove(ref byte dest, ref byte src, nuint len)
Definition Buffer.cs:286
static unsafe ref byte GetArrayDataReference(Array array)
static string ArgumentOutOfRange_MustBeNonNegInt32
Definition SR.cs:1064
static string Arg_MustBePrimArray
Definition SR.cs:290
static string Argument_InvalidOffLen
Definition SR.cs:22
Definition SR.cs:7
static void ClearWithoutReferences(ref byte b, nuint byteLength)
static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)