1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // |
5 | // File: CustomMarshalerInfo.h |
6 | // |
7 | |
8 | // |
9 | // Custom marshaler information used when marshaling |
10 | // a parameter with a custom marshaler. |
11 | // |
12 | |
13 | |
14 | #ifndef _CUSTOMMARSHALERINFO_H_ |
15 | #define _CUSTOMMARSHALERINFO_H_ |
16 | |
17 | |
18 | #include "vars.hpp" |
19 | #include "slist.h" |
20 | |
21 | |
22 | // This enumeration is used to retrieve a method desc from CustomMarshalerInfo::GetCustomMarshalerMD(). |
23 | enum EnumCustomMarshalerMethods |
24 | { |
25 | CustomMarshalerMethods_MarshalNativeToManaged = 0, |
26 | CustomMarshalerMethods_MarshalManagedToNative, |
27 | CustomMarshalerMethods_CleanUpNativeData, |
28 | CustomMarshalerMethods_CleanUpManagedData, |
29 | CustomMarshalerMethods_GetNativeDataSize, |
30 | CustomMarshalerMethods_GetInstance, |
31 | CustomMarshalerMethods_LastMember |
32 | }; |
33 | |
34 | |
35 | class CustomMarshalerInfo |
36 | { |
37 | public: |
38 | // Constructor and destructor. |
39 | CustomMarshalerInfo(BaseDomain* pDomain, TypeHandle hndCustomMarshalerType, TypeHandle hndManagedType, LPCUTF8 strCookie, DWORD cCookieStrBytes); |
40 | ~CustomMarshalerInfo(); |
41 | |
42 | // CustomMarshalerInfo's are always allocated on the loader heap so we need to redefine |
43 | // the new and delete operators to ensure this. |
44 | void* operator new(size_t size, LoaderHeap* pHeap); |
45 | void operator delete(void* pMem); |
46 | |
47 | // Helpers used to invoke the different methods in the ICustomMarshaler interface. |
48 | OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); |
49 | void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); |
50 | void InvokeCleanUpNativeMeth(void* pNative); |
51 | void InvokeCleanUpManagedMeth(OBJECTREF MngObj); |
52 | |
53 | // Accessors. |
54 | int GetNativeSize() |
55 | { |
56 | LIMITED_METHOD_CONTRACT; |
57 | return m_NativeSize; |
58 | } |
59 | |
60 | int GetManagedSize() |
61 | { |
62 | WRAPPER_NO_CONTRACT; |
63 | return m_hndManagedType.GetSize(); |
64 | } |
65 | |
66 | TypeHandle GetManagedType() |
67 | { |
68 | LIMITED_METHOD_CONTRACT; |
69 | return m_hndManagedType; |
70 | } |
71 | |
72 | BOOL IsDataByValue() |
73 | { |
74 | LIMITED_METHOD_CONTRACT; |
75 | return m_bDataIsByValue; |
76 | } |
77 | |
78 | OBJECTHANDLE GetCustomMarshaler() |
79 | { |
80 | LIMITED_METHOD_CONTRACT; |
81 | return m_hndCustomMarshaler; |
82 | } |
83 | |
84 | TypeHandle GetCustomMarshalerType() |
85 | { |
86 | CONTRACTL |
87 | { |
88 | NOTHROW; |
89 | GC_NOTRIGGER; |
90 | SO_TOLERANT; |
91 | MODE_COOPERATIVE; |
92 | } |
93 | CONTRACTL_END; |
94 | return ObjectFromHandle(m_hndCustomMarshaler)->GetTypeHandle(); |
95 | } |
96 | |
97 | // Helper function to retrieve a custom marshaler method desc. |
98 | static MethodDesc* GetCustomMarshalerMD(EnumCustomMarshalerMethods Method, TypeHandle hndCustomMarshalertype); |
99 | |
100 | // Link used to contain this CM info in a linked list. |
101 | SLink m_Link; |
102 | |
103 | private: |
104 | int m_NativeSize; |
105 | TypeHandle m_hndManagedType; |
106 | OBJECTHANDLE m_hndCustomMarshaler; |
107 | MethodDesc* m_pMarshalNativeToManagedMD; |
108 | MethodDesc* m_pMarshalManagedToNativeMD; |
109 | MethodDesc* m_pCleanUpNativeDataMD; |
110 | MethodDesc* m_pCleanUpManagedDataMD; |
111 | BOOL m_bDataIsByValue; |
112 | }; |
113 | |
114 | |
115 | typedef SList<CustomMarshalerInfo, true> CMINFOLIST; |
116 | |
117 | |
118 | class EECMHelperHashtableKey |
119 | { |
120 | public: |
121 | EECMHelperHashtableKey(DWORD cMarshalerTypeNameBytes, LPCSTR strMarshalerTypeName, DWORD cCookieStrBytes, LPCSTR strCookie, Instantiation instantiation) |
122 | : m_cMarshalerTypeNameBytes(cMarshalerTypeNameBytes) |
123 | , m_strMarshalerTypeName(strMarshalerTypeName) |
124 | , m_cCookieStrBytes(cCookieStrBytes) |
125 | , m_strCookie(strCookie) |
126 | , m_Instantiation(instantiation) |
127 | { |
128 | LIMITED_METHOD_CONTRACT; |
129 | } |
130 | |
131 | inline DWORD GetMarshalerTypeNameByteCount() const |
132 | { |
133 | LIMITED_METHOD_CONTRACT; |
134 | return m_cMarshalerTypeNameBytes; |
135 | } |
136 | inline LPCSTR GetMarshalerTypeName() const |
137 | { |
138 | LIMITED_METHOD_CONTRACT; |
139 | return m_strMarshalerTypeName; |
140 | } |
141 | inline LPCSTR GetCookieString() const |
142 | { |
143 | LIMITED_METHOD_CONTRACT; |
144 | return m_strCookie; |
145 | } |
146 | inline ULONG GetCookieStringByteCount() const |
147 | { |
148 | LIMITED_METHOD_CONTRACT; |
149 | return m_cCookieStrBytes; |
150 | } |
151 | inline Instantiation GetMarshalerInstantiation() const |
152 | { |
153 | LIMITED_METHOD_CONTRACT; |
154 | return m_Instantiation; |
155 | } |
156 | |
157 | DWORD m_cMarshalerTypeNameBytes; |
158 | LPCSTR m_strMarshalerTypeName; |
159 | DWORD m_cCookieStrBytes; |
160 | LPCSTR m_strCookie; |
161 | Instantiation m_Instantiation; |
162 | }; |
163 | |
164 | |
165 | class EECMHelperHashtableHelper |
166 | { |
167 | public: |
168 | static EEHashEntry_t* AllocateEntry(EECMHelperHashtableKey* pKey, BOOL bDeepCopy, AllocationHeap Heap); |
169 | static void DeleteEntry(EEHashEntry_t* pEntry, AllocationHeap Heap); |
170 | static BOOL CompareKeys(EEHashEntry_t* pEntry, EECMHelperHashtableKey* pKey); |
171 | static DWORD Hash(EECMHelperHashtableKey* pKey); |
172 | }; |
173 | |
174 | |
175 | typedef EEHashTable<EECMHelperHashtableKey*, EECMHelperHashtableHelper, TRUE> EECMHelperHashTable; |
176 | |
177 | |
178 | class CustomMarshalerHelper |
179 | { |
180 | public: |
181 | // Helpers used to invoke the different methods in the ICustomMarshaler interface. |
182 | OBJECTREF InvokeMarshalNativeToManagedMeth(void* pNative); |
183 | void* InvokeMarshalManagedToNativeMeth(OBJECTREF MngObj); |
184 | void InvokeCleanUpNativeMeth(void* pNative); |
185 | void InvokeCleanUpManagedMeth(OBJECTREF MngObj); |
186 | |
187 | // Accessors. |
188 | int GetNativeSize() |
189 | { |
190 | WRAPPER_NO_CONTRACT; |
191 | return GetCustomMarshalerInfo()->GetNativeSize(); |
192 | } |
193 | |
194 | int GetManagedSize() |
195 | { |
196 | WRAPPER_NO_CONTRACT; |
197 | return GetCustomMarshalerInfo()->GetManagedSize(); |
198 | } |
199 | |
200 | TypeHandle GetManagedType() |
201 | { |
202 | WRAPPER_NO_CONTRACT; |
203 | return GetCustomMarshalerInfo()->GetManagedType(); |
204 | } |
205 | |
206 | BOOL IsDataByValue() |
207 | { |
208 | WRAPPER_NO_CONTRACT; |
209 | return GetCustomMarshalerInfo()->IsDataByValue(); |
210 | } |
211 | |
212 | // Helper function to retrieve the custom marshaler object. |
213 | virtual CustomMarshalerInfo* GetCustomMarshalerInfo() = 0; |
214 | |
215 | protected: |
216 | ~CustomMarshalerHelper( void ) |
217 | { |
218 | LIMITED_METHOD_CONTRACT; |
219 | } |
220 | }; |
221 | |
222 | |
223 | class NonSharedCustomMarshalerHelper : public CustomMarshalerHelper |
224 | { |
225 | public: |
226 | // Constructor. |
227 | NonSharedCustomMarshalerHelper(CustomMarshalerInfo* pCMInfo) : m_pCMInfo(pCMInfo) |
228 | { |
229 | WRAPPER_NO_CONTRACT; |
230 | } |
231 | |
232 | // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine |
233 | // the new and delete operators to ensure this. |
234 | void *operator new(size_t size, LoaderHeap *pHeap); |
235 | void operator delete(void* pMem); |
236 | |
237 | protected: |
238 | // Helper function to retrieve the custom marshaler object. |
239 | virtual CustomMarshalerInfo* GetCustomMarshalerInfo() |
240 | { |
241 | LIMITED_METHOD_CONTRACT; |
242 | return m_pCMInfo; |
243 | } |
244 | |
245 | private: |
246 | CustomMarshalerInfo* m_pCMInfo; |
247 | }; |
248 | |
249 | |
250 | class SharedCustomMarshalerHelper : public CustomMarshalerHelper |
251 | { |
252 | public: |
253 | // Constructor. |
254 | SharedCustomMarshalerHelper(Assembly* pAssembly, TypeHandle hndManagedType, LPCUTF8 strMarshalerTypeName, DWORD cMarshalerTypeNameBytes, LPCUTF8 strCookie, DWORD cCookieStrBytes); |
255 | |
256 | // CustomMarshalerHelpers's are always allocated on the loader heap so we need to redefine |
257 | // the new and delete operators to ensure this. |
258 | void* operator new(size_t size, LoaderHeap* pHeap); |
259 | void operator delete(void* pMem); |
260 | |
261 | // Accessors. |
262 | inline Assembly* GetAssembly() |
263 | { |
264 | LIMITED_METHOD_CONTRACT; |
265 | return m_pAssembly; |
266 | } |
267 | |
268 | inline TypeHandle GetManagedType() |
269 | { |
270 | LIMITED_METHOD_CONTRACT; |
271 | return m_hndManagedType; |
272 | } |
273 | |
274 | inline DWORD GetMarshalerTypeNameByteCount() |
275 | { |
276 | LIMITED_METHOD_CONTRACT; |
277 | return m_cMarshalerTypeNameBytes; |
278 | } |
279 | |
280 | inline LPCSTR GetMarshalerTypeName() |
281 | { |
282 | LIMITED_METHOD_CONTRACT; |
283 | return m_strMarshalerTypeName; |
284 | } |
285 | |
286 | inline LPCSTR GetCookieString() |
287 | { |
288 | LIMITED_METHOD_CONTRACT; |
289 | return m_strCookie; |
290 | } |
291 | |
292 | inline ULONG GetCookieStringByteCount() |
293 | { |
294 | LIMITED_METHOD_CONTRACT; |
295 | return m_cCookieStrBytes; |
296 | } |
297 | |
298 | protected: |
299 | // Helper function to retrieve the custom marshaler object. |
300 | virtual CustomMarshalerInfo* GetCustomMarshalerInfo(); |
301 | |
302 | private: |
303 | Assembly* m_pAssembly; |
304 | TypeHandle m_hndManagedType; |
305 | DWORD m_cMarshalerTypeNameBytes; |
306 | LPCUTF8 m_strMarshalerTypeName; |
307 | DWORD m_cCookieStrBytes; |
308 | LPCUTF8 m_strCookie; |
309 | }; |
310 | |
311 | |
312 | #endif // _CUSTOMMARSHALERINFO_H_ |
313 | |