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