#include <iostream>
#include <string>
+#include <vector>
#include <string.h>
#include "IoTRMITypes.hpp"
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);
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;
}
+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) {
}
+// 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) {
} 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;
}
+// 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) {
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