Completing stub and skeleton sides' APIs; Adding tests for C++ side; Still need to...
[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, int len);
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*    getArrayParamObject(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, int len) {
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, len);
236         } else if ( string(type).find("[]") != string::npos) {
237                 // This is an array type, i.e. vector
238                 retObj = getArrayParamObject(retObj, type, paramBytes, len);
239         } else {
240                 string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
241                 throw error;
242         }
243
244         return retObj;
245 }
246
247
248 // Get array of objects from byte array - overload getParamObject function
249 void* IoTRMIUtil::getArrayParamObject(void* retObj, const char* type, char* paramBytes, int len) {
250
251         if (strcmp(type, "byte[]") == 0) {
252                 retObj = (vector<char>*) paramBytes;
253         } else if (strcmp(type, "short[]") == 0) {
254                 retObj = byteArrayToShortArray((vector<short>*) retObj, paramBytes, len);
255         } else if (strcmp(type, "int[]") == 0) {
256                 retObj = byteArrayToIntArray((vector<int>*) retObj, paramBytes, len);
257         } else if (strcmp(type, "long[]") == 0) {
258                 retObj = byteArrayToLongArray((vector<int64_t>*) retObj, paramBytes, len);
259         } else if (strcmp(type, "float[]") == 0) {
260                 retObj = byteArrayToFloatArray((vector<float>*) retObj, paramBytes, len);
261         } else if (strcmp(type, "double[]") == 0) {
262                 retObj = byteArrayToDoubleArray((vector<double>*) retObj, paramBytes, len);
263         } else if (strcmp(type, "bool[]") == 0) {
264                 retObj = byteArrayToBooleanArray((vector<bool>*) retObj, paramBytes, len);
265         } else if (strcmp(type, "char[]") == 0) {
266                 retObj = byteArrayToCharArray((vector<char>*) retObj, paramBytes, len);
267         } else if (strcmp(type, "string[]") == 0) {
268                 retObj = byteArrayToStringArray((vector<string>*) retObj, paramBytes, len);
269         } else {
270                 string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
271                 throw error;
272         }
273
274         return retObj;
275 }
276
277
278 // Getting byte array based on parameter and its type
279 char* IoTRMIUtil::getObjectBytes(char* retObjBytes, void* obj, const char* type) {
280
281         if (strcmp(type, "b") == 0 ||
282                 strcmp(type, "byte") == 0) {
283                 retObjBytes = (char*) obj;
284         } else if ( strcmp(type, "s") == 0 ||
285                                 strcmp(type, "short") == 0) {
286                 retObjBytes = shortToByteArray(*((short*) obj), retObjBytes);
287         } else if ( strcmp(type, "i") == 0 ||
288                                 strcmp(type, "int") == 0) {
289                 retObjBytes = intToByteArray(*((int*) obj), retObjBytes);
290         } else if ( strcmp(type, "l") == 0 ||
291                                 strcmp(type, "long") == 0) {
292                 retObjBytes = longToByteArray(*((int64_t*) obj), retObjBytes);
293         } else if ( strcmp(type, "f") == 0 ||
294                                 strcmp(type, "float") == 0) {
295                 retObjBytes = floatToByteArray(*((float*) obj), retObjBytes);
296         } else if ( strcmp(type, "d") == 0 ||
297                                 strcmp(type, "double") == 0) {
298                 retObjBytes = doubleToByteArray(*((double*) obj), retObjBytes);
299         } else if ( strcmp(type, "b") == 0 ||
300                                 strcmp(type, "bool") == 0) {
301                 retObjBytes = booleanToByteArray(*((bool*) obj), retObjBytes);
302         } else if ( strcmp(type, "c") == 0 ||
303                                 strcmp(type, "char") == 0) {
304                 retObjBytes = charToByteArray(*((char*) obj), retObjBytes);
305         } else if ( strcmp(type, "Ss") == 0 ||
306                                 strcmp(type, "string") == 0) {
307                 retObjBytes = stringToByteArray(*((string*) obj), retObjBytes);
308         } else if ( string(type).find("[]") != string::npos) {
309         // This is an array type, i.e. vector
310                 retObjBytes = getArrayObjectBytes(retObjBytes, obj, type);
311         } else {
312                 string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
313                 throw error;
314         }
315
316         return retObjBytes;
317 }
318
319
320 // Getting byte array for arrays of primitives
321 char* IoTRMIUtil::getArrayObjectBytes(char* retObjBytes, void* obj, const char* type) {
322
323         if (strcmp(type, "byte[]") == 0) {
324                 retObjBytes = (char*) obj;
325         } else if (strcmp(type, "short[]") == 0) {
326                 retObjBytes = arrShortToByteArray(*((vector<short>*) obj), retObjBytes);
327         } else if (strcmp(type, "int[]") == 0) {
328                 retObjBytes = arrIntToByteArray(*((vector<int>*) obj), retObjBytes);
329         } else if (strcmp(type, "long[]") == 0) {
330                 retObjBytes = arrLongToByteArray(*((vector<int64_t>*) obj), retObjBytes);
331         } else if (strcmp(type, "float[]") == 0) {
332                 retObjBytes = arrFloatToByteArray(*((vector<float>*) obj), retObjBytes);
333         } else if (strcmp(type, "double[]") == 0) {
334                 retObjBytes = arrDoubleToByteArray(*((vector<double>*) obj), retObjBytes);
335         } else if (strcmp(type, "bool[]") == 0) {
336                 retObjBytes = arrBooleanToByteArray(*((vector<bool>*) obj), retObjBytes);
337         } else if (strcmp(type, "char[]") == 0) {
338                 retObjBytes = arrCharToByteArray(*((vector<char>*) obj), retObjBytes);
339         } else if (strcmp(type, "string[]") == 0) {
340                 retObjBytes = arrStringToByteArray(*((vector<string>*) obj), retObjBytes);
341         } else {
342                 string error = "IoTRMIUtil: Unrecognizable type: " + string(type);
343                 throw error;
344         }
345
346         return retObjBytes;
347 }
348
349
350 // Conversions
351 // Array handlers - we use vector data type and not traditional arrays
352 // Array to bytes
353 char* IoTRMIUtil::arrShortToByteArray(vector<short> arrShort, char* bytes) {
354
355         int pos = 0;
356         for (short& sht : arrShort) {
357                 char tmpBytes[sizeof(short)];
358                 shortToByteArray(sht, tmpBytes);
359                 memcpy(bytes + pos, tmpBytes, sizeof(short));
360                 pos = pos + sizeof(short);
361         }
362
363         return bytes;
364 }
365
366
367 char* IoTRMIUtil::arrIntToByteArray(vector<int> arrInt, char* bytes) {
368
369         int pos = 0;
370         for (int& in : arrInt) {
371                 char tmpBytes[sizeof(int)];
372                 intToByteArray(in, tmpBytes);
373                 memcpy(bytes + pos, tmpBytes, sizeof(int));
374                 pos = pos + sizeof(int);
375         }
376
377         return bytes;
378 }
379
380
381 char* IoTRMIUtil::arrLongToByteArray(vector<int64_t> arrLong, char* bytes) {
382
383         int pos = 0;
384         for (int64_t& lng : arrLong) {
385                 char tmpBytes[sizeof(int64_t)];
386                 longToByteArray(lng, tmpBytes);
387                 memcpy(bytes + pos, tmpBytes, sizeof(int64_t));
388                 pos = pos + sizeof(int64_t);
389         }
390
391         return bytes;
392 }
393
394
395 char* IoTRMIUtil::arrFloatToByteArray(vector<float> arrFloat, char* bytes) {
396
397         int pos = 0;
398         for (float& flt : arrFloat) {
399                 char tmpBytes[sizeof(float)];
400                 floatToByteArray(flt, tmpBytes);
401                 memcpy(bytes + pos, tmpBytes, sizeof(float));
402                 pos = pos + sizeof(float);
403         }
404
405         return bytes;
406 }
407
408
409 char* IoTRMIUtil::arrDoubleToByteArray(vector<double> arrDouble, char* bytes) {
410
411         int pos = 0;
412         for (double& dbl : arrDouble) {
413                 char tmpBytes[sizeof(double)];
414                 doubleToByteArray(dbl, tmpBytes);
415                 memcpy(bytes + pos, tmpBytes, sizeof(double));
416                 pos = pos + sizeof(double);
417         }
418
419         return bytes;
420 }
421
422
423 char* IoTRMIUtil::arrCharToByteArray(vector<char> arrChar, char* bytes) {
424
425         int pos = 0;
426         for (char& chr : arrChar) {
427                 char tmpBytes[CHAR_LEN];
428                 charToByteArray(chr, tmpBytes);
429                 memcpy(bytes + pos, tmpBytes, CHAR_LEN);
430                 pos = pos + CHAR_LEN;
431         }
432
433         return bytes;
434 }
435
436
437 char* IoTRMIUtil::arrBooleanToByteArray(vector<bool> arrBoolean, char* bytes) {
438
439         int pos = 0;
440         for (bool bl : arrBoolean) {
441                 char tmpBytes[BOOL_LEN];
442                 booleanToByteArray(bl, tmpBytes);
443                 memcpy(bytes + pos, tmpBytes, BOOL_LEN);
444                 pos = pos + BOOL_LEN;
445         }
446
447         return bytes;
448 }
449
450
451 char* IoTRMIUtil::arrStringToByteArray(vector<string> arrString, char* bytes) {
452
453         int pos = 0;
454         char strArrLenBytes[PARAM_LEN];
455         intToByteArray(arrString.size(), strArrLenBytes);
456         memcpy(bytes, strArrLenBytes, PARAM_LEN);
457         pos = pos + PARAM_LEN;
458         for (string& str : arrString) {
459
460                 // Copy string length
461                 int strLen = str.length();
462                 char strLenBytes[PARAM_LEN];
463                 intToByteArray(strLen, strLenBytes);
464                 memcpy(bytes + pos, strLenBytes, PARAM_LEN);
465                 pos = pos + PARAM_LEN;
466                 // Copy string
467                 char strBytes[strLen];
468                 stringToByteArray(str, strBytes);
469                 memcpy(bytes + pos, strBytes, strLen);
470                 pos = pos + strLen;
471         }
472
473         return bytes;
474 }
475
476
477 // Bytes to array
478 vector<short>* IoTRMIUtil::byteArrayToShortArray(vector<short>* result, char* bytes, int len) {
479
480         // Single element bytes
481         char elmt[sizeof(short)];
482         // Prepare vector
483         int arrLen = len/sizeof(short);
484         for(int i = 0; i < arrLen; i++) {
485                 int offset = i * sizeof(short);
486                 memcpy(elmt, bytes + offset, sizeof(short));
487                 short res = 0;
488                 byteArrayToShort(&res, elmt);
489                 result->push_back(res);
490         }
491
492         return result;
493 }
494
495
496 vector<int>* IoTRMIUtil::byteArrayToIntArray(vector<int>* result, char* bytes, int len) {
497
498         // Single element bytes
499         char elmt[sizeof(int)];
500         // Prepare vector
501         int arrLen = len/sizeof(int);
502         for(int i = 0; i < arrLen; i++) {
503                 int offset = i * sizeof(int);
504                 memcpy(elmt, bytes + offset, sizeof(int));
505                 int res = 0;
506                 byteArrayToInt(&res, elmt);
507                 result->push_back(res);
508         }
509
510         return result;
511 }
512
513
514 vector<int64_t>* IoTRMIUtil::byteArrayToLongArray(vector<int64_t>* result, char* bytes, int len) {
515
516         // Single element bytes
517         char elmt[sizeof(int64_t)];
518         // Prepare vector
519         int arrLen = len/sizeof(int64_t);
520         for(int i = 0; i < arrLen; i++) {
521                 int offset = i * sizeof(int64_t);
522                 memcpy(elmt, bytes + offset, sizeof(int64_t));
523                 int64_t res = 0;
524                 byteArrayToLong(&res, elmt);
525                 result->push_back(res);
526         }
527
528         return result;
529 }
530
531
532 vector<float>* IoTRMIUtil::byteArrayToFloatArray(vector<float>* result, char* bytes, int len) {
533
534         // Single element bytes
535         char elmt[sizeof(float)];
536         // Prepare vector
537         int arrLen = len/sizeof(float);
538         for(int i = 0; i < arrLen; i++) {
539                 int offset = i * sizeof(float);
540                 memcpy(elmt, bytes + offset, sizeof(float));
541                 float res = 0;
542                 byteArrayToFloat(&res, elmt);
543                 result->push_back(res);
544         }
545
546         return result;
547 }
548
549
550 vector<double>* IoTRMIUtil::byteArrayToDoubleArray(vector<double>* result, char* bytes, int len) {
551
552         // Single element bytes
553         char elmt[sizeof(double)];
554         // Prepare vector
555         int arrLen = len/sizeof(double);
556         for(int i = 0; i < arrLen; i++) {
557                 int offset = i * sizeof(double);
558                 memcpy(elmt, bytes + offset, sizeof(double));
559                 double res = 0;
560                 byteArrayToDouble(&res, elmt);
561                 result->push_back(res);
562         }
563
564         return result;
565 }
566
567
568 vector<char>* IoTRMIUtil::byteArrayToCharArray(vector<char>* result, char* bytes, int len) {
569
570         // Single element bytes
571         char elmt[CHAR_LEN];
572         // Prepare vector
573         int arrLen = len/CHAR_LEN;
574         for(int i = 0; i < arrLen; i++) {
575                 int offset = i * CHAR_LEN;
576                 memcpy(elmt, bytes + offset, CHAR_LEN);
577                 char res;
578                 byteArrayToChar(&res, elmt);
579                 result->push_back(res);
580         }
581
582         return result;
583 }
584
585
586 vector<bool>* IoTRMIUtil::byteArrayToBooleanArray(vector<bool>* result, char* bytes, int len) {
587
588         // Single element bytes
589         char elmt[BOOL_LEN];
590         // Prepare vector
591         int arrLen = len/BOOL_LEN;
592         for(int i = 0; i < arrLen; i++) {
593                 int offset = i * BOOL_LEN;
594                 memcpy(elmt, bytes + offset, BOOL_LEN);
595                 bool res = false;
596                 byteArrayToBoolean(&res, elmt);
597                 result->push_back(res);
598         }
599
600         return result;
601 }
602
603
604 vector<string>* IoTRMIUtil::byteArrayToStringArray(vector<string>* result, char* bytes, int len) {
605
606         // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
607         // Get string array length
608         int pos = 0;
609         char strArrLenBytes[PARAM_LEN];
610         memcpy(strArrLenBytes, bytes, PARAM_LEN);
611         int strArrLen = 0;
612         byteArrayToInt(&strArrLen, strArrLenBytes);
613         pos = pos + PARAM_LEN;
614         // Extract array of strings
615         for(int i = 0; i < strArrLen; i++) {
616
617                 // Extract string length
618                 char strLenBytes[PARAM_LEN];
619                 memcpy(strLenBytes, bytes + pos, PARAM_LEN);
620                 int strLen = 0;
621                 byteArrayToInt(&strLen, strLenBytes);
622                 pos = pos + PARAM_LEN;
623                 // Extract string
624                 char strBytes[strLen];
625                 memcpy(strBytes, bytes + pos, strLen);
626                 pos = pos + strLen;
627                 string tmpStr = "";
628                 // Note: Somehow we need to instantiate the string
629                 //              with the length here although we are passing
630                 //              an array of bytes with an exact length
631                 byteArrayToString(&tmpStr, strBytes, strLen);
632                 result->push_back(tmpStr);
633         }
634
635         return result;
636 }
637
638
639 // Conversions
640 // Primitives to byte array
641 char* IoTRMIUtil::shortToByteArray(short s, char* bytes) {
642
643         short sInvert = htobe16(s);
644         //short sInvert = htons(s);
645         memcpy(bytes, &sInvert, sizeof(short));
646
647         return bytes;
648 }
649
650
651 char* IoTRMIUtil::intToByteArray(int i, char* bytes) {
652
653         int iInvert = htobe32(i);
654         //int iInvert = htonl(i);
655         memcpy(bytes, &iInvert, sizeof(int));
656
657         return bytes;
658 }
659
660
661 char* IoTRMIUtil::longToByteArray(int64_t l, char* bytes) {
662
663         int64_t lInvert = htobe64(l);
664         memcpy(bytes, &lInvert, sizeof(int64_t));
665
666         return bytes;
667 }
668
669
670 char* IoTRMIUtil::floatToByteArray(float f, char* bytes) {
671
672         // Copy to int to allow the usage of htobeXX() functions
673         int i = 0;
674         memcpy(&i, &f, sizeof(float));
675         int iInvert = htobe32(i);
676         memcpy(bytes, &iInvert, sizeof(int));
677         
678         return bytes;
679 }
680
681
682 char* IoTRMIUtil::doubleToByteArray(double d, char* bytes) {
683
684         // Copy to int to allow the usage of htobeXX() functions
685         int64_t i = 0;
686         memcpy(&i, &d, sizeof(double));
687         int64_t iInvert = htobe64(i);
688         memcpy(bytes, &iInvert, sizeof(int64_t));
689         
690         return bytes;
691 }
692
693
694 char* IoTRMIUtil::charToByteArray(char c, char* bytes) {
695
696         // We need 2 bytes to accommodate Java char type, whose size is 2
697         bytes[0] = 0;
698         bytes[1] = c;
699
700         return bytes;
701 }
702
703
704 char* IoTRMIUtil::booleanToByteArray(bool b, char* bytes) {
705
706         bytes[0] = (b) ? 1 : 0;
707         return bytes;
708 }
709
710
711 char* IoTRMIUtil::stringToByteArray(string str, char* bytes) {
712
713         strcpy(bytes, str.c_str());
714         return bytes;
715 }
716
717
718 // Conversions
719 // Byte array to primitives
720 short* IoTRMIUtil::byteArrayToShort(short* result, char* bytes) {
721
722         short s = 0;
723         memcpy(&s, bytes, sizeof(short));
724         //short result = be16toh(s);
725         *result = be16toh(s);
726
727         return result;
728 }
729
730
731 int* IoTRMIUtil::byteArrayToInt(int* result, char* bytes) {
732
733         int i = 0;
734         memcpy(&i, bytes, sizeof(int));
735         *result = be32toh(i);
736
737         return result;
738 }
739
740
741 int64_t* IoTRMIUtil::byteArrayToLong(int64_t* result, char* bytes) {
742
743         int64_t l = 0;
744         memcpy(&l, bytes, sizeof(int64_t));
745         *result = be64toh(l);
746
747         return result;
748 }
749
750
751 float* IoTRMIUtil::byteArrayToFloat(float* result, char* bytes) {
752
753         // Copy to int to allow the usage of beXXtoh() functions
754         int i = 0;
755         memcpy(&i, bytes, sizeof(int));
756         int iInvert = be32toh(i);
757         memcpy(result, &iInvert, sizeof(float));
758
759         return result;
760 }
761
762
763 double* IoTRMIUtil::byteArrayToDouble(double* result, char* bytes) {
764
765         // Copy to int to allow the usage of beXXtoh() functions
766         int64_t i = 0;
767         memcpy(&i, bytes, sizeof(int64_t));
768         int64_t iInvert = be64toh(i);
769         memcpy(result, &iInvert, sizeof(double));
770
771         return result;
772 }
773
774
775 char* IoTRMIUtil::byteArrayToChar(char* result, char* bytes) {
776
777         *result = bytes[1];
778         return result;
779 }
780
781
782 bool* IoTRMIUtil::byteArrayToBoolean(bool* result, char* bytes) {
783
784         *result = (bytes[0]) ? true : false;
785         return result;
786 }
787
788
789 string* IoTRMIUtil::byteArrayToString(string* result, char* bytes) {
790
791         *result = string(bytes);
792         return result;
793 }
794
795
796 string* IoTRMIUtil::byteArrayToString(string* result, char* bytes, int strLen) {
797
798         *result = string(bytes, strLen);
799         return result;
800 }
801
802
803 #endif