1 /** Class IoTRMIUtil provides methods that the upper
2 * layers can use to transport and invoke methods
3 * when using IoTSocket, IoTSocketClient and IoTSocketServer.
5 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
9 #ifndef _IOTRMIUTIL_HPP__
10 #define _IOTRMIUTIL_HPP__
24 #include "IoTRMITypes.hpp"
35 static void printBytes(char* bytes, const int len, const bool hex);
36 static int hashCode(string str);
37 static char* getHashCodeBytes(string methodSign, char* bytes);
38 int getTypeSize(string type);
40 // Primitives to byte array
41 static char* shortToByteArray(short i, char* bytes);
42 static char* intToByteArray(int i, char* bytes);
43 static char* longToByteArray(int64_t i, char* bytes);
44 static char* floatToByteArray(float f, char* bytes);
45 static char* doubleToByteArray(double d, char* bytes);
46 static char* charToByteArray(char c, char* bytes);
47 static char* booleanToByteArray(bool c, char* bytes);
48 static char* stringToByteArray(string c, char* bytes);
50 // Byte array to primitives
51 static short* byteArrayToShort(short* result, char* bytes);
52 static int* byteArrayToInt(int* result, char* bytes);
53 static int64_t* byteArrayToLong(int64_t* result, char* bytes);
54 static float* byteArrayToFloat(float* result, char* bytes);
55 static double* byteArrayToDouble(double* result, char* bytes);
56 static char* byteArrayToChar(char* result, char* bytes);
57 static bool* byteArrayToBoolean(bool* result, char* bytes);
58 static string* byteArrayToString(string* result, char* bytes);
60 // Get parameter object from byte array
61 static void* getParamObject(void* retObj, const char* type, char* paramBytes);
62 static char* getObjectBytes(char* retObjBytes, void* obj, const char* type);
65 const static int METHOD_ID_LEN = 4; // 4 bytes = 32 bits
66 const static int PARAM_LEN = 4; // 4 bytes = 32 bits (4-byte field that stores the length of the param)
69 map<string,string> mapPrimitives;
70 map<string,int> mapPrimitiveSizesJava;
71 map<string,int> mapPrimitiveSizesCplus;
72 map<string,string> mapNonPrimitives;
77 IoTRMIUtil::IoTRMIUtil() {
79 // Prepare vectors for inputs
80 std::vector<string> primJava (IoTRMITypes::primitivesJava,
81 IoTRMITypes::primitivesJava + sizeof(IoTRMITypes::primitivesJava)/sizeof(string));
82 std::vector<string> primCplus (IoTRMITypes::primitivesCplus,
83 IoTRMITypes::primitivesCplus + sizeof(IoTRMITypes::primitivesCplus)/sizeof(string));
84 std::vector<int> primJavaSizes (IoTRMITypes::primitivesJavaSizes,
85 IoTRMITypes::primitivesJavaSizes + sizeof(IoTRMITypes::primitivesJavaSizes)/sizeof(int));
86 std::vector<int> primCplusSizes (IoTRMITypes::primitivesCplusSizes,
87 IoTRMITypes::primitivesCplusSizes + sizeof(IoTRMITypes::primitivesCplusSizes)/sizeof(int));
88 std::vector<string> nonPrimJava (IoTRMITypes::nonPrimitivesJava,
89 IoTRMITypes::nonPrimitivesJava + sizeof(IoTRMITypes::nonPrimitivesJava)/sizeof(string));
90 std::vector<string> nonPrimCplus (IoTRMITypes::nonPrimitivesCplus,
91 IoTRMITypes::nonPrimitivesCplus + sizeof(IoTRMITypes::nonPrimitivesCplus)/sizeof(string));
95 IoTRMITypes::arraysToMap(mapPrimitives, primJava, primCplus);
96 IoTRMITypes::arraysToMap(mapPrimitiveSizesJava, primJava, primJavaSizes);
97 IoTRMITypes::arraysToMap(mapPrimitiveSizesCplus, primJava, primCplusSizes);
98 IoTRMITypes::arraysToMap(mapNonPrimitives, nonPrimJava, nonPrimCplus);
104 void IoTRMIUtil::printBytes(char* bytes, const int len, const bool hex) {
107 for (int i = 0; i < len; i++) {
108 if (hex) // print in hexadecimal
109 printf("%x", bytes[i]);
111 printf("%d", bytes[i]);
119 // Return hashCode value
120 // This mimics the method Object.hashCode() in Java
121 int IoTRMIUtil::hashCode(string str)
124 int len = str.length();
129 for (int i = 0; i < len; i++) {
131 hash = (31*hash) + (int) c;
138 char* IoTRMIUtil::getHashCodeBytes(string methodSign, char* bytes) {
140 int hash = hashCode(methodSign);
141 return intToByteArray(hash, bytes);
145 int IoTRMIUtil::getTypeSize(string type) {
147 // Handle the types and find the sizes
148 if (mapPrimitiveSizesCplus.find(type) != mapPrimitiveSizesCplus.end())
149 return mapPrimitiveSizesCplus.find(type)->second;
151 return -1; // Size is unknown
155 // Getting parameter object based on received byte array
156 void* IoTRMIUtil::getParamObject(void* retObj, const char* type, char* paramBytes) {
158 if (strcmp(type, "b") == 0 ||
159 strcmp(type, "byte") == 0) {
160 retObj = (void*) ¶mBytes[0];
161 } else if ( strcmp(type, "s") == 0 ||
162 strcmp(type, "short") == 0) {
163 retObj = (void*) byteArrayToShort((short*) retObj, paramBytes);
164 } else if ( strcmp(type, "i") == 0 ||
165 strcmp(type, "int") == 0) {
166 retObj = (void*) byteArrayToInt((int*) retObj, paramBytes);
167 } else if ( strcmp(type, "l") == 0 ||
168 strcmp(type, "long") == 0) {
169 retObj = (void*) byteArrayToLong((int64_t*) retObj, paramBytes);
170 } else if ( strcmp(type, "f") == 0 ||
171 strcmp(type, "float") == 0) {
172 retObj = (void*) byteArrayToFloat((float*) retObj, paramBytes);
173 } else if ( strcmp(type, "d") == 0 ||
174 strcmp(type, "double") == 0) {
175 retObj = (void*) byteArrayToDouble((double*) retObj, paramBytes);
176 } else if ( strcmp(type, "b") == 0 ||
177 strcmp(type, "bool") == 0) {
178 retObj = (void*) byteArrayToBoolean((bool*) retObj, paramBytes);
179 } else if ( strcmp(type, "c") == 0 ||
180 strcmp(type, "char") == 0) {
181 retObj = (void*) byteArrayToChar((char*) retObj, paramBytes);
182 } else if ( strcmp(type, "Ss") == 0 ||
183 strcmp(type, "string") == 0) {
184 retObj = (void*) byteArrayToString((string*) retObj, paramBytes);
186 string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
194 // Getting byte array based on parameter and its type
195 char* IoTRMIUtil::getObjectBytes(char* retObjBytes, void* obj, const char* type) {
197 if (strcmp(type, "b") == 0 ||
198 strcmp(type, "byte") == 0) {
199 retObjBytes = (char*) obj;
200 } else if ( strcmp(type, "s") == 0 ||
201 strcmp(type, "short") == 0) {
202 retObjBytes = shortToByteArray(*((short*) obj), retObjBytes);
203 } else if ( strcmp(type, "i") == 0 ||
204 strcmp(type, "int") == 0) {
205 retObjBytes = intToByteArray(*((int*) obj), retObjBytes);
206 } else if ( strcmp(type, "l") == 0 ||
207 strcmp(type, "long") == 0) {
208 retObjBytes = longToByteArray(*((int64_t*) obj), retObjBytes);
209 } else if ( strcmp(type, "f") == 0 ||
210 strcmp(type, "float") == 0) {
211 retObjBytes = floatToByteArray(*((float*) obj), retObjBytes);
212 } else if ( strcmp(type, "d") == 0 ||
213 strcmp(type, "double") == 0) {
214 retObjBytes = doubleToByteArray(*((double*) obj), retObjBytes);
215 } else if ( strcmp(type, "b") == 0 ||
216 strcmp(type, "bool") == 0) {
217 retObjBytes = booleanToByteArray(*((bool*) obj), retObjBytes);
218 } else if ( strcmp(type, "c") == 0 ||
219 strcmp(type, "char") == 0) {
220 retObjBytes = charToByteArray(*((char*) obj), retObjBytes);
221 } else if ( strcmp(type, "Ss") == 0 ||
222 strcmp(type, "string") == 0) {
223 retObjBytes = stringToByteArray(*((string*) obj), retObjBytes);
225 string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
234 // Primitives to byte array
235 char* IoTRMIUtil::shortToByteArray(short s, char* bytes) {
237 short sInvert = htobe16(s);
238 //short sInvert = htons(s);
239 memcpy(bytes, &sInvert, sizeof(short));
245 char* IoTRMIUtil::intToByteArray(int i, char* bytes) {
247 int iInvert = htobe32(i);
248 //int iInvert = htonl(i);
249 memcpy(bytes, &iInvert, sizeof(int));
255 char* IoTRMIUtil::longToByteArray(int64_t l, char* bytes) {
257 int64_t lInvert = htobe64(l);
258 memcpy(bytes, &lInvert, sizeof(int64_t));
264 char* IoTRMIUtil::floatToByteArray(float f, char* bytes) {
266 // Copy to int to allow the usage of htobeXX() functions
268 memcpy(&i, &f, sizeof(float));
269 int iInvert = htobe32(i);
270 memcpy(bytes, &iInvert, sizeof(int));
276 char* IoTRMIUtil::doubleToByteArray(double d, char* bytes) {
278 // Copy to int to allow the usage of htobeXX() functions
280 memcpy(&i, &d, sizeof(double));
281 int64_t iInvert = htobe64(i);
282 memcpy(bytes, &iInvert, sizeof(int64_t));
288 char* IoTRMIUtil::charToByteArray(char c, char* bytes) {
290 // We need 2 bytes to accommodate Java char type, whose size is 2
298 char* IoTRMIUtil::booleanToByteArray(bool b, char* bytes) {
300 bytes[0] = (b) ? 1 : 0;
305 char* IoTRMIUtil::stringToByteArray(string str, char* bytes) {
307 strcpy(bytes, str.c_str());
313 // Byte array to primitives
314 short* IoTRMIUtil::byteArrayToShort(short* result, char* bytes) {
317 memcpy(&s, bytes, sizeof(short));
318 //short result = be16toh(s);
319 *result = be16toh(s);
325 int* IoTRMIUtil::byteArrayToInt(int* result, char* bytes) {
328 memcpy(&i, bytes, sizeof(int));
329 *result = be32toh(i);
335 int64_t* IoTRMIUtil::byteArrayToLong(int64_t* result, char* bytes) {
338 memcpy(&l, bytes, sizeof(int64_t));
339 *result = be64toh(l);
345 float* IoTRMIUtil::byteArrayToFloat(float* result, char* bytes) {
347 // Copy to int to allow the usage of beXXtoh() functions
349 memcpy(&i, bytes, sizeof(int));
350 int iInvert = be32toh(i);
351 memcpy(result, &iInvert, sizeof(float));
357 double* IoTRMIUtil::byteArrayToDouble(double* result, char* bytes) {
359 // Copy to int to allow the usage of beXXtoh() functions
361 memcpy(&i, bytes, sizeof(int64_t));
362 int64_t iInvert = be64toh(i);
363 memcpy(result, &iInvert, sizeof(double));
369 char* IoTRMIUtil::byteArrayToChar(char* result, char* bytes) {
376 bool* IoTRMIUtil::byteArrayToBoolean(bool* result, char* bytes) {
378 *result = (bytes[0]) ? true : false;
383 string* IoTRMIUtil::byteArrayToString(string* result, char* bytes) {
385 *result= string(bytes);