Removing printing statements from C++ RMI library - this will cause SO files to get...
[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 <set>
6 #include <thread>
7 #include "../IoTRMICall.hpp"
8 #include "../IoTRMIObject.hpp"
9 #include "TestClassInterface.hpp"
10 #include "CallBack_CBSkeleton.hpp"
11 #include "StructC.hpp"
12
13 using namespace std;
14
15 class TestClass_Stub : public TestClassInterface {
16         public:
17                 TestClass_Stub();
18                 TestClass_Stub(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports);
19                 ~TestClass_Stub();
20
21                 void                            setA(int _int);
22                 void                            setB(float _float);
23                 void                            setC(string _string);
24                 string                          sumArray(vector<string> newA);
25                 //int64_t                               sumArray(vector<int> newA);
26                 int                                     setAndGetA(int newA);
27                 int                                     setACAndGetA(string newC, int newA);
28                 void                            registerCallback(CallBackInterface* _cb);
29                 void                            registerCallback(vector<CallBackInterface*>_cb);
30                 int                                     callBack();
31                 vector<data>            handleStruct(vector<data> vecData);
32                 vector<EnumC>           handleEnum(vector<EnumC> vecEn);
33                 void                            ____init_CallBack();    // thread
34                 void                            ____registerCallBack(); // tell the other side that we are ready
35
36                 //exception_ptr         teptr = nullptr;
37
38         private:                
39                 int                                                     intA;
40                 float                                           floatB;
41                 string                                          stringC;
42                 //CallBackInterface                     cb;
43                 IoTRMICall                                      *rmiCall;
44                 string                                          address;
45                 vector<int>                                     ports;
46                 const static int                        objectId = 0;   // Default value is 0
47
48                 // Specific for callbacks
49                 IoTRMIObject                            *rmiObj;
50                 vector<CallBackInterface*>      vecCBObj;
51                 static int      objIdCnt;
52                 // Callback permission
53                 const static set<int>           set0Allowed;
54 };
55
56
57 int TestClass_Stub::objIdCnt = 0;
58
59
60 const set<int> TestClass_Stub::set0Allowed { 0, 1 };
61
62
63 TestClass_Stub::TestClass_Stub() {
64
65         address = "";
66         rmiCall = NULL;
67 }
68
69
70 TestClass_Stub::TestClass_Stub(int _port, const char* _address, int _rev, bool* _bResult, vector<int> _ports) {
71
72         address = _address;
73         rmiCall = new IoTRMICall(_port, _address, _rev, _bResult);
74         ports = _ports;
75         // Start thread
76         /*if (teptr) {
77                 try {
78                         thread th1 (&TestClass_Stub::____init_CallBack, this);
79                         th1.detach();
80                 } catch(const exception&) {
81                         cout << "Got here!" << endl;
82                         throw exception();
83                 }
84         }*/
85         thread th1 (&TestClass_Stub::____init_CallBack, this);
86         th1.detach();
87         //th1.join();
88         ____registerCallBack();
89 }
90
91
92 TestClass_Stub::~TestClass_Stub() {
93
94         if (rmiCall != NULL) {
95                 delete rmiCall;
96                 rmiCall = NULL;
97         }
98         if (rmiObj != NULL) {
99                 delete rmiObj;
100                 rmiObj = NULL;
101         }
102         // Special for callbacks!!!
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);
115         while (true) {
116                 char* method = rmiObj->getMethodBytes();
117                 int methodId = IoTRMIObject::getMethodId(method);
118                 // Permission check
119                 // Complain if the method is not allowed
120                 if (set0Allowed.find(methodId) == set0Allowed.end()) {
121                         cerr << "TestClass_Skeleton: This object is not allowed to access method " << methodId << endl;
122                         exit(-1);
123                         //throw exception();
124                         //teptr = current_exception();
125                 }
126                 int objId = IoTRMIObject::getObjectId(method);
127                 if (objId < vecCBObj.size()) {  // Check if still within range
128                         CallBack_CBSkeleton* skel = 
129                                 dynamic_cast<CallBack_CBSkeleton*> (vecCBObj.at(objId));
130                         skel->invokeMethod(rmiObj);
131                 } else {
132                         string error = "TestClass_Stub: Illegal object Id: " + to_string(objId);
133                         throw error;
134                 }
135         }
136 }
137
138
139 // Notify that callback thread is ready
140 void TestClass_Stub::____registerCallBack() {
141
142         int numParam = 3;
143         int methodId = 9;
144         string retType = "void";
145         string paramCls[] = { "int", "string", "int" };
146         int rev = 0;
147         void* paramObj[] = { &ports[0], &address, &rev };
148         void* retObj = NULL;
149         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
150 }
151
152
153 void TestClass_Stub::setA(int _int) {
154
155         int numParam = 1;
156         int methodId = 0;
157         string retType = "void";
158         string paramCls[] = { "int" };
159         void* paramObj[] = { &_int };
160         void* retObj = NULL;
161         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
162 }
163
164
165 void TestClass_Stub::setB(float _float) {
166
167         int numParam = 1;
168         int methodId = 1;
169         string retType = "void";
170         string paramCls[] = { "float" };
171         void* paramObj[] = { &_float };
172         void* retObj = NULL;
173         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
174 }
175
176
177 void TestClass_Stub::setC(string _string) {
178
179         int numParam = 1;
180         int methodId = 2;
181         string retType = "void";
182         string paramCls[] = { "string" };
183         void* paramObj[] = { &_string };
184         void* retObj = NULL;
185         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
186 }
187
188
189 string TestClass_Stub::sumArray(vector<string> newA) {
190
191         int numParam = 1;
192         int methodId = 3;
193         string retType = "string";
194         string paramCls[] = { "string[]" };
195         void* paramObj[] = { &newA };
196         string retVal = "";
197         void* retObj = &retVal;
198         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
199         return retVal;
200 }
201
202
203 /*int64_t TestClass_Stub::sumArray(vector<int> newA) {
204
205         int numParam = 1;
206         string sign = "sumArray(int[])";
207         string retType = "long";
208         string paramCls[] = { "int[]" };
209         void* paramObj[] = { &newA };
210         int64_t retVal = 0;
211         void* retObj = &retVal;
212         rmiCall->remoteCall(objectId, sign, retType, paramCls, paramObj, numParam, retObj);
213         return retVal;
214 }*/
215
216
217
218 int TestClass_Stub::setAndGetA(int newA) {
219
220         int numParam = 1;
221         int methodId = 4;
222         string retType = "int";
223         string paramCls[] = { "int" };
224         void* paramObj[] = { &newA };
225         int retVal = 0;
226         void* retObj = &retVal;
227         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
228         return retVal;
229 }
230
231
232 int TestClass_Stub::setACAndGetA(string newC, int newA) {
233
234         int numParam = 2;
235         int methodId = 5;
236         string retType = "int";
237         string paramCls[] = { "string", "int" };
238         void* paramObj[] = { &newC, &newA };
239         int retVal = 0;
240         void* retObj = &retVal;
241         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
242         return retVal;
243 }
244
245
246 void TestClass_Stub::registerCallback(CallBackInterface* _cb) {
247
248         //Should implement the callback here
249 }
250
251
252 void TestClass_Stub::registerCallback(vector<CallBackInterface*> _cb) {
253
254         for (CallBackInterface* cb: _cb) {
255                 CallBack_CBSkeleton* skel = new CallBack_CBSkeleton(cb, objIdCnt++);
256                 vecCBObj.push_back(skel);
257         }
258
259         int numParam = 1;
260         int methodId = 8;
261         string retType = "void";
262         string paramCls[] = { "int" };
263         int param1 = _cb.size();
264         void* paramObj[] = { &param1 };
265         void* retObj = NULL;
266         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
267 }
268
269
270 int TestClass_Stub::callBack() {
271
272         int numParam = 0;
273         int methodId = 6;
274         string retType = "int";
275         string paramCls[] = { };
276         void* paramObj[] = { };
277         int retVal = 0;
278         void* retObj = &retVal;
279         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
280         return retVal;
281 }
282
283
284 vector<data> TestClass_Stub::handleStruct(vector<data> vecData) {
285
286         int numParam = 1;
287         int methodId = 11;
288         string retType = "void";
289         string paramCls[] = { "int" };
290         int structsize = vecData.size();
291         void* paramObj[] = { &structsize };
292         void* retObj = NULL;
293         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
294
295         int numParam2 = 3*vecData.size();
296         int methodId2 = 10;
297         string retType2 = "int";
298         string paramCls2[numParam2];
299         void* paramObj2[numParam2];
300         int pos = 0;
301         for(int i = 0; i < vecData.size(); i++) {
302                 paramCls2[pos] = "string";
303                 paramObj2[pos] = &vecData[i].name; pos++;
304                 paramCls2[pos] = "float";
305                 paramObj2[pos] = &vecData[i].value; pos++;
306                 paramCls2[pos] = "int";
307                 paramObj2[pos] = &vecData[i].year; pos++;
308         }
309         // RETURN STRUCT OBJECT
310         // Get length of struct array
311         int structsize1 = 0;
312         void* retObj2 = { &structsize1 };
313         // IF we don't have returned struct objects, then it's just "void* retObj2 = NULL;"
314         rmiCall->remoteCall(objectId, methodId2, retType2, paramCls2, paramObj2, numParam2, retObj2);
315         cout << "Struct length: " << structsize1 << endl;
316
317         // Get the returned objects
318         string retCls[3*structsize1];
319         void* retObj3[3*structsize1];
320         int numRet = 3*structsize1;
321         // define array of everything
322         string param1[structsize1];
323         float param2[structsize1];
324         int param3[structsize1];
325         pos = 0;
326         for(int i=0; i < structsize1; i++) {
327                 retCls[pos] = "string";
328                 retObj3[pos++] = &param1[i];
329                 retCls[pos] = "float";
330                 retObj3[pos++] = &param2[i];
331                 retCls[pos] = "int";
332                 retObj3[pos++] = &param3[i];
333         }
334         rmiCall->getStructObjects(retCls, numRet, retObj3);
335         vector<data> dat(structsize1);
336         pos = 0;
337         for (int i=0; i < structsize1; i++) {
338                 dat[i].name = param1[i];
339                 dat[i].value = param2[i];
340                 dat[i].year = param3[i];
341         }
342
343         return dat;
344 }
345
346
347 vector<EnumC> TestClass_Stub::handleEnum(vector<EnumC> vecEn) {
348
349         int numParam = 1;
350         int numEl = vecEn.size();
351         int methodId = 12;
352         string retType = "int[]";
353         string paramCls[] = { "int[]" };
354         // Need to define this container for integer version of enum
355         vector<int> paramInt(numEl);
356         for(int i = 0; i < numEl; i++) {
357                 paramInt[i] = (int) vecEn[i]; // cast enum to integer
358         }
359         void* paramObj[] = { &paramInt };
360         // if no return value just
361         // void* retObj2 = NULL;
362         // This is with return value:
363         vector<int> retEnumInt;
364         void* retObj = &retEnumInt;
365         rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);
366         int enumsize1 = retEnumInt.size();
367         vector<EnumC> retVal(enumsize1);
368         for (int i=0; i < enumsize1; i++) {
369                 retVal[i] = (EnumC) retEnumInt[i];
370         }
371         return retVal;
372 }
373
374
375
376 #endif