Fixing bug for return value from callback in C++ (sendReturnObj is called twice)...
[iot2.git] / iotjava / iotrmi / C++ / sample / TestClass_Stub.hpp
1 #ifndef _TESTCLASS_STUB_HPP__
2 #define _TESTCLASS_STUB_HPP__
3
4 #include <iostream>
5 #include <thread>
6 #include "../IoTRMICall.hpp"
7 #include "../IoTRMIObject.hpp"
8 #include "TestClassInterface.hpp"
9 #include "CallBack_CBSkeleton.hpp"
10 #include "StructC.hpp"
11
12 using namespace std;
13
14 class TestClass_Stub : public TestClassInterface {
15         public:
16                 TestClass_Stub();
17                 TestClass_Stub(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports);
18                 ~TestClass_Stub();
19
20                 void                            setA(int _int);
21                 void                            setB(float _float);
22                 void                            setC(string _string);
23                 string                          sumArray(vector<string> newA);
24                 //int64_t                               sumArray(vector<int> newA);
25                 int                                     setAndGetA(int newA);
26                 int                                     setACAndGetA(string newC, int newA);
27                 void                            registerCallback(CallBackInterface* _cb);
28                 void                            registerCallback(vector<CallBackInterface*>_cb);
29                 int                                     callBack();
30                 void                            handleStruct(vector<data> vecData);
31                 void                            ____init_CallBack();    // thread
32                 void                            ____registerCallBack(); // tell the other side that we are ready
33
34                 const static int        size = 12;
35                 const static string methodSignatures[size];
36
37         private:                
38                 int                                                     intA;
39                 float                                           floatB;
40                 string                                          stringC;
41                 //CallBackInterface                     cb;
42                 IoTRMICall                                      *rmiCall;
43                 IoTRMIObject                            *rmiObj;
44                 string                                          address;
45                 vector<int>                                     ports;
46                 vector<CallBackInterface*>      vecCBObj;
47
48                 int             objectId = 0;   // Default value is 0
49                 static int      objIdCnt;
50 };
51
52
53 int TestClass_Stub::objIdCnt = 0;
54
55
56 const string TestClass_Stub::methodSignatures[TestClass_Stub::size] = {
57         "voidsetA(int)",
58         "voidsetB(float)",
59         "voidsetC(string)",
60         "sumArray(string[])",
61         //"sumArray(int[])",
62         "intsetAndGetA(int)",
63         "intsetACAndGetA(string,int)",
64         "intcallBack()",
65         "voidregisterCallBack(CallBackInterface)",
66         "voidregisterCallBack(CallBackInterface[])",
67         "registercallback",
68         "handleStruct(StructJ[])",
69         "structsize"
70 };
71
72
73 TestClass_Stub::TestClass_Stub() {
74
75         address = "";
76         rmiCall = NULL;
77 }
78
79
80 TestClass_Stub::TestClass_Stub(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports) {
81
82         address = _address;
83         rmiCall = new IoTRMICall(_port, _address, _rev, _bResult, methodSignatures, size);
84         ports = _ports;
85         // Start thread
86         thread th1 (&TestClass_Stub::____init_CallBack, this);
87         th1.detach();
88         //th1.join();
89         ____registerCallBack();
90 }
91
92
93 TestClass_Stub::~TestClass_Stub() {
94
95         if (rmiCall != NULL) {
96                 delete rmiCall;
97                 rmiCall = NULL;
98         }
99         if (rmiObj != NULL) {
100                 delete rmiObj;
101                 rmiObj = NULL;
102         }
103         for(CallBackInterface* cb : vecCBObj) {
104                 delete cb;
105                 cb = NULL;
106         }
107 }
108
109
110 // Callback handler thread
111 void TestClass_Stub::____init_CallBack() {
112
113         bool bResult = false;
114         rmiObj = new IoTRMIObject(ports[0], &bResult, CallBack_CBSkeleton::methodSignatures, CallBack_CBSkeleton::size);
115         while (true) {
116                 char* method = rmiObj->getMethodBytes();
117                 int objId = IoTRMIObject::getObjectId(method);
118                 if (objId < vecCBObj.size()) {  // Check if still within range
119                         CallBack_CBSkeleton* skel = 
120                                 dynamic_cast<CallBack_CBSkeleton*> (vecCBObj.at(objId));
121                         skel->invokeMethod(rmiObj);
122                 } else {
123                         string error = "TestClass_Stub: Illegal object Id: " + to_string(objId);
124                         throw error;
125                 }
126         }
127 }
128
129
130 // Notify that callback thread is ready
131 void TestClass_Stub::____registerCallBack() {
132
133         int numParam = 3;
134         string sign = "registercallback";
135         string retType = "void";
136         string paramCls[] = { "int", "string", "int" };
137         int rev = 0;
138         void* paramObj[] = { &ports[0], &address, &rev };
139         void* retObj = NULL;
140         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
141 }
142
143
144 void TestClass_Stub::setA(int _int) {
145
146         int numParam = 1;
147         string sign = "voidsetA(int)";
148         string retType = "void";
149         string paramCls[] = { "int" };
150         void* paramObj[] = { &_int };
151         void* retObj = NULL;
152         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
153 }
154
155
156 void TestClass_Stub::setB(float _float) {
157
158         int numParam = 1;
159         string sign = "voidsetB(float)";
160         string retType = "void";
161         string paramCls[] = { "float" };
162         void* paramObj[] = { &_float };
163         void* retObj = NULL;
164         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
165 }
166
167
168 void TestClass_Stub::setC(string _string) {
169
170         int numParam = 1;
171         string sign = "voidsetC(string)";
172         string retType = "void";
173         string paramCls[] = { "string" };
174         void* paramObj[] = { &_string };
175         void* retObj = NULL;
176         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
177 }
178
179
180 string TestClass_Stub::sumArray(vector<string> newA) {
181
182         int numParam = 1;
183         string sign = "sumArray(string[])";
184         string retType = "string";
185         string paramCls[] = { "string[]" };
186         void* paramObj[] = { &newA };
187         string retVal = "";
188         void* retObj = &retVal;
189         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
190         return retVal;
191 }
192
193
194 /*int64_t TestClass_Stub::sumArray(vector<int> newA) {
195
196         int numParam = 1;
197         string sign = "sumArray(int[])";
198         string retType = "long";
199         string paramCls[] = { "int[]" };
200         void* paramObj[] = { &newA };
201         int64_t retVal = 0;
202         void* retObj = &retVal;
203         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
204         return retVal;
205 }*/
206
207
208
209 int TestClass_Stub::setAndGetA(int newA) {
210
211         int numParam = 1;
212         string sign = "intsetAndGetA(int)";
213         string retType = "int";
214         string paramCls[] = { "int" };
215         void* paramObj[] = { &newA };
216         int retVal = 0;
217         void* retObj = &retVal;
218         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
219         return retVal;
220 }
221
222
223 int TestClass_Stub::setACAndGetA(string newC, int newA) {
224
225         int numParam = 2;
226         string sign = "intsetACAndGetA(string,int)";
227         string retType = "int";
228         string paramCls[] = { "string", "int" };
229         void* paramObj[] = { &newC, &newA };
230         int retVal = 0;
231         void* retObj = &retVal;
232         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
233         return retVal;
234 }
235
236
237 void TestClass_Stub::registerCallback(CallBackInterface* _cb) {
238
239         //Should implement the callback here
240 }
241
242
243 void TestClass_Stub::registerCallback(vector<CallBackInterface*> _cb) {
244
245         for (CallBackInterface* cb: _cb) {
246                 CallBack_CBSkeleton* skel = new CallBack_CBSkeleton(cb, objIdCnt++);
247                 vecCBObj.push_back(skel);
248         }
249
250         int numParam = 1;
251         string sign = "voidregisterCallBack(CallBackInterface[])";
252         string retType = "void";
253         string paramCls[] = { "int" };
254         int param1 = _cb.size();
255         void* paramObj[] = { &param1 };
256         void* retObj = NULL;
257         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
258 }
259
260
261 int TestClass_Stub::callBack() {
262
263         int numParam = 0;
264         string sign = "intcallBack()";
265         string retType = "int";
266         string paramCls[] = { };
267         void* paramObj[] = { };
268         int retVal = 0;
269         void* retObj = &retVal;
270         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
271         return retVal;
272 }
273
274
275 void TestClass_Stub::handleStruct(vector<data> vecData) {
276
277         int numParam = 1;
278         string sign = "structsize";
279         string retType = "void";
280         string paramCls[] = { "int" };
281         int structsize = vecData.size();
282         void* paramObj[] = { &structsize };
283         void* retObj = NULL;
284         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
285
286         int numParam2 = 3*vecData.size();
287         string sign2 = "handleStruct(StructJ[])";
288         string retType2 = "void";
289         string paramCls2[numParam2];
290         void* paramObj2[numParam2];
291         int pos = 0;
292         for(int i = 0; i < vecData.size(); i++) {
293                 paramCls2[pos] = "string";
294                 paramObj2[pos] = &vecData[i].name; pos++;
295                 paramCls2[pos] = "float";
296                 paramObj2[pos] = &vecData[i].value; pos++;
297                 paramCls2[pos] = "int";
298                 paramObj2[pos] = &vecData[i].year; pos++;
299         }
300         void* retObj2 = NULL;
301         cout << "In handle struct 3!" << endl;
302         rmiCall->remoteCall(objectId, sign2, retType2, paramCls2, paramObj2, numParam2, retObj2);
303 }
304
305
306 #endif