Adding config file for sharing.
[iot2.git] / iotjava / iotrmi / C++ / IoTRMIUtil.hpp
1 /** Class IoTRMIUtil provides methods that the upper
2  *  layers can use to transport and invoke methods
3  *  when using IoTSocket, IoTSocketClient and IoTSocketServer.
4  *
5  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
6  * @version     1.0
7  * @since       2016-10-18
8  */
9 #ifndef _IOTRMIUTIL_HPP__
10 #define _IOTRMIUTIL_HPP__
11
12 #include <stdio.h>
13 #include <stdint.h>
14 #include <endian.h>
15 #include <cxxabi.h>
16 #include <cstdlib>
17 #include <memory>
18 #include <typeinfo>
19 #include <map>
20
21 #include <iostream>
22 #include <string>
23 #include <vector>
24 #include <string.h>
25
26 #include "IoTRMITypes.hpp"
27
28 using namespace std;
29
30 class IoTRMIUtil final {
31
32         public:
33                 IoTRMIUtil();
34                 //~IoTRMIUtil();
35                 
36                 // Helper functions
37                 static void     printBytes(char* bytes, const int len, const bool hex);
38                 static int      hashCode(string str);
39                 static char*    getHashCodeBytes(string methodSign, char* bytes);
40                 int             getTypeSize(string type);
41                 int             getVarTypeSize(string type, void* paramObj);
42                 static int      getArrStringLength(vector<string> arrString);
43                 static int      getByteStringLength(vector<string> arrString);
44                 
45                 // Primitives to byte array
46                 static char*    byteToByteArray(char c, char* bytes);
47                 static char*    shortToByteArray(short i, char* bytes);
48                 static char*    intToByteArray(int i, char* bytes);
49                 static char*    longToByteArray(int64_t i, char* bytes);
50                 static char*    floatToByteArray(float f, char* bytes);
51                 static char*    doubleToByteArray(double d, char* bytes);
52                 static char*    charToByteArray(char c, char* bytes);
53                 static char*    booleanToByteArray(bool c, char* bytes);
54                 static char*    stringToByteArray(string c, char* bytes);
55
56                 // Byte array to primitives
57                 static char*    byteArrayToByte(char* result, char* bytes);
58                 static short*   byteArrayToShort(short* result, char* bytes);
59                 static int*     byteArrayToInt(int* result, char* bytes);
60                 static int64_t* byteArrayToLong(int64_t* result, char* bytes);
61                 static float*   byteArrayToFloat(float* result, char* bytes);
62                 static double*  byteArrayToDouble(double* result, char* bytes);
63                 static char*    byteArrayToChar(char* result, char* bytes);
64                 static bool*    byteArrayToBoolean(bool* result, char* bytes);
65                 static string*  byteArrayToString(string* result, char* bytes);
66                 static string*  byteArrayToString(string* result, char* bytes, int len);
67
68                 // Get parameter object from byte array
69                 static void*    getParamObject(void* retObj, const char* type, char* paramBytes, int len);
70                 static char*    getObjectBytes(char* retObjBytes, void* obj, const char* type);
71
72                 // Arrays to bytes
73                 static char*    arrByteToByteArray(vector<char> arrByte, char* bytes);
74                 static char*    arrShortToByteArray(vector<short> arrShort, char* bytes);
75                 static char*    arrIntToByteArray(vector<int> arrInt, char* bytes);
76                 static char*    arrLongToByteArray(vector<int64_t> arrInt, char* bytes);
77                 static char*    arrFloatToByteArray(vector<float> arrFloat, char* bytes);
78                 static char*    arrDoubleToByteArray(vector<double> arrDouble, char* bytes);
79                 static char*    arrCharToByteArray(vector<char> arrChar, char* bytes);
80                 static char*    arrBooleanToByteArray(vector<bool> arrBoolean, char* bytes);
81                 static char*    arrStringToByteArray(vector<string> arrString, char* bytes);
82
83                 // Bytes to array
84                 static vector<char>*    byteArrayToByteArray(vector<char>* result, char* bytes, int len);
85                 static vector<short>*   byteArrayToShortArray(vector<short>* result, char* bytes, int len);
86                 static vector<int>*     byteArrayToIntArray(vector<int>* result, char* bytes, int len);
87                 static vector<int64_t>* byteArrayToLongArray(vector<int64_t>* result, char* bytes, int len);
88                 static vector<float>*   byteArrayToFloatArray(vector<float>* result, char* bytes, int len);
89                 static vector<double>*  byteArrayToDoubleArray(vector<double>* result, char* bytes, int len);
90                 static vector<char>*    byteArrayToCharArray(vector<char>* result, char* bytes, int len);
91                 static vector<bool>*    byteArrayToBooleanArray(vector<bool>* result, char* bytes, int len);
92                 static vector<string>*  byteArrayToStringArray(vector<string>* result, char* bytes, int len);
93
94                 // Aggregator functions
95                 static char*    getArrayObjectBytes(char* retObjBytes, void* obj, const char* type);
96                 static void*    getArrayParamObject(void* retObj, const char* type, char* paramBytes, int len);
97
98                 // Constants
99                 const static int        OBJECT_ID_LEN = 4;      // 4 bytes = 32 bits
100                 const static int        METHOD_ID_LEN = 4;      // 4 bytes = 32 bits
101                 const static int        PACKET_TYPE_LEN = 4;// 4 bytes = 32 bits
102                 const static int        PARAM_LEN = 4;          // 4 bytes = 32 bits (4-byte field that stores the length of the param)
103                 const static int        RETURN_LEN = 4;         // 4 bytes = 32 bits (4-byte field that stores the length of the return object)
104                 const static int        CHAR_LEN = 2;           // 2 bytes (we follow Java convention)
105                 const static int        BYTE_LEN = 1;           // 1 byte
106                 const static int        BOOL_LEN = 1;           // 1 byte
107                 const static int        METHOD_TYPE = 1;        // Packet type of method
108                 const static int        RET_VAL_TYPE = -1;      // Packet type of return value
109
110                 // Static containers
111                 static map<int,void*>* mapStub;         // Map object to its stub ID
112                 static map<void*,void*>* mapSkel;       // Map object to its skeleton
113                 static map<void*,int>* mapSkelId;       // Map object to its skeleton ID
114                 
115         private:
116                 map<string,string>      mapPrimitives;
117                 map<string,int>         mapPrimitiveSizes;
118                 map<string,string>      mapNonPrimitives;
119 };
120
121 map<int,void*>* IoTRMIUtil::mapStub = new map<int,void*>();
122 map<void*,void*>* IoTRMIUtil::mapSkel = new map<void*,void*>();
123 map<void*,int>* IoTRMIUtil::mapSkelId = new map<void*,int>();
124
125
126 // Constructor
127 IoTRMIUtil::IoTRMIUtil() {
128
129         // Prepare vectors for inputs
130         std::vector<string> primJava (IoTRMITypes::primitivesJava, 
131                 IoTRMITypes::primitivesJava + sizeof(IoTRMITypes::primitivesJava)/sizeof(string));
132         std::vector<string> primCplus (IoTRMITypes::primitivesCplus, 
133                 IoTRMITypes::primitivesCplus + sizeof(IoTRMITypes::primitivesCplus)/sizeof(string));
134         std::vector<int> primSizes (IoTRMITypes::primitivesSizes, 
135                 IoTRMITypes::primitivesSizes + sizeof(IoTRMITypes::primitivesSizes)/sizeof(int));
136         std::vector<string> nonPrimJava (IoTRMITypes::nonPrimitivesJava, 
137                 IoTRMITypes::nonPrimitivesJava + sizeof(IoTRMITypes::nonPrimitivesJava)/sizeof(string));
138         std::vector<string> nonPrimCplus (IoTRMITypes::nonPrimitivesCplus, 
139                 IoTRMITypes::nonPrimitivesCplus + sizeof(IoTRMITypes::nonPrimitivesCplus)/sizeof(string));
140
141         // Write into maps
142         IoTRMITypes::arraysToMap(mapPrimitives, primJava, primCplus);
143         IoTRMITypes::arraysToMap(mapPrimitiveSizes, primJava, primSizes); 
144         IoTRMITypes::arraysToMap(mapNonPrimitives, nonPrimJava, nonPrimCplus);
145 }
146
147 // *************
148 //    Helpers
149 // *************
150 void IoTRMIUtil::printBytes(char* bytes, const int len, const bool hex) {
151
152         printf("[ ");
153         for (int i = 0; i < len; i++) {
154                 if (hex)        // print in hexadecimal
155                         printf("%x", bytes[i]);
156                 else
157                         printf("%d", bytes[i]);
158                 if (i < len - 1)
159                         printf(", ");
160         }
161         printf(" ]\n");
162 }
163
164
165 // Return hashCode value 
166 // This mimics the method Object.hashCode() in Java
167 int IoTRMIUtil::hashCode(string str)  
168 {
169         int hash = 0;
170         int len = str.length();
171         char c;
172         if (len == 0) 
173                 return hash;
174         
175         for (int i = 0; i < len; i++) {
176                 c = str.at(i);
177                 hash = (31*hash) + (int) c;
178         }
179
180         return hash;
181 }
182
183
184 char* IoTRMIUtil::getHashCodeBytes(string methodSign, char* bytes) {
185
186         int hash = hashCode(methodSign);
187         return intToByteArray(hash, bytes);
188 }
189
190
191 int IoTRMIUtil::getTypeSize(string type) {
192
193         // Handle the types and find the sizes
194         if (mapPrimitiveSizes.find(type) != mapPrimitiveSizes.end())
195                 return mapPrimitiveSizes.find(type)->second;
196         else
197                 return -1; // Size is unknown
198 }
199
200
201 // Get variable type size, e.g. strings, arrays, etc.
202 int IoTRMIUtil::getVarTypeSize(string type, void* paramObj) {
203
204         int paramLen = 0;
205         if (type.compare("String") == 0) {
206                 // Get the length of the string through void* casting to string*
207                 paramLen = (*(string*)paramObj).length();
208         } else if (     (type.compare("String*") == 0) ||
209                                 (type.compare("string*") == 0) ||
210                                 (type.compare("vector<String>") == 0)) {
211                 paramLen = IoTRMIUtil::getByteStringLength(*(vector<string>*) paramObj);
212         } else if ( (type.compare("byte*") == 0) ||
213                                 (type.compare("Byte*") == 0) ||
214                                 (type.compare("vector<Byte>") == 0)) {
215                 int dataSize = getTypeSize("byte");
216                 paramLen = (*(vector<char>*) paramObj).size() * dataSize;
217         } else if ( (type.compare("short*") == 0) ||
218                                 (type.compare("Short*") == 0) ||
219                                 (type.compare("vector<Short>") == 0)) {
220                 int dataSize = getTypeSize("short");
221                 paramLen = (*(vector<short>*) paramObj).size() * dataSize;
222         } else if ( (type.compare("int*") == 0) ||
223                                 (type.compare("Integer*") == 0) ||
224                                 (type.compare("vector<Integer>") == 0)) {
225                 int dataSize = getTypeSize("int");
226                 paramLen = (*(vector<int>*) paramObj).size() * dataSize;
227         } else if ( (type.compare("long*") == 0) ||
228                                 (type.compare("Long*") == 0) ||
229                                 (type.compare("vector<Long>") == 0)) {
230                 int dataSize = getTypeSize("long");
231                 paramLen = (*(vector<int64_t>*) paramObj).size() * dataSize;
232         } else if ( (type.compare("float*") == 0) ||
233                                 (type.compare("Float*") == 0) ||
234                                 (type.compare("vector<Float>") == 0)) {
235                 int dataSize = getTypeSize("float");
236                 paramLen = (*(vector<float>*) paramObj).size() * dataSize;
237         } else if ( (type.compare("double*") == 0) ||
238                                 (type.compare("Double*") == 0) ||
239                                 (type.compare("vector<Double>") == 0)) {
240                 int dataSize = getTypeSize("double");
241                 paramLen = (*(vector<double>*) paramObj).size() * dataSize;
242         } else if ( (type.compare("boolean*") == 0) ||
243                                 (type.compare("Boolean*") == 0) ||
244                                 (type.compare("vector<Boolean>") == 0)) {
245                 int dataSize = getTypeSize("boolean");
246                 paramLen = (*(vector<bool>*) paramObj).size() * dataSize;
247         } else if ( (type.compare("char*") == 0) ||
248                                 (type.compare("Character*") == 0) ||
249                                 (type.compare("vector<Character>") == 0)) {
250                 int dataSize = getTypeSize("char");
251                 paramLen = (*(vector<char>*) paramObj).size() * dataSize;
252         } else {
253                 cerr << "IoTRMIUtil: Unrecognizable type: " << type << endl;
254                 exit(-1);
255         }
256
257         return paramLen;
258 }
259
260
261 int IoTRMIUtil::getArrStringLength(vector<string> arrString) {
262
263         int len = 0;
264         for (string& str : arrString) {
265                 len = len + str.length();
266         }
267         return len;
268 }
269
270
271 int IoTRMIUtil::getByteStringLength(vector<string> arrString) {
272
273         int len = PARAM_LEN + (PARAM_LEN*arrString.size()) + getArrStringLength(arrString);
274         return len;
275 }
276
277
278 // ****************************
279 //    Parameters Translation
280 // ****************************
281
282 // Getting parameter object based on received byte array
283 void* IoTRMIUtil::getParamObject(void* retObj, const char* type, char* paramBytes, int len) {
284
285         if (strcmp(type, "b") == 0 ||
286                 strcmp(type, "byte") == 0) {
287                 retObj = (void*) byteArrayToByte((char*) retObj, paramBytes);
288         } else if ( strcmp(type, "s") == 0 ||
289                                 strcmp(type, "short") == 0) {
290                 retObj = (void*) byteArrayToShort((short*) retObj, paramBytes);
291         } else if ( strcmp(type, "i") == 0 ||
292                                 strcmp(type, "int") == 0) {
293                 retObj = (void*) byteArrayToInt((int*) retObj, paramBytes);
294         } else if ( strcmp(type, "l") == 0 ||
295                                 strcmp(type, "long") == 0) {
296                 retObj = (void*) byteArrayToLong((int64_t*) retObj, paramBytes);
297         } else if ( strcmp(type, "f") == 0 ||
298                                 strcmp(type, "float") == 0) {
299                 retObj = (void*) byteArrayToFloat((float*) retObj, paramBytes);
300         } else if ( strcmp(type, "d") == 0 ||
301                                 strcmp(type, "double") == 0) {
302                 retObj = (void*) byteArrayToDouble((double*) retObj, paramBytes);
303         } else if ( strcmp(type, "b") == 0 ||
304                                 strcmp(type, "boolean") == 0) {
305                 retObj = (void*) byteArrayToBoolean((bool*) retObj, paramBytes);
306         } else if ( strcmp(type, "c") == 0 ||
307                                 strcmp(type, "char") == 0) {
308                 retObj = (void*) byteArrayToChar((char*) retObj, paramBytes);
309         } else if ( strcmp(type, "Ss") == 0 ||
310                                 strcmp(type, "String") == 0) {
311                 retObj = (void*) byteArrayToString((string*) retObj, paramBytes, len);
312         } else if ( string(type).find("*") != string::npos) {
313                 // This is an array type, i.e. vector
314                 retObj = getArrayParamObject(retObj, type, paramBytes, len);
315         } else if ( (string(type).find("<") != string::npos) &&
316                                 (string(type).find(">") != string::npos)) {
317                 // This is a vector/list type
318                 retObj = getArrayParamObject(retObj, type, paramBytes, len);
319         } else {
320                 cerr << "IoTRMIUtil: Unrecognizable type: " << type << endl;
321                 exit(-1);
322         }
323
324         return retObj;
325 }
326
327
328 // Get array of objects from byte array
329 void* IoTRMIUtil::getArrayParamObject(void* retObj, const char* type, char* paramBytes, int len) {
330
331         if ((strcmp(type, "byte*") == 0) ||
332                 (strcmp(type, "Byte*") == 0) ||
333                 (strcmp(type, "vector<Byte>") == 0)) {
334                 retObj = byteArrayToByteArray((vector<char>*) retObj, paramBytes, len);
335         } else if ( (strcmp(type, "short*") == 0) ||
336                                 (strcmp(type, "Short*") == 0) ||
337                                 (strcmp(type, "vector<Short>") == 0)) {
338                 retObj = byteArrayToShortArray((vector<short>*) retObj, paramBytes, len);
339         } else if ( (strcmp(type, "int*") == 0) ||
340                                 (strcmp(type, "Integer*") == 0) ||
341                                 (strcmp(type, "vector<Integer>") == 0)) {
342                 retObj = byteArrayToIntArray((vector<int>*) retObj, paramBytes, len);
343         } else if ( (strcmp(type, "long*") == 0) ||
344                                 (strcmp(type, "Long*") == 0) ||
345                                 (strcmp(type, "vector<Long>") == 0)) {
346                 retObj = byteArrayToLongArray((vector<int64_t>*) retObj, paramBytes, len);
347         } else if ( (strcmp(type, "float*") == 0) ||
348                                 (strcmp(type, "Float*") == 0) ||
349                                 (strcmp(type, "vector<Float>") == 0)) {
350                 retObj = byteArrayToFloatArray((vector<float>*) retObj, paramBytes, len);
351         } else if ( (strcmp(type, "double*") == 0) ||
352                                 (strcmp(type, "Double*") == 0) ||
353                                 (strcmp(type, "vector<Double>") == 0)) {
354                 retObj = byteArrayToDoubleArray((vector<double>*) retObj, paramBytes, len);
355         } else if ( (strcmp(type, "boolean*") == 0) ||
356                                 (strcmp(type, "Boolean*") == 0) ||
357                                 (strcmp(type, "vector<Boolean>") == 0)) {
358                 retObj = byteArrayToBooleanArray((vector<bool>*) retObj, paramBytes, len);
359         } else if ( (strcmp(type, "char*") == 0)      ||
360                                 (strcmp(type, "Character*") == 0) ||
361                                 (strcmp(type, "vector<Character>") == 0)) {
362                 retObj = byteArrayToCharArray((vector<char>*) retObj, paramBytes, len);
363         } else if ( (strcmp(type, "String*") == 0) ||
364                                 (strcmp(type, "vector<String>") == 0)) {
365                 retObj = byteArrayToStringArray((vector<string>*) retObj, paramBytes, len);
366         } else {
367                 cerr << "IoTRMIUtil: Unrecognizable type: " << type << endl;
368                 exit(-1);       
369         }
370
371         return retObj;
372 }
373
374
375 // Getting byte array based on parameter and its type
376 char* IoTRMIUtil::getObjectBytes(char* retObjBytes, void* obj, const char* type) {
377
378         if (strcmp(type, "b") == 0 ||
379                 strcmp(type, "byte") == 0) {
380                 retObjBytes = byteToByteArray(*((char*) obj), retObjBytes);             
381         } else if ( strcmp(type, "s") == 0 ||
382                                 strcmp(type, "short") == 0) {
383                 retObjBytes = shortToByteArray(*((short*) obj), retObjBytes);
384         } else if ( strcmp(type, "i") == 0 ||
385                                 strcmp(type, "int") == 0) {
386                 retObjBytes = intToByteArray(*((int*) obj), retObjBytes);
387         } else if ( strcmp(type, "l") == 0 ||
388                                 strcmp(type, "long") == 0) {
389                 retObjBytes = longToByteArray(*((int64_t*) obj), retObjBytes);
390         } else if ( strcmp(type, "f") == 0 ||
391                                 strcmp(type, "float") == 0) {
392                 retObjBytes = floatToByteArray(*((float*) obj), retObjBytes);
393         } else if ( strcmp(type, "d") == 0 ||
394                                 strcmp(type, "double") == 0) {
395                 retObjBytes = doubleToByteArray(*((double*) obj), retObjBytes);
396         } else if ( strcmp(type, "b") == 0 ||
397                                 strcmp(type, "boolean") == 0) {
398                 retObjBytes = booleanToByteArray(*((bool*) obj), retObjBytes);
399         } else if ( strcmp(type, "c") == 0 ||
400                                 strcmp(type, "char") == 0) {
401                 retObjBytes = charToByteArray(*((char*) obj), retObjBytes);
402         } else if ( strcmp(type, "Ss") == 0 ||
403                                 strcmp(type, "String") == 0) {
404                 retObjBytes = stringToByteArray(*((string*) obj), retObjBytes);
405         } else if ( string(type).find("*") != string::npos) {
406         // This is an array type, i.e. vector
407                 retObjBytes = getArrayObjectBytes(retObjBytes, obj, type);
408         } else if ( (string(type).find("<") != string::npos) &&
409                                 (string(type).find(">") != string::npos)) {
410         // This is a vector/list type
411                 retObjBytes = getArrayObjectBytes(retObjBytes, obj, type);
412         } else {
413                 cerr << "IoTRMIUtil: Unrecognizable type: " << type << endl;
414                 exit(-1);
415         }
416
417         return retObjBytes;
418 }
419
420
421 // Getting byte array for arrays of primitives
422 char* IoTRMIUtil::getArrayObjectBytes(char* retObjBytes, void* obj, const char* type) {
423
424         if ((strcmp(type, "byte*") == 0) ||
425                 (strcmp(type, "Byte*") == 0) ||
426                 (strcmp(type, "vector<Byte>") == 0)) {
427                 retObjBytes = arrByteToByteArray(*((vector<char>*) obj), retObjBytes);
428         } else if ( (strcmp(type, "short*") == 0) ||
429                                 (strcmp(type, "Short*") == 0) ||
430                                 (strcmp(type, "vector<Short>") == 0)) {
431                 retObjBytes = arrShortToByteArray(*((vector<short>*) obj), retObjBytes);
432         } else if ( (strcmp(type, "int*") == 0) ||
433                                 (strcmp(type, "Integer*") == 0) ||
434                                 (strcmp(type, "vector<Integer>") == 0)) {
435                 retObjBytes = arrIntToByteArray(*((vector<int>*) obj), retObjBytes);
436         } else if ( (strcmp(type, "long*") == 0) ||
437                                 (strcmp(type, "Long*") == 0) ||
438                                 (strcmp(type, "vector<Long>") == 0)) {
439                 retObjBytes = arrLongToByteArray(*((vector<int64_t>*) obj), retObjBytes);
440         } else if ( (strcmp(type, "float*") == 0) ||
441                                 (strcmp(type, "Float*") == 0) ||
442                                 (strcmp(type, "vector<Float>") == 0)) {
443                 retObjBytes = arrFloatToByteArray(*((vector<float>*) obj), retObjBytes);
444         } else if ( (strcmp(type, "double*") == 0) ||
445                                 (strcmp(type, "Double*") == 0) ||
446                                 (strcmp(type, "vector<Double>") == 0)) {
447                 retObjBytes = arrDoubleToByteArray(*((vector<double>*) obj), retObjBytes);
448         } else if ( (strcmp(type, "boolean*") == 0) ||
449                                 (strcmp(type, "Boolean*") == 0) ||
450                                 (strcmp(type, "vector<Boolean>") == 0)) {
451                 retObjBytes = arrBooleanToByteArray(*((vector<bool>*) obj), retObjBytes);
452         } else if ( (strcmp(type, "char*") == 0) ||
453                                 (strcmp(type, "Character*") == 0) ||
454                                 (strcmp(type, "vector<Character>") == 0)) {
455                 retObjBytes = arrCharToByteArray(*((vector<char>*) obj), retObjBytes);
456         } else if ( (strcmp(type, "String*") == 0) ||
457                                 (strcmp(type, "vector<String>") == 0)) {
458                 retObjBytes = arrStringToByteArray(*((vector<string>*) obj), retObjBytes);
459         } else {
460                 cerr << "IoTRMIUtil: Unrecognizable type: " << type << endl;
461                 exit(-1);
462         }
463
464         return retObjBytes;
465 }
466
467
468 // Conversions
469 // Array handlers - we use vector data type and not traditional arrays
470 // Array to bytes
471 char* IoTRMIUtil::arrByteToByteArray(vector<char> arrByte, char* bytes) {
472
473         int pos = 0;
474         for (char chr : arrByte) {
475                 char tmpBytes[BYTE_LEN];
476                 byteToByteArray(chr, tmpBytes);
477                 memcpy(bytes + pos, tmpBytes, BYTE_LEN);
478                 pos = pos + BYTE_LEN;
479         }
480
481         return bytes;
482 }
483
484
485 char* IoTRMIUtil::arrShortToByteArray(vector<short> arrShort, char* bytes) {
486
487         int pos = 0;
488         for (short& sht : arrShort) {
489                 char tmpBytes[sizeof(short)];
490                 shortToByteArray(sht, tmpBytes);
491                 memcpy(bytes + pos, tmpBytes, sizeof(short));
492                 pos = pos + sizeof(short);
493         }
494
495         return bytes;
496 }
497
498
499 char* IoTRMIUtil::arrIntToByteArray(vector<int> arrInt, char* bytes) {
500
501         int pos = 0;
502         for (int& in : arrInt) {
503                 char tmpBytes[sizeof(int)];
504                 intToByteArray(in, tmpBytes);
505                 memcpy(bytes + pos, tmpBytes, sizeof(int));
506                 pos = pos + sizeof(int);
507         }
508
509         return bytes;
510 }
511
512
513 char* IoTRMIUtil::arrLongToByteArray(vector<int64_t> arrLong, char* bytes) {
514
515         int pos = 0;
516         for (int64_t& lng : arrLong) {
517                 char tmpBytes[sizeof(int64_t)];
518                 longToByteArray(lng, tmpBytes);
519                 memcpy(bytes + pos, tmpBytes, sizeof(int64_t));
520                 pos = pos + sizeof(int64_t);
521         }
522
523         return bytes;
524 }
525
526
527 char* IoTRMIUtil::arrFloatToByteArray(vector<float> arrFloat, char* bytes) {
528
529         int pos = 0;
530         for (float& flt : arrFloat) {
531                 char tmpBytes[sizeof(float)];
532                 floatToByteArray(flt, tmpBytes);
533                 memcpy(bytes + pos, tmpBytes, sizeof(float));
534                 pos = pos + sizeof(float);
535         }
536
537         return bytes;
538 }
539
540
541 char* IoTRMIUtil::arrDoubleToByteArray(vector<double> arrDouble, char* bytes) {
542
543         int pos = 0;
544         for (double& dbl : arrDouble) {
545                 char tmpBytes[sizeof(double)];
546                 doubleToByteArray(dbl, tmpBytes);
547                 memcpy(bytes + pos, tmpBytes, sizeof(double));
548                 pos = pos + sizeof(double);
549         }
550
551         return bytes;
552 }
553
554
555 char* IoTRMIUtil::arrCharToByteArray(vector<char> arrChar, char* bytes) {
556
557         int pos = 0;
558         for (char& chr : arrChar) {
559                 char tmpBytes[CHAR_LEN];
560                 charToByteArray(chr, tmpBytes);
561                 memcpy(bytes + pos, tmpBytes, CHAR_LEN);
562                 pos = pos + CHAR_LEN;
563         }
564
565         return bytes;
566 }
567
568
569 char* IoTRMIUtil::arrBooleanToByteArray(vector<bool> arrBoolean, char* bytes) {
570
571         int pos = 0;
572         for (bool bl : arrBoolean) {
573                 char tmpBytes[BOOL_LEN];
574                 booleanToByteArray(bl, tmpBytes);
575                 memcpy(bytes + pos, tmpBytes, BOOL_LEN);
576                 pos = pos + BOOL_LEN;
577         }
578
579         return bytes;
580 }
581
582
583 char* IoTRMIUtil::arrStringToByteArray(vector<string> arrString, char* bytes) {
584
585         int pos = 0;
586         char strArrLenBytes[PARAM_LEN];
587         intToByteArray(arrString.size(), strArrLenBytes);
588         memcpy(bytes, strArrLenBytes, PARAM_LEN);
589         pos = pos + PARAM_LEN;
590         for (string& str : arrString) {
591
592                 // Copy string length
593                 int strLen = str.length();
594                 char strLenBytes[PARAM_LEN];
595                 intToByteArray(strLen, strLenBytes);
596                 memcpy(bytes + pos, strLenBytes, PARAM_LEN);
597                 pos = pos + PARAM_LEN;
598                 // Copy string
599                 char strBytes[strLen];
600                 stringToByteArray(str, strBytes);
601                 memcpy(bytes + pos, strBytes, strLen);
602                 pos = pos + strLen;
603         }
604
605         return bytes;
606 }
607
608
609 // Bytes to array
610 vector<char>* IoTRMIUtil::byteArrayToByteArray(vector<char>* result, char* bytes, int len) {
611
612         // Single element bytes
613         char elmt[BYTE_LEN];
614         // Prepare vector
615         int arrLen = len/BYTE_LEN;
616         for(int i = 0; i < arrLen; i++) {
617                 int offset = i * BYTE_LEN;
618                 memcpy(elmt, bytes + offset, BYTE_LEN);
619                 char res;
620                 byteArrayToByte(&res, elmt);
621                 result->push_back(res);
622         }
623
624         return result;
625 }
626
627
628 vector<short>* IoTRMIUtil::byteArrayToShortArray(vector<short>* result, char* bytes, int len) {
629
630         // Single element bytes
631         char elmt[sizeof(short)];
632         // Prepare vector
633         int arrLen = len/sizeof(short);
634         for(int i = 0; i < arrLen; i++) {
635                 int offset = i * sizeof(short);
636                 memcpy(elmt, bytes + offset, sizeof(short));
637                 short res = 0;
638                 byteArrayToShort(&res, elmt);
639                 result->push_back(res);
640         }
641
642         return result;
643 }
644
645
646 vector<int>* IoTRMIUtil::byteArrayToIntArray(vector<int>* result, char* bytes, int len) {
647
648         // Single element bytes
649         char elmt[sizeof(int)];
650         // Prepare vector
651         int arrLen = len/sizeof(int);
652         for(int i = 0; i < arrLen; i++) {
653                 int offset = i * sizeof(int);
654                 memcpy(elmt, bytes + offset, sizeof(int));
655                 int res = 0;
656                 byteArrayToInt(&res, elmt);
657                 result->push_back(res);
658         }
659
660         return result;
661 }
662
663
664 vector<int64_t>* IoTRMIUtil::byteArrayToLongArray(vector<int64_t>* result, char* bytes, int len) {
665
666         // Single element bytes
667         char elmt[sizeof(int64_t)];
668         // Prepare vector
669         int arrLen = len/sizeof(int64_t);
670         for(int i = 0; i < arrLen; i++) {
671                 int offset = i * sizeof(int64_t);
672                 memcpy(elmt, bytes + offset, sizeof(int64_t));
673                 int64_t res = 0;
674                 byteArrayToLong(&res, elmt);
675                 result->push_back(res);
676         }
677
678         return result;
679 }
680
681
682 vector<float>* IoTRMIUtil::byteArrayToFloatArray(vector<float>* result, char* bytes, int len) {
683
684         // Single element bytes
685         char elmt[sizeof(float)];
686         // Prepare vector
687         int arrLen = len/sizeof(float);
688         for(int i = 0; i < arrLen; i++) {
689                 int offset = i * sizeof(float);
690                 memcpy(elmt, bytes + offset, sizeof(float));
691                 float res = 0;
692                 byteArrayToFloat(&res, elmt);
693                 result->push_back(res);
694         }
695
696         return result;
697 }
698
699
700 vector<double>* IoTRMIUtil::byteArrayToDoubleArray(vector<double>* result, char* bytes, int len) {
701
702         // Single element bytes
703         char elmt[sizeof(double)];
704         // Prepare vector
705         int arrLen = len/sizeof(double);
706         for(int i = 0; i < arrLen; i++) {
707                 int offset = i * sizeof(double);
708                 memcpy(elmt, bytes + offset, sizeof(double));
709                 double res = 0;
710                 byteArrayToDouble(&res, elmt);
711                 result->push_back(res);
712         }
713
714         return result;
715 }
716
717
718 vector<char>* IoTRMIUtil::byteArrayToCharArray(vector<char>* result, char* bytes, int len) {
719
720         // Single element bytes
721         char elmt[CHAR_LEN];
722         // Prepare vector
723         int arrLen = len/CHAR_LEN;
724         for(int i = 0; i < arrLen; i++) {
725                 int offset = i * CHAR_LEN;
726                 memcpy(elmt, bytes + offset, CHAR_LEN);
727                 char res;
728                 byteArrayToChar(&res, elmt);
729                 result->push_back(res);
730         }
731
732         return result;
733 }
734
735
736 vector<bool>* IoTRMIUtil::byteArrayToBooleanArray(vector<bool>* result, char* bytes, int len) {
737
738         // Single element bytes
739         char elmt[BOOL_LEN];
740         // Prepare vector
741         int arrLen = len/BOOL_LEN;
742         for(int i = 0; i < arrLen; i++) {
743                 int offset = i * BOOL_LEN;
744                 memcpy(elmt, bytes + offset, BOOL_LEN);
745                 bool res = false;
746                 byteArrayToBoolean(&res, elmt);
747                 result->push_back(res);
748         }
749
750         return result;
751 }
752
753
754 vector<string>* IoTRMIUtil::byteArrayToStringArray(vector<string>* result, char* bytes, int len) {
755
756         // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
757         // Get string array length
758         int pos = 0;
759         char strArrLenBytes[PARAM_LEN];
760         memcpy(strArrLenBytes, bytes, PARAM_LEN);
761         int strArrLen = 0;
762         byteArrayToInt(&strArrLen, strArrLenBytes);
763         pos = pos + PARAM_LEN;
764         // Extract array of strings
765         for(int i = 0; i < strArrLen; i++) {
766
767                 // Extract string length
768                 char strLenBytes[PARAM_LEN];
769                 memcpy(strLenBytes, bytes + pos, PARAM_LEN);
770                 int strLen = 0;
771                 byteArrayToInt(&strLen, strLenBytes);
772                 pos = pos + PARAM_LEN;
773                 // Extract string
774                 char strBytes[strLen];
775                 memcpy(strBytes, bytes + pos, strLen);
776                 pos = pos + strLen;
777                 string tmpStr = "";
778                 // Note: Somehow we need to instantiate the string
779                 //              with the length here although we are passing
780                 //              an array of bytes with an exact length
781                 byteArrayToString(&tmpStr, strBytes, strLen);
782                 result->push_back(tmpStr);
783         }
784
785         return result;
786 }
787
788
789 // Conversions
790 // Primitives to byte array
791 char* IoTRMIUtil::byteToByteArray(char c, char* bytes) {
792
793         // Just copy the char into char*
794         bytes[0] = c;
795
796         return bytes;
797 }
798
799
800 char* IoTRMIUtil::shortToByteArray(short s, char* bytes) {
801
802         short sInvert = htobe16(s);
803         //short sInvert = htons(s);
804         memcpy(bytes, &sInvert, sizeof(short));
805
806         return bytes;
807 }
808
809
810 char* IoTRMIUtil::intToByteArray(int i, char* bytes) {
811
812         int iInvert = htobe32(i);
813         //int iInvert = htonl(i);
814         memcpy(bytes, &iInvert, sizeof(int));
815
816         return bytes;
817 }
818
819
820 char* IoTRMIUtil::longToByteArray(int64_t l, char* bytes) {
821
822         int64_t lInvert = htobe64(l);
823         memcpy(bytes, &lInvert, sizeof(int64_t));
824
825         return bytes;
826 }
827
828
829 char* IoTRMIUtil::floatToByteArray(float f, char* bytes) {
830
831         // Copy to int to allow the usage of htobeXX() functions
832         int i = 0;
833         memcpy(&i, &f, sizeof(float));
834         int iInvert = htobe32(i);
835         memcpy(bytes, &iInvert, sizeof(int));
836         
837         return bytes;
838 }
839
840
841 char* IoTRMIUtil::doubleToByteArray(double d, char* bytes) {
842
843         // Copy to int to allow the usage of htobeXX() functions
844         int64_t i = 0;
845         memcpy(&i, &d, sizeof(double));
846         int64_t iInvert = htobe64(i);
847         memcpy(bytes, &iInvert, sizeof(int64_t));
848         
849         return bytes;
850 }
851
852
853 char* IoTRMIUtil::charToByteArray(char c, char* bytes) {
854
855         // We need 2 bytes to accommodate Java char type, whose size is 2
856         bytes[0] = 0;
857         bytes[1] = c;
858
859         return bytes;
860 }
861
862
863 char* IoTRMIUtil::booleanToByteArray(bool b, char* bytes) {
864
865         bytes[0] = (b) ? 1 : 0;
866         return bytes;
867 }
868
869
870 char* IoTRMIUtil::stringToByteArray(string str, char* bytes) {
871
872         strcpy(bytes, str.c_str());
873         return bytes;
874 }
875
876
877 // Conversions
878 // Byte array to primitives
879 short* IoTRMIUtil::byteArrayToShort(short* result, char* bytes) {
880
881         short s = 0;
882         memcpy(&s, bytes, sizeof(short));
883         //short result = be16toh(s);
884         *result = be16toh(s);
885
886         return result;
887 }
888
889
890 int* IoTRMIUtil::byteArrayToInt(int* result, char* bytes) {
891
892         int i = 0;
893         memcpy(&i, bytes, sizeof(int));
894         *result = be32toh(i);
895
896         return result;
897 }
898
899
900 int64_t* IoTRMIUtil::byteArrayToLong(int64_t* result, char* bytes) {
901
902         int64_t l = 0;
903         memcpy(&l, bytes, sizeof(int64_t));
904         *result = be64toh(l);
905
906         return result;
907 }
908
909
910 float* IoTRMIUtil::byteArrayToFloat(float* result, char* bytes) {
911
912         // Copy to int to allow the usage of beXXtoh() functions
913         int i = 0;
914         memcpy(&i, bytes, sizeof(int));
915         int iInvert = be32toh(i);
916         memcpy(result, &iInvert, sizeof(float));
917
918         return result;
919 }
920
921
922 double* IoTRMIUtil::byteArrayToDouble(double* result, char* bytes) {
923
924         // Copy to int to allow the usage of beXXtoh() functions
925         int64_t i = 0;
926         memcpy(&i, bytes, sizeof(int64_t));
927         int64_t iInvert = be64toh(i);
928         memcpy(result, &iInvert, sizeof(double));
929
930         return result;
931 }
932
933
934 char* IoTRMIUtil::byteArrayToByte(char* result, char* bytes) {
935
936         *result = bytes[0];
937         return result;
938 }
939
940
941 char* IoTRMIUtil::byteArrayToChar(char* result, char* bytes) {
942
943         *result = bytes[1];
944         return result;
945 }
946
947
948 bool* IoTRMIUtil::byteArrayToBoolean(bool* result, char* bytes) {
949
950         *result = (bytes[0]) ? true : false;
951         return result;
952 }
953
954
955 string* IoTRMIUtil::byteArrayToString(string* result, char* bytes) {
956
957         *result = string(bytes);
958         return result;
959 }
960
961
962 string* IoTRMIUtil::byteArrayToString(string* result, char* bytes, int strLen) {
963
964         *result = string(bytes, strLen);
965         return result;
966 }
967
968
969 #endif