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