Add PInvoke/Array tests (#19266)
[platform/upstream/coreclr.git] / tests / src / Interop / PInvoke / Array / MarshalArray.h
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 #pragma once 
6 #include <stdio.h>
7 #include <stdlib.h> // required by itoa
8 #include <iostream>
9 #include "platformdefines.h"
10
11 //////////////////////////////////////////////////////////////////////////////
12 // Macro definitions
13 //////////////////////////////////////////////////////////////////////////////
14 #define ARRAY_SIZE 100
15 #define ROWS 2
16 #define COLUMNS 3
17
18 #define COUNTOF(__arr) sizeof(__arr) / sizeof(__arr[0])
19 #define ELEM_PER_ROW_2D(__arr) (&(__arr[1][0]) - &(__arr[0][0]))
20 #define ROWS_2D(__arr) sizeof(__arr) / (ELEM_PER_ROW_2D(__arr) * sizeof(__arr[0][0]))
21
22 #define ENTERFUNC() printf("============ [%s]\t ============\n", __FUNCTION__)
23
24 #define CHECK_PARAM_NOT_EMPTY(__p) \
25     ENTERFUNC(); \
26     if ( (__p) == NULL ) \
27     { \
28     printf("[%s] Error: parameter actual is NULL\n", __FUNCTION__); \
29     return false; \
30     }
31
32 #define CHECK_PARAM_EMPTY(__p) \
33     ENTERFUNC(); \
34     if ( __p != NULL ) \
35     { \
36     printf("[%s] Error: parameter ppActual is not NULL\n", __FUNCTION__); \
37     return false; \
38     }
39
40 #define VERIFY_ERROR(__expect, __actual) \
41     std::cout << '[' << __FUNCSIG__ << "] EXPECT: " << (__expect) << ", ACTUAL: " << (__actual) << std::endl
42
43 #define TRACE(__msg) \
44     std::cout << __msg << std::endl
45
46 #define VERIFY_ERROR_MSG(__msg, __expect, __actual) \
47     printf("["##__FUNCSIG__##"] "##__msg, (__expect), (__actual))
48
49 //////////////////////////////////////////////////////////////////////////////
50 // Verify helper methods
51 //////////////////////////////////////////////////////////////////////////////
52
53 template<typename T>
54 bool IsObjectEquals(const T& o1, const T& o2)
55 {
56     return o1 == o2;
57 }
58
59 template<>
60 bool IsObjectEquals(const LPSTR& o1, const LPSTR& o2)
61 {
62     if (o1 == NULL)
63     {
64         return (o2 == NULL);
65     }
66     else if (o2 == NULL)
67     {
68         return false;
69     }
70
71     size_t cLen1 = strlen(o1);
72     size_t cLen2 = strlen(o2);
73
74     if (cLen1 != cLen2 )
75     {
76         printf("Not equals in %s\n",__FUNCTION__);
77         return false;
78     }
79
80     return strncmp(o1, o2, cLen1) == 0;
81 }
82
83 template<>
84 bool IsObjectEquals(const LPCSTR& o1, const LPCSTR& o2)
85 {
86     if (o1 == NULL)
87     {
88         return (o2 == NULL);
89     }
90     else if (o2 == NULL)
91     {
92         return false;
93     }
94
95     size_t cLen1 = strlen(o1);
96     size_t cLen2 = strlen(o2);
97
98     if (cLen1 != cLen2 )
99     {
100         printf("Not equals in %s\n",__FUNCTION__);
101         return false;
102     }
103
104     return strncmp(o1, o2, cLen1) == 0;
105 }
106
107 #ifdef _WIN32
108 template<>
109 bool IsObjectEquals(const BSTR& o1, const BSTR& o2)
110 {
111     if (o1 == NULL)
112     {
113         return (o2 == NULL);
114     }
115     else if (o2 == NULL)
116     {
117         return false;
118     }
119
120     UINT uLen1 = SysStringLen(o1);
121     UINT uLen2 = SysStringLen(o2);
122
123     if (uLen1 != uLen2 )
124     {
125         printf("Not equals in %s\n",__FUNCTION__);
126         return false;
127     }
128
129     return memcmp(o1, o2, uLen1 * sizeof(*o1)) == 0;
130 }
131 #endif
132
133 //////////////////////////////////////////////////////////////////////////////
134 // Test Data Structure
135 //////////////////////////////////////////////////////////////////////////////
136
137 LPSTR ToString(int i)
138 {
139     CHAR *pBuffer = (CHAR *)CoreClrAlloc(10 * sizeof(CHAR)); // 10 is enough for our case
140     _itoa_s(i, pBuffer, 10, 10);
141
142     return pBuffer;
143 }
144
145 #ifdef _WIN32
146 BSTR ToBSTR(int i)
147 {
148     BSTR bstrRet = NULL;
149     VarBstrFromI4(i, 0, 0, &bstrRet);
150
151     return bstrRet;
152 }
153 #endif
154
155 struct TestStruct
156 {
157     inline TestStruct()
158         : x(0)
159         , d(0)
160         , l(0)
161         , str(NULL)
162     {
163     }
164
165     inline TestStruct(int v)
166         : x(v)
167         , d(v)
168         , l(v)
169     {
170         str = ToString(v);
171     }
172
173     int x;
174     double d;
175     LONG64 l;
176     LPSTR str;
177
178     inline bool operator==(const TestStruct &other) const
179     {
180         return IsObjectEquals(x, other.x) &&
181             IsObjectEquals(d, other.d) &&
182             IsObjectEquals(l, other.l) &&
183             IsObjectEquals(str, other.str);
184     }
185 };
186
187 typedef struct S2
188 {
189     INT i32;
190     UINT ui32;
191     SHORT s1;
192     WORD us1;
193     BYTE b;
194     CHAR sb;
195     SHORT i16;
196     WORD ui16;
197     LONG64 i64;
198     ULONG64 ui64;
199     FLOAT sgl;
200     DOUBLE d;
201 }S2;
202
203 //////////////////////////////////////////////////////////////////////////////
204 // Other methods
205 //////////////////////////////////////////////////////////////////////////////
206
207 #ifdef _WIN32
208 // Do not output variants, and suppress the boring template compile warning
209 std::ostream &operator<<(std::ostream &ostr, VARIANT &v)
210 {
211     return ostr;
212 }
213
214 std::ostream &operator<<(std::ostream &ostr, BSTR &b)
215 {
216     std::wcout << b;
217     return ostr;
218 }
219 #endif
220
221 //////////////////////////////////method for struct S2////////////////////////////////////////////////
222 void InstanceS2(S2 * pREC, int i32,UINT ui32,SHORT s1,WORD us1,BYTE b,CHAR sb,SHORT i16,WORD ui16,
223                 LONG64 i64,ULONG64 ui64,FLOAT sgl,DOUBLE d)
224 {
225     pREC->i32 = i32;
226     pREC->ui32 = ui32;
227     pREC->s1 = s1;
228     pREC->us1 = us1;
229     pREC->b = b;
230     pREC->sb = sb;
231     pREC->i16 = i16;
232     pREC->ui16 = ui16;
233     pREC->i64 = i64;
234     pREC->ui64 = ui64;
235     pREC->sgl = sgl;
236     pREC->d = d;
237 }
238
239 bool ValidateS2LPArray(S2 * pREC, S2 * pRECCorrect, int numArrElement)
240 {
241     for(int i = 0; i<numArrElement;i++)
242     {
243         if(pREC[i].i32 != pRECCorrect[i].i32)
244         {
245             printf("\t The field of int is not the expected!");
246             printf("\t\tpREC[%d].i32 = %d\n", i, pREC[i].i32);
247             printf("\t\tpRECCorrect[%d].i32 = %d\n", i, pRECCorrect[i].i32);
248             return false;
249         }
250         else if(pREC[i].ui32 != pRECCorrect[i].ui32)
251         {
252             printf("\t The field of UInt32 is not the expected!");
253             printf("\t\tpREC[%d].ui32 = %d\n", i, pREC[i].ui32);
254             printf("\t\tpRECCorrect[%d].ui32 = %u\n", i, pRECCorrect[i].ui32);
255             return false;
256         }
257         else if(pREC[i].s1 != pRECCorrect[i].s1)
258         {
259             printf("\t The field of short is not the expected!");
260             printf("\t\tpREC[%d].s1 = %d\n", i, pREC[i].s1);
261             printf("\t\tpRECCorrect[%d].s1 = %d\n", i, pRECCorrect[i].s1);
262             return false;
263         }
264         else if(pREC[i].us1 != pRECCorrect[i].us1)
265         {
266             printf("\t The field of ushort is not the expected!");
267             printf("\t\tpREC[%d].us1 = %d\n", i, pREC[i].us1);
268             printf("\t\tpRECCorrect[%d].us1 = %u\n", i, pRECCorrect[i].us1);
269             return false;
270         }
271         else if(pREC[i].b != pRECCorrect[i].b)
272         {
273             printf("\t The field of byte is not the expected!");
274             printf("\t\tpREC[%d].b = %d\n", i, pREC[i].b);
275             printf("\t\tpRECCorrect[%d].b = %d\n", i, pRECCorrect[i].b);
276             return false;
277         }
278         else if(pREC[i].sb != pRECCorrect[i].sb)
279         {
280             printf("\t The field of sbyte is not the expected!");
281             printf("\t\tpREC[%d].sb = %d\n", i, pREC[i].sb);
282             printf("\t\tpRECCorrect[%d].sb = %u\n", i, pRECCorrect[i].sb);
283             return false;
284         }
285         else if(pREC[i].i16 != pRECCorrect[i].i16)
286         {
287             printf("\t The field of Int16 is not the expected!");
288             printf("\t\tpREC[%d].i16 = %d\n", i, pREC[i].i16);
289             printf("\t\tpRECCorrect[%d].i16 = %d\n", i, pRECCorrect[i].i16);
290             return false;
291         }
292         else if(pREC[i].ui16 != pRECCorrect[i].ui16)
293         {
294             printf("\t The field of UInt16 is not the expected!");
295             printf("\t\tpREC[%d].ui16 = %d\n", i, pREC[i].ui16);
296             printf("\t\tpRECCorrect[%d].ui16 = %u\n", i, pRECCorrect[i].ui16);
297             return false;
298         }
299         else if(pREC[i].i64 != pRECCorrect[i].i64)
300         {
301             printf("\t The field of Int64 is not the expected!");
302             printf("\t\tpREC[%d].i64 = %lld\n", i, pREC[i].i64);
303             printf("\t\tpRECCorrect[%d].i64 = %lld\n", i, pRECCorrect[i].i64);
304             return false;
305         }
306         else if(pREC[i].ui64 != pRECCorrect[i].ui64)
307         {
308             printf("\t The field of UInt64 is not the expected!");
309             printf("\t\tpREC[%d].ui64 = %llu\n", i, pREC[i].ui64);
310             printf("\t\tpRECCorrect[%d].ui64 = %llu\n", i, pRECCorrect[i].ui64);
311             return false;
312         }
313         else if(pREC[i].sgl != pRECCorrect[i].sgl)
314         {
315             printf("\t The field of single is not the expected!");
316             printf("\t\tpREC[%d].sgl = %f\n", i, pREC[i].sgl);
317             printf("\t\tpRECCorrect[%d].sgl = %f\n", i, pRECCorrect[i].sgl);
318             return false;
319         }
320         else if(pREC[i].d != pRECCorrect[i].d)
321         {
322             printf("\t The field of double is not the expected!");
323             printf("\t\tpREC[%d].d = %f\n", i, pREC[i].d);
324             printf("\t\tpRECCorrect[%d].d = %f\n", i, pRECCorrect[i].d);
325             return false;
326         }
327     }
328     return true;
329 }