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