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 | } |
330 | |