Fixed compiler for Java code generation (not heavily tested yet, but fixes include...
[iot2.git] / iotjava / iotrmi / C++ / IoTRMICall.hpp
index f498758dc572989f709946e85409d5a36e80603a..a92f3e3732da99b090073d334cf5d96d47abd3f8 100644 (file)
 
 #include <iostream>
 #include <string>
+#include <mutex>
 #include "IoTRMIUtil.hpp"
 #include "IoTSocketClient.hpp"
 
 using namespace std;
 
+mutex mtx;
+
 class IoTRMICall {
        public:
-               IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult, 
-                                       const string _methodSign[], const int _size);
+               IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult);
                ~IoTRMICall();
                // Public methods
                int             methodLength(string paramCls[], void* paramObj[], int numParam);
-               char*   methodToBytes(int objectId, string methodSign, string paramCls[], void* paramObj[],
+               char*   methodToBytes(int objectId, int methId, string paramCls[], void* paramObj[],
                                                                char* method, int numParam);
-               void*   remoteCall(int objectId, string methodSign, string retType, string paramCls[], 
+               void*   remoteCall(int objectId, int methodId, string retType, string paramCls[], 
                                                                void* paramObj[], int numParam, void* retObj);
+               void**  getStructObjects(string retType[], int numRet, void* retObj[]);
+               void**  getReturnObjects(char* retBytes, string retCls[], int numRet, void* retObj[]);
 
        private:
-               map<string,int>         mapSign2MethodId;
                IoTRMIUtil                      *rmiUtil;
                IoTSocketClient         *rmiClient;
 
@@ -43,9 +46,8 @@ class IoTRMICall {
 
 
 // Constructor
-IoTRMICall::IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult, const string _methodSign[], const int _size) {
+IoTRMICall::IoTRMICall(int _port, const char* _address, int _rev, bool* _bResult) {
 
-       getMethodIds(_methodSign, _size);
        rmiUtil = new IoTRMIUtil();
        if (rmiUtil == NULL) {
                perror("IoTRMICall: IoTRMIUtil isn't initialized!");
@@ -77,13 +79,15 @@ IoTRMICall::~IoTRMICall() {
 
 
 // Calls a method remotely by passing in parameters and getting a return object
-void* IoTRMICall::remoteCall(int objectId, string methodSign, string retType, string paramCls[], 
+void* IoTRMICall::remoteCall(int objectId, int methodId, string retType, string paramCls[], 
                                                                void* paramObj[], int numParam, void* retObj) {
 
+       // Critical section that is used by different objects
+       lock_guard<mutex> guard(mtx);
        // Send input parameters
        int len = methodLength(paramCls, paramObj, numParam);
        char method[len];
-       methodToBytes(objectId, methodSign, paramCls, paramObj, method, numParam);
+       methodToBytes(objectId, methodId, paramCls, paramObj, method, numParam);
        // Send bytes
        fflush(NULL);
        rmiClient->sendBytes(method, len);
@@ -96,14 +100,33 @@ void* IoTRMICall::remoteCall(int objectId, string methodSign, string retType, st
                int retLen = 0;
                char* retObjBytes = NULL;
                retObjBytes = rmiClient->receiveBytes(retObjBytes, &retLen);
-               IoTRMIUtil::printBytes(retObjBytes, retLen, false);
                retObj = IoTRMIUtil::getParamObject(retObj, retType.c_str(), retObjBytes, retLen);
+               // Delete received bytes object
+               delete[] retObjBytes;
        }
        
        return retObj;
 }
 
 
+// Get a set of return objects (struct)
+void** IoTRMICall::getStructObjects(string retType[], int numRet, void* retObj[]) {
+
+       // Critical section that is used by different objects
+       lock_guard<mutex> guard(mtx);
+       // Receive struct return value and return it to caller
+       int retLen = 0;
+       char* retObjBytes = NULL;
+       // Return size of array of struct
+       retObjBytes = rmiClient->receiveBytes(retObjBytes, &retLen);
+       retObj = getReturnObjects(retObjBytes, retType, numRet, retObj);
+       // Delete received bytes object
+       delete[] retObjBytes;
+       
+       return retObj;
+}
+
+
 // Find the bytes length of a method
 int IoTRMICall::methodLength(string paramCls[], void* paramObj[], int numParam) {
 
@@ -121,13 +144,12 @@ int IoTRMICall::methodLength(string paramCls[], void* paramObj[], int numParam)
                // Calculate methodLen
                methodLen = methodLen + paramLen;
        }
-
        return methodLen;
 }
 
 
 // Convert method and its parameters into bytes
-char* IoTRMICall::methodToBytes(int objectId, string methodSign, string paramCls[], 
+char* IoTRMICall::methodToBytes(int objectId, int methId, string paramCls[], 
                void* paramObj[], char* method, int numParam) {
 
        // Get object Id in bytes
@@ -137,7 +159,6 @@ char* IoTRMICall::methodToBytes(int objectId, string methodSign, string paramCls
        int pos = IoTRMIUtil::OBJECT_ID_LEN;
        // Get method Id in bytes
        char methodId[IoTRMIUtil::METHOD_ID_LEN];
-       int methId = mapSign2MethodId.find(methodSign)->second;
        IoTRMIUtil::intToByteArray(methId, methodId);
        memcpy(method + pos, methodId, IoTRMIUtil::METHOD_ID_LEN);
        pos = pos + IoTRMIUtil::METHOD_ID_LEN;
@@ -148,7 +169,7 @@ char* IoTRMICall::methodToBytes(int objectId, string methodSign, string paramCls
                if (paramLen == -1) { // Store the length of the field - indefinite length
                        paramLen = rmiUtil->getVarTypeSize(paramCls[i], paramObj[i]);
                        // Write the parameter length
-                       char prmLenBytes[IoTRMIUtil::METHOD_ID_LEN];
+                       char prmLenBytes[IoTRMIUtil::PARAM_LEN];
                        IoTRMIUtil::intToByteArray(paramLen, prmLenBytes);
                        memcpy(method + pos, prmLenBytes, IoTRMIUtil::PARAM_LEN);                       
                        pos = pos + IoTRMIUtil::PARAM_LEN;
@@ -164,16 +185,29 @@ char* IoTRMICall::methodToBytes(int objectId, string methodSign, string paramCls
 }
 
 
-// *************
-//    Helpers
-// *************
-void IoTRMICall::getMethodIds(const string methodSign[], const int size) {
-
-       for(int i = 0; i < size; i++) {
-               mapSign2MethodId[methodSign[i]] = i;
+void** IoTRMICall::getReturnObjects(char* retBytes, string retCls[], int numRet, void* retObj[]) {
+
+       // Byte scanning position
+       int pos = 0;
+       for (int i = 0; i < numRet; i++) {
+               int retLen = rmiUtil->getTypeSize(retCls[i]);
+               // Get the 32-bit field in the byte array to get the actual
+               //              length (this is a param with indefinite length)
+               if (retLen == -1) {
+                       char bytRetLen[IoTRMIUtil::RETURN_LEN];
+                       memcpy(bytRetLen, retBytes + pos, IoTRMIUtil::RETURN_LEN);
+                       pos = pos + IoTRMIUtil::RETURN_LEN;
+                       int* retLenPtr = IoTRMIUtil::byteArrayToInt(&retLen, bytRetLen);
+                       retLen = *retLenPtr;
+               }
+               char retObjBytes[retLen];
+               memcpy(retObjBytes, retBytes + pos, retLen);
+               pos = pos + retLen;
+               retObj[i] = IoTRMIUtil::getParamObject(retObj[i], retCls[i].c_str(), retObjBytes, retLen);
        }
-}
 
+       return retObj;
+}
 
 
 #endif