Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
AsAnyMarshaler.cs
Go to the documentation of this file.
3using System.Text;
4
5namespace System.StubHelpers;
6
7internal struct AsAnyMarshaler
8{
9 private enum BackPropAction
10 {
11 None,
12 Array,
13 Layout,
16 }
17
19
21
23
25
26 private static bool IsIn(int dwFlags)
27 {
28 return (dwFlags & 0x10000000) != 0;
29 }
30
31 private static bool IsOut(int dwFlags)
32 {
33 return (dwFlags & 0x20000000) != 0;
34 }
35
36 private static bool IsAnsi(int dwFlags)
37 {
38 return (dwFlags & 0xFF0000) != 0;
39 }
40
41 private static bool IsThrowOn(int dwFlags)
42 {
43 return (dwFlags & 0xFF00) != 0;
44 }
45
46 private static bool IsBestFit(int dwFlags)
47 {
48 return (dwFlags & 0xFF) != 0;
49 }
50
52 {
53 this.pvArrayMarshaler = pvArrayMarshaler;
55 layoutType = null;
56 cleanupWorkList = null;
57 }
58
59 private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags)
60 {
61 Type elementType = pManagedHome.GetType().GetElementType();
62 VarEnum varEnum = VarEnum.VT_EMPTY;
64 {
65 case TypeCode.SByte:
66 varEnum = VarEnum.VT_I1;
67 break;
68 case TypeCode.Byte:
69 varEnum = VarEnum.VT_UI1;
70 break;
71 case TypeCode.Int16:
72 varEnum = VarEnum.VT_I2;
73 break;
74 case TypeCode.UInt16:
75 varEnum = VarEnum.VT_UI2;
76 break;
77 case TypeCode.Int32:
78 varEnum = VarEnum.VT_I4;
79 break;
80 case TypeCode.UInt32:
81 varEnum = VarEnum.VT_UI4;
82 break;
83 case TypeCode.Int64:
84 varEnum = VarEnum.VT_I8;
85 break;
86 case TypeCode.UInt64:
87 varEnum = VarEnum.VT_UI8;
88 break;
89 case TypeCode.Single:
90 varEnum = VarEnum.VT_R4;
91 break;
92 case TypeCode.Double:
93 varEnum = VarEnum.VT_R8;
94 break;
95 case TypeCode.Char:
96 varEnum = (IsAnsi(dwFlags) ? ((VarEnum)253) : VarEnum.VT_UI2);
97 break;
98 case TypeCode.Boolean:
99 varEnum = (VarEnum)254;
100 break;
101 case TypeCode.Object:
102 if (elementType == typeof(IntPtr))
103 {
104 _ = IntPtr.Size;
105 varEnum = VarEnum.VT_I8;
106 break;
107 }
108 if (elementType == typeof(UIntPtr))
109 {
110 _ = IntPtr.Size;
111 varEnum = VarEnum.VT_UI8;
112 break;
113 }
114 goto default;
115 default:
117 }
118 int num = (int)varEnum;
119 if (IsBestFit(dwFlags))
120 {
121 num |= 0x10000;
122 }
123 if (IsThrowOn(dwFlags))
124 {
125 num |= 0x1000000;
126 }
128 System.Runtime.CompilerServices.Unsafe.SkipInit(out IntPtr result);
129 IntPtr pNativeHome = new IntPtr(&result);
130 MngdNativeArrayMarshaler.ConvertSpaceToNative(pvArrayMarshaler, ref pManagedHome, pNativeHome);
131 if (IsIn(dwFlags))
132 {
134 }
135 if (IsOut(dwFlags))
136 {
138 }
139 return result;
140 }
141
142 private unsafe static IntPtr ConvertStringToNative(string pManagedHome, int dwFlags)
143 {
144 IntPtr intPtr;
145 if (IsAnsi(dwFlags))
146 {
147 intPtr = CSTRMarshaler.ConvertToNative(dwFlags & 0xFFFF, pManagedHome, IntPtr.Zero);
148 }
149 else
150 {
151 int cb = (pManagedHome.Length + 1) * 2;
152 intPtr = Marshal.AllocCoTaskMem(cb);
153 Buffer.Memmove(ref *(char*)(void*)intPtr, ref pManagedHome.GetRawStringData(), (nuint)pManagedHome.Length + (nuint)1u);
154 }
155 return intPtr;
156 }
157
158 private unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags)
159 {
160 int capacity = pManagedHome.Capacity;
161 int length = pManagedHome.Length;
162 if (length > capacity)
163 {
165 }
166 IntPtr intPtr;
167 if (IsAnsi(dwFlags))
168 {
170 int num = checked(capacity * Marshal.SystemMaxDBCSCharSize + 4);
171 intPtr = Marshal.AllocCoTaskMem(num);
172 byte* ptr = (byte*)(void*)intPtr;
173 *(ptr + num - 3) = 0;
174 *(ptr + num - 2) = 0;
175 *(ptr + num - 1) = 0;
176 if (IsIn(dwFlags))
177 {
178 int num2 = Marshal.StringToAnsiString(pManagedHome.ToString(), ptr, num, IsBestFit(dwFlags), IsThrowOn(dwFlags));
179 }
180 if (IsOut(dwFlags))
181 {
182 backPropAction = BackPropAction.StringBuilderAnsi;
183 }
184 }
185 else
186 {
187 int num3 = checked(capacity * 2 + 4);
188 intPtr = Marshal.AllocCoTaskMem(num3);
189 byte* ptr2 = (byte*)(void*)intPtr;
190 *(ptr2 + num3 - 1) = 0;
191 *(ptr2 + num3 - 2) = 0;
192 if (IsIn(dwFlags))
193 {
194 pManagedHome.InternalCopy(intPtr, length);
195 int num4 = length * 2;
196 ptr2[num4] = 0;
197 (ptr2 + num4)[1] = 0;
198 }
199 if (IsOut(dwFlags))
200 {
201 backPropAction = BackPropAction.StringBuilderUnicode;
202 }
203 }
204 return intPtr;
205 }
206
207 private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags)
208 {
209 int cb = Marshal.SizeOfHelper(pManagedHome.GetType(), throwIfNotMarshalable: false);
210 IntPtr intPtr = Marshal.AllocCoTaskMem(cb);
211 if (IsIn(dwFlags))
212 {
213 StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte*)(void*)intPtr, ref cleanupWorkList);
214 }
215 if (IsOut(dwFlags))
216 {
218 }
219 layoutType = pManagedHome.GetType();
220 return intPtr;
221 }
222
223 internal IntPtr ConvertToNative(object pManagedHome, int dwFlags)
224 {
225 if (pManagedHome == null)
226 {
227 return IntPtr.Zero;
228 }
229 if (pManagedHome is ArrayWithOffset)
230 {
232 }
233 if (pManagedHome.GetType().IsArray)
234 {
235 return ConvertArrayToNative(pManagedHome, dwFlags);
236 }
237 if (pManagedHome is string pManagedHome2)
238 {
239 return ConvertStringToNative(pManagedHome2, dwFlags);
240 }
241 if (pManagedHome is StringBuilder pManagedHome3)
242 {
243 return ConvertStringBuilderToNative(pManagedHome3, dwFlags);
244 }
245 if (pManagedHome.GetType().IsLayoutSequential || pManagedHome.GetType().IsExplicitLayout)
246 {
247 return ConvertLayoutToNative(pManagedHome, dwFlags);
248 }
250 }
251
252 internal unsafe void ConvertToManaged(object pManagedHome, IntPtr pNativeHome)
253 {
254 switch (backPropAction)
255 {
256 case BackPropAction.Array:
257 MngdNativeArrayMarshaler.ConvertContentsToManaged(pvArrayMarshaler, ref pManagedHome, new IntPtr(&pNativeHome));
258 break;
259 case BackPropAction.Layout:
260 StubHelpers.FmtClassUpdateCLRInternal(pManagedHome, (byte*)(void*)pNativeHome);
261 break;
262 case BackPropAction.StringBuilderAnsi:
263 {
264 int newLength2 = ((!(pNativeHome == IntPtr.Zero)) ? string.strlen((byte*)(void*)pNativeHome) : 0);
265 ((StringBuilder)pManagedHome).ReplaceBufferAnsiInternal((sbyte*)(void*)pNativeHome, newLength2);
266 break;
267 }
268 case BackPropAction.StringBuilderUnicode:
269 {
270 int newLength = ((!(pNativeHome == IntPtr.Zero)) ? string.wcslen((char*)(void*)pNativeHome) : 0);
271 ((StringBuilder)pManagedHome).ReplaceBufferInternal((char*)(void*)pNativeHome, newLength);
272 break;
273 }
274 }
275 }
276
277 internal void ClearNative(IntPtr pNativeHome)
278 {
279 if (pNativeHome != IntPtr.Zero)
280 {
281 if (layoutType != null)
282 {
283 Marshal.DestroyStructure(pNativeHome, layoutType);
284 }
285 Marshal.FreeCoTaskMem(pNativeHome);
286 }
288 }
289}
static void Memmove(ref byte dest, ref byte src, nuint len)
Definition Buffer.cs:215
static unsafe int StringToAnsiString(string s, byte *buffer, int bufferLength, bool bestFit=false, bool throwOnUnmappableChar=false)
Definition Marshal.cs:1608
static void FreeCoTaskMem(IntPtr ptr)
Definition Marshal.cs:1712
static IntPtr AllocCoTaskMem(int cb)
Definition Marshal.cs:1702
static void DestroyStructure(IntPtr ptr, Type structuretype)
static int SizeOfHelper(Type t, bool throwIfNotMarshalable)
static readonly int SystemMaxDBCSCharSize
Definition Marshal.cs:19
static string Arg_MarshalAsAnyRestriction
Definition SR.cs:236
static string Arg_NDirectBadObject
Definition SR.cs:322
Definition SR.cs:7
static unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
static void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome)
static void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags, IntPtr pManagedMarshaler)
static void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome)
static void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome)
static void CheckStringLength(int length)
static unsafe void FmtClassUpdateNativeInternal(object obj, byte *pNative, ref CleanupWorkListElement pCleanupWorkList)
static unsafe void FmtClassUpdateCLRInternal(object obj, byte *pNative)
static void DestroyCleanupList(ref CleanupWorkListElement pCleanupWorkList)
override string ToString()
unsafe void InternalCopy(IntPtr dest, int charLen)
static void ThrowInvalidOperationException()
static TypeCode GetTypeCode(Type? type)
Definition Type.cs:919
TypeCode
Definition TypeCode.cs:4
static int Size
Definition IntPtr.cs:21
static readonly IntPtr Zero
Definition IntPtr.cs:18
unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags)
IntPtr ConvertToNative(object pManagedHome, int dwFlags)
unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags)
static bool IsAnsi(int dwFlags)
static unsafe IntPtr ConvertStringToNative(string pManagedHome, int dwFlags)
static bool IsThrowOn(int dwFlags)
AsAnyMarshaler(IntPtr pvArrayMarshaler)
unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags)
void ClearNative(IntPtr pNativeHome)
static bool IsIn(int dwFlags)
static bool IsOut(int dwFlags)
static bool IsBestFit(int dwFlags)
unsafe void ConvertToManaged(object pManagedHome, IntPtr pNativeHome)
CleanupWorkListElement cleanupWorkList