From: rtrimana Date: Wed, 26 Oct 2016 17:14:23 +0000 (-0700) Subject: Adding array/vector feature on C++ side - vector is chosen here because C++ doesn... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=iot2.git;a=commitdiff_plain;h=6af259f06ec3a02ae9195099afc5b2dfc71f274f Adding array/vector feature on C++ side - vector is chosen here because C++ doesn't provide a straightforward way to get dimensions for traditional arrays --- diff --git a/iotjava/Makefile b/iotjava/Makefile index 985e41e..7522db0 100644 --- a/iotjava/Makefile +++ b/iotjava/Makefile @@ -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 diff --git a/iotjava/iotrmi/C++/IoTRMIUtil.hpp b/iotjava/iotrmi/C++/IoTRMIUtil.hpp index 677612b..c083a37 100644 --- a/iotjava/iotrmi/C++/IoTRMIUtil.hpp +++ b/iotjava/iotrmi/C++/IoTRMIUtil.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #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 arrString); + static int getByteStringLength(vector 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 arrShort, char* bytes); + static char* arrIntToByteArray(vector arrInt, char* bytes); + static char* arrLongToByteArray(vector arrInt, char* bytes); + static char* arrFloatToByteArray(vector arrFloat, char* bytes); + static char* arrDoubleToByteArray(vector arrDouble, char* bytes); + static char* arrCharToByteArray(vector arrChar, char* bytes); + static char* arrBooleanToByteArray(vector arrBoolean, char* bytes); + static char* arrStringToByteArray(vector arrString, char* bytes); + + // Bytes to array + static vector* byteArrayToShortArray(vector* result, char* bytes, int len); + static vector* byteArrayToIntArray(vector* result, char* bytes, int len); + static vector* byteArrayToLongArray(vector* result, char* bytes, int len); + static vector* byteArrayToFloatArray(vector* result, char* bytes, int len); + static vector* byteArrayToDoubleArray(vector* result, char* bytes, int len); + static vector* byteArrayToCharArray(vector* result, char* bytes, int len); + static vector* byteArrayToBooleanArray(vector* result, char* bytes, int len); + static vector* byteArrayToStringArray(vector* 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 mapPrimitives; @@ -152,6 +182,27 @@ int IoTRMIUtil::getTypeSize(string type) { } +int IoTRMIUtil::getArrStringLength(vector arrString) { + + int len = 0; + for (string& str : arrString) { + len = len + str.length(); + } + return len; +} + + +int IoTRMIUtil::getByteStringLength(vector 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*) paramBytes; + } else if (strcmp(type, "short[]") == 0) { + retObj = byteArrayToShortArray((vector*) retObj, paramBytes, len); + } else if (strcmp(type, "int[]") == 0) { + retObj = byteArrayToIntArray((vector*) retObj, paramBytes, len); + } else if (strcmp(type, "long[]") == 0) { + retObj = byteArrayToLongArray((vector*) retObj, paramBytes, len); + } else if (strcmp(type, "float[]") == 0) { + retObj = byteArrayToFloatArray((vector*) retObj, paramBytes, len); + } else if (strcmp(type, "double[]") == 0) { + retObj = byteArrayToDoubleArray((vector*) retObj, paramBytes, len); + } else if (strcmp(type, "bool[]") == 0) { + retObj = byteArrayToBooleanArray((vector*) retObj, paramBytes, len); + } else if (strcmp(type, "char[]") == 0) { + retObj = byteArrayToCharArray((vector*) retObj, paramBytes, len); + } else if (strcmp(type, "string[]") == 0) { + retObj = byteArrayToStringArray((vector*) 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*) obj), retObjBytes); + } else if (strcmp(type, "int[]") == 0) { + retObjBytes = arrIntToByteArray(*((vector*) obj), retObjBytes); + } else if (strcmp(type, "long[]") == 0) { + retObjBytes = arrLongToByteArray(*((vector*) obj), retObjBytes); + } else if (strcmp(type, "float[]") == 0) { + retObjBytes = arrFloatToByteArray(*((vector*) obj), retObjBytes); + } else if (strcmp(type, "double[]") == 0) { + retObjBytes = arrDoubleToByteArray(*((vector*) obj), retObjBytes); + } else if (strcmp(type, "bool[]") == 0) { + retObjBytes = arrBooleanToByteArray(*((vector*) obj), retObjBytes); + } else if (strcmp(type, "char[]") == 0) { + retObjBytes = arrCharToByteArray(*((vector*) obj), retObjBytes); + } else if (strcmp(type, "string[]") == 0) { + retObjBytes = arrStringToByteArray(*((vector*) 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 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 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 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 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 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 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 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 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* IoTRMIUtil::byteArrayToShortArray(vector* 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* IoTRMIUtil::byteArrayToIntArray(vector* 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* IoTRMIUtil::byteArrayToLongArray(vector* 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* IoTRMIUtil::byteArrayToFloatArray(vector* 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* IoTRMIUtil::byteArrayToDoubleArray(vector* 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* IoTRMIUtil::byteArrayToCharArray(vector* 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* IoTRMIUtil::byteArrayToBooleanArray(vector* 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* IoTRMIUtil::byteArrayToStringArray(vector* 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 diff --git a/iotjava/iotrmi/Java/IoTRMIUtil.java b/iotjava/iotrmi/Java/IoTRMIUtil.java index a3e6b54..2463c38 100644 --- a/iotjava/iotrmi/Java/IoTRMIUtil.java +++ b/iotjava/iotrmi/Java/IoTRMIUtil.java @@ -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();