Adding array/vector feature on C++ side - vector is chosen here because C++ doesn...
authorrtrimana <rtrimana@uci.edu>
Wed, 26 Oct 2016 17:14:23 +0000 (10:14 -0700)
committerrtrimana <rtrimana@uci.edu>
Wed, 26 Oct 2016 17:14:23 +0000 (10:14 -0700)
iotjava/Makefile
iotjava/iotrmi/C++/IoTRMIUtil.hpp
iotjava/iotrmi/Java/IoTRMIUtil.java

index 985e41e67c6073bcf3745a6b5243bc0dd10b9c37..7522db0d83b4136e145946da34e4b421a2940991 100644 (file)
@@ -31,9 +31,9 @@ runtime:
 PHONY += rmi
 rmi:
        mkdir -p $(BIN_DIR)
-       $(JAVAC) -cp . -d $(BIN_DIR) iotrmi/*.java
-       $(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/*.java
-       $(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/sample/*.java
+       #$(JAVAC) -cp . -d $(BIN_DIR) iotrmi/*.java
+       #$(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/*.java
+       #$(JAVAC) -cp .:../$(BIN_DIR) -d $(BIN_DIR) iotrmi/Java/sample/*.java
        mkdir -p $(BIN_DIR)/iotrmi/C++
        #$(G++) iotrmi/C++/IoTSocketServer.cpp -o $(BIN_DIR)/iotrmi/C++/IoTSocketServer.out
        #$(G++) iotrmi/C++/IoTSocketClient.cpp -o $(BIN_DIR)/iotrmi/C++/IoTSocketClient.out
index 677612b222789c4a48b55a75a8f5f34d6670f204..c083a37202034749752b393d58128bc762299df3 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <iostream>
 #include <string>
+#include <vector>
 #include <string.h>
 
 #include "IoTRMITypes.hpp"
@@ -36,6 +37,8 @@ class IoTRMIUtil {
                static int              hashCode(string str);
                static char*    getHashCodeBytes(string methodSign, char* bytes);
                int                     getTypeSize(string type);
+               static int              getArrStringLength(vector<string> arrString);
+               static int              getByteStringLength(vector<string> arrString);
                
                // Primitives to byte array
                static char*    shortToByteArray(short i, char* bytes);
@@ -56,14 +59,41 @@ class IoTRMIUtil {
                static char*    byteArrayToChar(char* result, char* bytes);
                static bool*    byteArrayToBoolean(bool* result, char* bytes);
                static string*  byteArrayToString(string* result, char* bytes);
+               static string*  byteArrayToString(string* result, char* bytes, int len);
 
                // Get parameter object from byte array
                static void*    getParamObject(void* retObj, const char* type, char* paramBytes);
                static char*    getObjectBytes(char* retObjBytes, void* obj, const char* type);
 
+               // Arrays to bytes
+               static char*    arrShortToByteArray(vector<short> arrShort, char* bytes);
+               static char*    arrIntToByteArray(vector<int> arrInt, char* bytes);
+               static char*    arrLongToByteArray(vector<int64_t> arrInt, char* bytes);
+               static char*    arrFloatToByteArray(vector<float> arrFloat, char* bytes);
+               static char*    arrDoubleToByteArray(vector<double> arrDouble, char* bytes);
+               static char*    arrCharToByteArray(vector<char> arrChar, char* bytes);
+               static char*    arrBooleanToByteArray(vector<bool> arrBoolean, char* bytes);
+               static char*    arrStringToByteArray(vector<string> arrString, char* bytes);
+
+               // Bytes to array
+               static vector<short>*   byteArrayToShortArray(vector<short>* result, char* bytes, int len);
+               static vector<int>*     byteArrayToIntArray(vector<int>* result, char* bytes, int len);
+               static vector<int64_t>* byteArrayToLongArray(vector<int64_t>* result, char* bytes, int len);
+               static vector<float>*   byteArrayToFloatArray(vector<float>* result, char* bytes, int len);
+               static vector<double>*  byteArrayToDoubleArray(vector<double>* result, char* bytes, int len);
+               static vector<char>*    byteArrayToCharArray(vector<char>* result, char* bytes, int len);
+               static vector<bool>*    byteArrayToBooleanArray(vector<bool>* result, char* bytes, int len);
+               static vector<string>*  byteArrayToStringArray(vector<string>* result, char* bytes, int len);
+
+               // Aggregator functions
+               static char*    getArrayObjectBytes(char* retObjBytes, void* obj, const char* type);
+               static void*    getParamObject(void* retObj, const char* type, char* paramBytes, int len);
+
                // Constants
                const static int        METHOD_ID_LEN = 4;      // 4 bytes = 32 bits
                const static int        PARAM_LEN = 4;          // 4 bytes = 32 bits (4-byte field that stores the length of the param)
+               const static int        CHAR_LEN = 2;           // 2 bytes (we follow Java convention)
+               const static int        BOOL_LEN = 1;           // 1 byte
                
        private:
                map<string,string>      mapPrimitives;
@@ -152,6 +182,27 @@ int IoTRMIUtil::getTypeSize(string type) {
 }
 
 
+int IoTRMIUtil::getArrStringLength(vector<string> arrString) {
+
+       int len = 0;
+       for (string& str : arrString) {
+               len = len + str.length();
+       }
+       return len;
+}
+
+
+int IoTRMIUtil::getByteStringLength(vector<string> arrString) {
+
+       int len = PARAM_LEN + (PARAM_LEN*arrString.size()) + getArrStringLength(arrString);
+       return len;
+}
+
+
+// ****************************
+//    Parameters Translation
+// ****************************
+
 // Getting parameter object based on received byte array
 void* IoTRMIUtil::getParamObject(void* retObj, const char* type, char* paramBytes) {
 
@@ -191,6 +242,36 @@ void* IoTRMIUtil::getParamObject(void* retObj, const char* type, char* paramByte
 }
 
 
+// Get array of objects from byte array - overload getParamObject function
+void* IoTRMIUtil::getParamObject(void* retObj, const char* type, char* paramBytes, int len) {
+
+       if (strcmp(type, "byte[]") == 0) {
+               retObj = (vector<char>*) paramBytes;
+       } else if (strcmp(type, "short[]") == 0) {
+               retObj = byteArrayToShortArray((vector<short>*) retObj, paramBytes, len);
+       } else if (strcmp(type, "int[]") == 0) {
+               retObj = byteArrayToIntArray((vector<int>*) retObj, paramBytes, len);
+       } else if (strcmp(type, "long[]") == 0) {
+               retObj = byteArrayToLongArray((vector<int64_t>*) retObj, paramBytes, len);
+       } else if (strcmp(type, "float[]") == 0) {
+               retObj = byteArrayToFloatArray((vector<float>*) retObj, paramBytes, len);
+       } else if (strcmp(type, "double[]") == 0) {
+               retObj = byteArrayToDoubleArray((vector<double>*) retObj, paramBytes, len);
+       } else if (strcmp(type, "bool[]") == 0) {
+               retObj = byteArrayToBooleanArray((vector<bool>*) retObj, paramBytes, len);
+       } else if (strcmp(type, "char[]") == 0) {
+               retObj = byteArrayToCharArray((vector<char>*) retObj, paramBytes, len);
+       } else if (strcmp(type, "string[]") == 0) {
+               retObj = byteArrayToStringArray((vector<string>*) retObj, paramBytes, len);
+       } else {
+               string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
+               throw error;
+       }
+
+       return retObj;
+}
+
+
 // Getting byte array based on parameter and its type
 char* IoTRMIUtil::getObjectBytes(char* retObjBytes, void* obj, const char* type) {
 
@@ -221,6 +302,39 @@ char* IoTRMIUtil::getObjectBytes(char* retObjBytes, void* obj, const char* type)
        } else if ( strcmp(type, "Ss") == 0 ||
                                strcmp(type, "string") == 0) {
                retObjBytes = stringToByteArray(*((string*) obj), retObjBytes);
+       } else if ( string(type).find("[]") != string::npos) {
+       // This is an array type, i.e. vector
+               retObjBytes = getArrayObjectBytes(retObjBytes, obj, type);
+       } else {
+               string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
+               throw error;
+       }
+
+       return retObjBytes;
+}
+
+
+// Getting byte array for arrays of primitives
+char* IoTRMIUtil::getArrayObjectBytes(char* retObjBytes, void* obj, const char* type) {
+
+       if (strcmp(type, "byte[]") == 0) {
+               retObjBytes = (char*) obj;
+       } else if (strcmp(type, "short[]") == 0) {
+               retObjBytes = arrShortToByteArray(*((vector<short>*) obj), retObjBytes);
+       } else if (strcmp(type, "int[]") == 0) {
+               retObjBytes = arrIntToByteArray(*((vector<int>*) obj), retObjBytes);
+       } else if (strcmp(type, "long[]") == 0) {
+               retObjBytes = arrLongToByteArray(*((vector<int64_t>*) obj), retObjBytes);
+       } else if (strcmp(type, "float[]") == 0) {
+               retObjBytes = arrFloatToByteArray(*((vector<float>*) obj), retObjBytes);
+       } else if (strcmp(type, "double[]") == 0) {
+               retObjBytes = arrDoubleToByteArray(*((vector<double>*) obj), retObjBytes);
+       } else if (strcmp(type, "bool[]") == 0) {
+               retObjBytes = arrBooleanToByteArray(*((vector<bool>*) obj), retObjBytes);
+       } else if (strcmp(type, "char[]") == 0) {
+               retObjBytes = arrCharToByteArray(*((vector<char>*) obj), retObjBytes);
+       } else if (strcmp(type, "string[]") == 0) {
+               retObjBytes = arrStringToByteArray(*((vector<string>*) obj), retObjBytes);
        } else {
                string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
                throw error;
@@ -230,6 +344,295 @@ char* IoTRMIUtil::getObjectBytes(char* retObjBytes, void* obj, const char* type)
 }
 
 
+// Conversions
+// Array handlers - we use vector data type and not traditional arrays
+// Array to bytes
+char* IoTRMIUtil::arrShortToByteArray(vector<short> arrShort, char* bytes) {
+
+       int pos = 0;
+       for (short& sht : arrShort) {
+               char tmpBytes[sizeof(short)];
+               shortToByteArray(sht, tmpBytes);
+               memcpy(bytes + pos, tmpBytes, sizeof(short));
+               pos = pos + sizeof(short);
+       }
+
+       return bytes;
+}
+
+
+char* IoTRMIUtil::arrIntToByteArray(vector<int> arrInt, char* bytes) {
+
+       int pos = 0;
+       for (int& in : arrInt) {
+               char tmpBytes[sizeof(int)];
+               intToByteArray(in, tmpBytes);
+               memcpy(bytes + pos, tmpBytes, sizeof(int));
+               pos = pos + sizeof(int);
+       }
+
+       return bytes;
+}
+
+
+char* IoTRMIUtil::arrLongToByteArray(vector<int64_t> arrLong, char* bytes) {
+
+       int pos = 0;
+       for (int64_t& lng : arrLong) {
+               char tmpBytes[sizeof(int64_t)];
+               longToByteArray(lng, tmpBytes);
+               memcpy(bytes + pos, tmpBytes, sizeof(int64_t));
+               pos = pos + sizeof(int64_t);
+       }
+
+       return bytes;
+}
+
+
+char* IoTRMIUtil::arrFloatToByteArray(vector<float> arrFloat, char* bytes) {
+
+       int pos = 0;
+       for (float& flt : arrFloat) {
+               char tmpBytes[sizeof(float)];
+               floatToByteArray(flt, tmpBytes);
+               memcpy(bytes + pos, tmpBytes, sizeof(float));
+               pos = pos + sizeof(float);
+       }
+
+       return bytes;
+}
+
+
+char* IoTRMIUtil::arrDoubleToByteArray(vector<double> arrDouble, char* bytes) {
+
+       int pos = 0;
+       for (double& dbl : arrDouble) {
+               char tmpBytes[sizeof(double)];
+               doubleToByteArray(dbl, tmpBytes);
+               memcpy(bytes + pos, tmpBytes, sizeof(double));
+               pos = pos + sizeof(double);
+       }
+
+       return bytes;
+}
+
+
+char* IoTRMIUtil::arrCharToByteArray(vector<char> arrChar, char* bytes) {
+
+       int pos = 0;
+       for (char& chr : arrChar) {
+               char tmpBytes[CHAR_LEN];
+               charToByteArray(chr, tmpBytes);
+               memcpy(bytes + pos, tmpBytes, CHAR_LEN);
+               pos = pos + CHAR_LEN;
+       }
+
+       return bytes;
+}
+
+
+char* IoTRMIUtil::arrBooleanToByteArray(vector<bool> arrBoolean, char* bytes) {
+
+       int pos = 0;
+       for (bool bl : arrBoolean) {
+               char tmpBytes[BOOL_LEN];
+               booleanToByteArray(bl, tmpBytes);
+               memcpy(bytes + pos, tmpBytes, BOOL_LEN);
+               pos = pos + BOOL_LEN;
+       }
+
+       return bytes;
+}
+
+
+char* IoTRMIUtil::arrStringToByteArray(vector<string> arrString, char* bytes) {
+
+       int pos = 0;
+       char strArrLenBytes[PARAM_LEN];
+       intToByteArray(arrString.size(), strArrLenBytes);
+       memcpy(bytes, strArrLenBytes, PARAM_LEN);
+       pos = pos + PARAM_LEN;
+       for (string& str : arrString) {
+
+               // Copy string length
+               int strLen = str.length();
+               char strLenBytes[PARAM_LEN];
+               intToByteArray(strLen, strLenBytes);
+               memcpy(bytes + pos, strLenBytes, PARAM_LEN);
+               pos = pos + PARAM_LEN;
+               // Copy string
+               char strBytes[strLen];
+               stringToByteArray(str, strBytes);
+               memcpy(bytes + pos, strBytes, strLen);
+               pos = pos + strLen;
+       }
+
+       return bytes;
+}
+
+
+// Bytes to array
+vector<short>* IoTRMIUtil::byteArrayToShortArray(vector<short>* result, char* bytes, int len) {
+
+       // Single element bytes
+       char elmt[sizeof(short)];
+       // Prepare vector
+       int arrLen = len/sizeof(short);
+       for(int i = 0; i < arrLen; i++) {
+               int offset = i * sizeof(short);
+               memcpy(elmt, bytes + offset, sizeof(short));
+               short res = 0;
+               byteArrayToShort(&res, elmt);
+               result->push_back(res);
+       }
+
+       return result;
+}
+
+
+vector<int>* IoTRMIUtil::byteArrayToIntArray(vector<int>* result, char* bytes, int len) {
+
+       // Single element bytes
+       char elmt[sizeof(int)];
+       // Prepare vector
+       int arrLen = len/sizeof(int);
+       for(int i = 0; i < arrLen; i++) {
+               int offset = i * sizeof(int);
+               memcpy(elmt, bytes + offset, sizeof(int));
+               int res = 0;
+               byteArrayToInt(&res, elmt);
+               result->push_back(res);
+       }
+
+       return result;
+}
+
+
+vector<int64_t>* IoTRMIUtil::byteArrayToLongArray(vector<int64_t>* result, char* bytes, int len) {
+
+       // Single element bytes
+       char elmt[sizeof(int64_t)];
+       // Prepare vector
+       int arrLen = len/sizeof(int64_t);
+       for(int i = 0; i < arrLen; i++) {
+               int offset = i * sizeof(int64_t);
+               memcpy(elmt, bytes + offset, sizeof(int64_t));
+               int64_t res = 0;
+               byteArrayToLong(&res, elmt);
+               result->push_back(res);
+       }
+
+       return result;
+}
+
+
+vector<float>* IoTRMIUtil::byteArrayToFloatArray(vector<float>* result, char* bytes, int len) {
+
+       // Single element bytes
+       char elmt[sizeof(float)];
+       // Prepare vector
+       int arrLen = len/sizeof(float);
+       for(int i = 0; i < arrLen; i++) {
+               int offset = i * sizeof(float);
+               memcpy(elmt, bytes + offset, sizeof(float));
+               float res = 0;
+               byteArrayToFloat(&res, elmt);
+               result->push_back(res);
+       }
+
+       return result;
+}
+
+
+vector<double>* IoTRMIUtil::byteArrayToDoubleArray(vector<double>* result, char* bytes, int len) {
+
+       // Single element bytes
+       char elmt[sizeof(double)];
+       // Prepare vector
+       int arrLen = len/sizeof(double);
+       for(int i = 0; i < arrLen; i++) {
+               int offset = i * sizeof(double);
+               memcpy(elmt, bytes + offset, sizeof(double));
+               double res = 0;
+               byteArrayToDouble(&res, elmt);
+               result->push_back(res);
+       }
+
+       return result;
+}
+
+
+vector<char>* IoTRMIUtil::byteArrayToCharArray(vector<char>* result, char* bytes, int len) {
+
+       // Single element bytes
+       char elmt[CHAR_LEN];
+       // Prepare vector
+       int arrLen = len/CHAR_LEN;
+       for(int i = 0; i < arrLen; i++) {
+               int offset = i * CHAR_LEN;
+               memcpy(elmt, bytes + offset, CHAR_LEN);
+               char res;
+               byteArrayToChar(&res, elmt);
+               result->push_back(res);
+       }
+
+       return result;
+}
+
+
+vector<bool>* IoTRMIUtil::byteArrayToBooleanArray(vector<bool>* result, char* bytes, int len) {
+
+       // Single element bytes
+       char elmt[BOOL_LEN];
+       // Prepare vector
+       int arrLen = len/BOOL_LEN;
+       for(int i = 0; i < arrLen; i++) {
+               int offset = i * BOOL_LEN;
+               memcpy(elmt, bytes + offset, BOOL_LEN);
+               bool res = false;
+               byteArrayToBoolean(&res, elmt);
+               result->push_back(res);
+       }
+
+       return result;
+}
+
+
+vector<string>*        IoTRMIUtil::byteArrayToStringArray(vector<string>* result, char* bytes, int len) {
+
+       // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
+       // Get string array length
+       int pos = 0;
+       char strArrLenBytes[PARAM_LEN];
+       memcpy(strArrLenBytes, bytes, PARAM_LEN);
+       int strArrLen = 0;
+       byteArrayToInt(&strArrLen, strArrLenBytes);
+       pos = pos + PARAM_LEN;
+       // Extract array of strings
+       for(int i = 0; i < strArrLen; i++) {
+
+               // Extract string length
+               char strLenBytes[PARAM_LEN];
+               memcpy(strLenBytes, bytes + pos, PARAM_LEN);
+               int strLen = 0;
+               byteArrayToInt(&strLen, strLenBytes);
+               pos = pos + PARAM_LEN;
+               // Extract string
+               char strBytes[strLen];
+               memcpy(strBytes, bytes + pos, strLen);
+               pos = pos + strLen;
+               string tmpStr = "";
+               // Note: Somehow we need to instantiate the string
+               //              with the length here although we are passing
+               //              an array of bytes with an exact length
+               byteArrayToString(&tmpStr, strBytes, strLen);
+               result->push_back(tmpStr);
+       }
+
+       return result;
+}
+
+
 // Conversions
 // Primitives to byte array
 char* IoTRMIUtil::shortToByteArray(short s, char* bytes) {
@@ -382,8 +785,16 @@ bool* IoTRMIUtil::byteArrayToBoolean(bool* result, char* bytes) {
 
 string* IoTRMIUtil::byteArrayToString(string* result, char* bytes) {
 
-       *result= string(bytes);
+       *result = string(bytes);
        return result;
 }
 
+
+string* IoTRMIUtil::byteArrayToString(string* result, char* bytes, int strLen) {
+
+       *result = string(bytes, strLen);
+       return result;
+}
+
+
 #endif
index a3e6b54de71fa16c28b7997b7b5e5d209ebffc7f..2463c3885e2c33a759166f67be9605fd56556dbd 100644 (file)
@@ -1310,16 +1310,16 @@ public class IoTRMIUtil {
 
        public static void main(String[] args) {
 
-               boolean data = false;
+               //boolean data = false;
                //char data = 'c';
-               //float data = 12.5123f;
+               float data = 1234.123f;
                //double data = 12.51231234;
-               //long data = 123456781234l;
+               //long data = 1234l;
                //short data = 1234;
                //int data = 12345678;
-               byte[] result = booleanToByteArray(data);
+               byte[] result = floatToByteArray(data);
                System.out.println("Result: " + Arrays.toString(result));
-               System.out.println("Converted back: " + byteArrayToBoolean(result));
+               System.out.println("Converted back: " + byteArrayToFloat(result));
                
                String str = "methodA(int,string,float,double,double)";
                int hash = str.hashCode();