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#include <iostream>
6#include <xplatform.h>
7#include "platformdefines.h"
8
9DECIMAL g_DECIMAL_MaxValue = { 0, {{ 0, 0 }}, 0xffffffff, {{0xffffffff, 0xffffffff}} };
10DECIMAL g_DECIMAL_MinValue = { 0, {{ 0, DECIMAL_NEG }}, 0xffffffff, {{0xffffffff, 0xffffffff }}};
11DECIMAL g_DECIMAL_Zero = { 0 };
12
13CY g_CY_MaxValue = { {0xffffffff, 0x7fffffff} };
14CY g_CY_MinValue = { {(LONG)0x00000000, (LONG)0x80000000} };
15CY g_CY_Zero = { {0} };
16
17typedef struct _Stru_Seq_DecAsStructAsFld
18{
19 int number;
20 DECIMAL dec;
21} Stru_Seq_DecAsStructAsFld;
22
23typedef struct _Stru_Exp_DecAsCYAsFld
24{
25 WCHAR wc;
26 CY cy;
27} Stru_Exp_DecAsCYAsFld;
28
29typedef struct _Stru_Seq_DecAsLPStructAsFld
30{
31 DOUBLE dblVal;
32 CHAR cVal;
33 DECIMAL* dec;
34} Stru_Seq_DecAsLPStructAsFld;
35
36// As Struct
37typedef BOOL (STDMETHODCALLTYPE *Fp_Dec)(DECIMAL*);
38typedef DECIMAL (STDMETHODCALLTYPE *Fp_RetDec)();
39typedef BOOL (STDMETHODCALLTYPE *Fp_Stru_Seq_DecAsStructAsFld)(Stru_Seq_DecAsStructAsFld*);
40// As CY
41typedef BOOL (STDMETHODCALLTYPE *Fp_CY)(CY*);
42typedef CY (STDMETHODCALLTYPE *Fp_RetCY)();
43typedef BOOL (STDMETHODCALLTYPE *Fp_Stru_Exp_DecAsCYAsFld)(Stru_Exp_DecAsCYAsFld*);
44// As LPStruct
45typedef BOOL (STDMETHODCALLTYPE *Fp_DecAsLPStruct)(DECIMAL**);
46typedef DECIMAL* (STDMETHODCALLTYPE *Fp_RetDecAsLPStruct)();
47typedef BOOL (STDMETHODCALLTYPE *Fp_Stru_Seq_DecAsLPStructAsFld)(Stru_Seq_DecAsLPStructAsFld*);
48
49void DecDisplay(const DECIMAL& dec)
50{
51 std::cout << "\twReserved" << "\t\t" << dec.wReserved << "\n"
52 << "\tscale" << "\t\t" << dec.scale << "\n"
53 << "\tsign" << "\t\t" << dec.sign << "\n"
54 << "\tsignscale" << "\t\t" << dec.signscale << "\n"
55 << "\tHi32" << "\t\t" << dec.Hi32 << "\n"
56 << "\tLo32" << "\t\t" << dec.Lo32 << "\n"
57 << "\tMid32" << "\t\t" << dec.Mid32 << "\n"
58 << "\tLo64" << "\t\t" << dec.Lo64 << std::endl;
59}
60
61template<typename T>
62bool operator==(const T& t1, const T& t2)
63{
64 return 0 == memcmp((void*)&t1, (void*)&t2, sizeof(T));
65}
66
67template<typename T>
68bool Equals(LPCSTR err_id, T expected, T actual)
69{
70 if(expected == actual)
71 return true;
72 else
73 {
74 std::cout << "\t#Native Side Err# -- " << err_id
75 << "\n\tExpected = " << expected << std::endl;
76 std::wcout << "\tActual is = " << actual << std::endl;
77
78 return false;
79 }
80}
81
82bool IntEqualsToExpected(LPCSTR err_id, int number, int expected)
83{
84
85 if(number == expected)
86 {
87 return true;
88 }
89 else
90 {
91 std::wcout << "\t#Native Side Err# -- " << err_id
92 << "\n\tnumber Expected = " << expected << std::endl;
93
94 std::wcout << "\tnumber Actual is = " << number << std::endl;
95
96 return false;
97 }
98}
99bool DecEqualsToExpected(LPCSTR err_id, const DECIMAL& expected, const DECIMAL& actual)
100{
101 if(expected == actual)
102 return true;
103 else
104 {
105 std::cout << "\t#Native Side Err # -- " << err_id
106 << "DECIMAL Expected is :" << std::endl;
107 DecDisplay(expected);
108
109 std::cout << "\t" << "____________________________________" << std::endl;
110
111 std::cout << "\tDECIMAL Actual is :" << std::endl;
112 DecDisplay(actual);
113
114 return false;
115 }
116}
117
118bool CYEqualsToExpected(LPCSTR err_id, const CY& expected, const CY& actual)
119{
120 if(expected == actual)
121 return true;
122 else
123 {
124 std::cout << "\t#Native Side Err# -- " << err_id
125 << "\n\tCY Expected is :" << "Hi = " << expected.Hi
126 << "Lo = " << expected.Lo << std::endl;
127
128 std::cout << "\tCY Actual is :" << "Hi = " << actual.Hi
129 << "Lo = " << actual.Lo << std::endl;
130
131 return false;
132 }
133}
134
135template<typename T>
136T* RetSpecificTypeInstancePtr(T tVal)
137{
138 T* lpT = (T*)CoreClrAlloc(sizeof(T));
139 *lpT = tVal;
140 return lpT;
141}
142
143// As Struct
144extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByInOutRef(Fp_Dec fp)
145{
146 DECIMAL* lpDec = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue);
147
148 if((*fp)(lpDec))
149 return DecEqualsToExpected("001.01", g_DECIMAL_MinValue, *lpDec);
150 else
151 return false;
152}
153
154extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByOutRef(Fp_Dec fp)
155{
156 DECIMAL* lpDec = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue);
157
158 if((*fp)(lpDec))
159 return DecEqualsToExpected("001.02", g_DECIMAL_Zero, *lpDec);
160 else
161 return false;
162}
163
164extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_DecRet(Fp_RetDec fp)
165{
166 return DecEqualsToExpected("001.03", g_DECIMAL_MinValue, (*fp)());
167}
168
169extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeStru_Seq_DecAsStructAsFldByInOutRef(Fp_Stru_Seq_DecAsStructAsFld fp)
170{
171 Stru_Seq_DecAsStructAsFld s = { 1, g_DECIMAL_MaxValue };
172
173 if((*fp)(&s))
174 return DecEqualsToExpected("001.04", g_DECIMAL_MinValue, s.dec) && IntEqualsToExpected("001.05", s.number, 2);
175 else
176 return false;
177}
178
179// As CY
180extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeCYByInOutRef(Fp_CY fp)
181{
182 CY* lpCy = RetSpecificTypeInstancePtr(g_CY_MaxValue);
183
184 if((*fp)(lpCy))
185 return CYEqualsToExpected("002.01", g_CY_MinValue, *lpCy);
186 else
187 return false;
188}
189
190extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeCYByOutRef(Fp_CY fp)
191{
192 CY* lpCy = RetSpecificTypeInstancePtr(g_CY_MaxValue);
193
194 if((*fp)(lpCy))
195 return CYEqualsToExpected("002.02", g_CY_Zero, *lpCy);
196 else
197 return false;
198}
199
200extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_CYRet(Fp_RetCY fp)
201{
202 return CYEqualsToExpected("002.03", g_CY_MinValue, (*fp)());
203}
204
205extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeStru_Exp_DecAsCYAsFldByOutRef(Fp_Stru_Exp_DecAsCYAsFld fp)
206{
207 Stru_Exp_DecAsCYAsFld s = { 0 };
208
209 if((*fp)(&s))
210 return CYEqualsToExpected("002.04", g_CY_MaxValue, s.cy) && Equals("002.05", W('C'), s.wc);
211 else
212 return false;
213}
214
215// As LPStrcut
216extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByInOutRefAsLPStruct(Fp_DecAsLPStruct fp)
217{
218 DECIMAL* lpDec = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue);
219 DECIMAL** lppDec = &lpDec;
220
221 if((*fp)(lppDec))
222 return DecEqualsToExpected("003.01", g_DECIMAL_MinValue, **lppDec);
223 else
224 return false;
225}
226
227extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByOutRefAsLPStruct(Fp_DecAsLPStruct fp)
228{
229 DECIMAL* lpDecAsLPStruct = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue);
230 DECIMAL** lppDecAsLPStruct = &lpDecAsLPStruct;
231
232 if((*fp)(lppDecAsLPStruct))
233 return DecEqualsToExpected("003.02", g_DECIMAL_Zero, **lppDecAsLPStruct);
234 else
235 return false;
236}
237
238//************** ReverseCall Return Int From Net **************//
239typedef int (*Fp_RetInt)();
240extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_IntRet(Fp_RetInt fp)
241{
242 return 0x12345678 == (*fp)();
243}
244