781610600d890f2a4916f74aed4a065059f2f1f1
[iot2.git] / iotjava / iotrmi / Java / IoTRMIUtil.java
1 package iotrmi.Java;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.io.ObjectInputStream;
7 import java.io.ObjectOutputStream;
8 import java.nio.ByteBuffer;
9 import java.util.Arrays;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18
19
20 /** Class IoTRMI provides utility services.
21  *  <p>
22  *  It provides miscellaneous (data type/value) translations.
23  *
24  * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
25  * @version     1.0
26  * @since       2016-10-04
27  */
28 public class IoTRMIUtil {
29
30         /**
31          * Class Properties
32          */
33         private Map<String,String> mapPrimitives;
34         private Map<String,Integer> mapPrimitiveSizesJava;
35         private Map<String,Integer> mapPrimitiveSizesCplus;
36         private Map<String,String> mapNonPrimitives;
37
38         /**
39          * Class Constants
40          */
41         public final static int METHOD_ID_LEN = 4;      // 4 bytes = 32 bits
42         public final static int PARAM_LEN = 4;          // 4 bytes = 32 bits (4-byte field that stores the length of the param)
43
44         public final static int SHT_LEN = 2;
45         public final static int INT_LEN = 4;
46         public final static int LNG_LEN = 8;
47         public final static int FLT_LEN = 4;
48         public final static int DBL_LEN = 8;
49         public final static int CHR_LEN = 2;
50         public final static int BYT_LEN = 1;
51         public final static int BOL_LEN = 1;
52
53         /**
54          * Constructors
55          */
56         public IoTRMIUtil() {
57
58                 mapPrimitives = new HashMap<String,String>();
59                         IoTRMITypes.arraysToMap(mapPrimitives, 
60                                 IoTRMITypes.primitivesJava, IoTRMITypes.primitivesCplus);
61                 mapPrimitiveSizesJava = new HashMap<String,Integer>();
62                         IoTRMITypes.arraysToMap(mapPrimitiveSizesJava, 
63                                 IoTRMITypes.primitivesJava, IoTRMITypes.primitivesJavaSizes);
64                 mapPrimitiveSizesCplus = new HashMap<String,Integer>();
65                         IoTRMITypes.arraysToMap(mapPrimitiveSizesCplus, 
66                                 IoTRMITypes.primitivesCplus, IoTRMITypes.primitivesCplusSizes);
67                 mapNonPrimitives = new HashMap<String,String>();
68                         IoTRMITypes.arraysToMap(mapNonPrimitives, 
69                                 IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
70         }
71
72
73         /**
74          * getHashCodeBytes() gets hash value (in bytes) from method name
75          */
76         public static byte[] getHashCodeBytes(String string) {
77
78                 int hash = string.hashCode();
79                 byte[] hashBytes = ByteBuffer.allocate(4).putInt(hash).array();
80                 return hashBytes;
81         }
82
83
84         /**================
85          * Helper methods
86          **================
87          */
88         /**
89          * translateType() try to translate a type
90          * <p>
91          * It returns the original type when fails.
92          */
93         public String translateType(String type) {
94
95                 if (mapPrimitives.containsKey(type))
96                         return mapPrimitives.get(type);
97                 else if (mapNonPrimitives.containsKey(type))
98                         return mapNonPrimitives.get(type);
99                 else
100                         return type;
101         }
102
103
104         /**
105          * getTypeSize() gets the size of a type
106          *
107          */
108         public int getTypeSize(String type) {
109
110                 if (mapPrimitiveSizesJava.containsKey(type))
111                         return mapPrimitiveSizesJava.get(type);
112                 else if (mapPrimitiveSizesCplus.containsKey(type))
113                         return mapPrimitiveSizesCplus.get(type);
114                 else
115                         return -1; // Size is unknown
116         }
117         
118
119         /**
120          * getTypeSize() gets the size of a type
121          *
122          */
123         public static int getTypeSize(Class<?> type) {
124
125                 int size = 0;
126                 if (type == byte.class) {
127                         size = BYT_LEN;
128                 } else if (type == Byte.class) {
129                         size = BYT_LEN;
130                 } else if (type == short.class) {
131                         size = SHT_LEN;
132                 } else if (type == Short.class) {
133                         size = SHT_LEN;
134                 } else if (     type == int.class) {
135                         size = INT_LEN;
136                 } else if (     type == Integer.class) {
137                         size = INT_LEN;
138                 } else if (     type == long.class) {
139                         size = LNG_LEN;
140                 } else if (     type == Long.class) {
141                         size = LNG_LEN;
142                 } else if (     type == float.class) {
143                         size = FLT_LEN;
144                 } else if (     type == Float.class) {
145                         size = FLT_LEN;
146                 } else if (     type == double.class) {
147                         size = DBL_LEN;
148                 } else if ( type == Double.class) {
149                         size = DBL_LEN;
150                 } else if (     type == boolean.class) {
151                         size = BOL_LEN;
152                 } else if (     type == Boolean.class) {
153                         size = BOL_LEN;
154                 } else if (     type == char.class) {
155                         size = CHR_LEN;
156                 } else if (     type == Character[].class) {
157                         size = CHR_LEN;
158                 } else if (type == String[].class) {
159                         size = -1;
160                 } else
161                         throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
162
163                 return size;
164         }
165
166         
167         /**
168          * getParamObject() converts byte array of certain object type into Object
169          */
170         public static Object getParamObject(Class<?> type, Class<?> genTypeKey, Class<?> genTypeVal, byte[] paramBytes) {
171                 
172                 Object retObj = null;
173                 if (type == byte.class ||
174                         type == Byte.class) {
175                         retObj = (Object) paramBytes[0];
176                 } else if (     type == short.class ||
177                                         type == Short.class) {
178                         retObj = (Object) byteArrayToShort(paramBytes);
179                 } else if (     type == int.class ||
180                                         type == Integer.class) {
181                         retObj = (Object) byteArrayToInt(paramBytes);
182                 } else if (     type == long.class ||
183                                         type == Long.class) {
184                         retObj = (Object) byteArrayToLong(paramBytes);
185                 } else if (     type == float.class ||
186                                         type == Float.class) {
187                         retObj = (Object) byteArrayToFloat(paramBytes);
188                 } else if (     type == double.class ||
189                                         type == Double.class) {
190                         retObj = (Object) byteArrayToDouble(paramBytes);
191                 } else if (     type == boolean.class ||
192                                         type == Boolean.class) {
193                         retObj = (Object) byteArrayToBoolean(paramBytes);
194                 } else if (     type == char.class ||
195                                         type == Character.class) {
196                         retObj = (Object) byteArrayToChar(paramBytes);
197                 } else if (type == String.class) {
198                         retObj = (Object) byteArrayToString(paramBytes);
199                 // Array
200                 } else if (type.isArray()) {
201                         retObj = getParamObjectArray(type, paramBytes);
202                 // Set
203                 // e.g. Set<String> - type = Set.class, genTypeVal = String.class
204                 } else if (type == Set.class) {
205                         retObj = getParamSetObject(genTypeVal, paramBytes);
206                 // List
207                 } else if (type == List.class) {
208                         retObj = getParamListObject(genTypeVal, paramBytes);
209                 // Map
210                 // e.g. Map<String,Integer> - type = Map.class, genTypeKey = String.class, genTypeVal = Integer.class
211                 } else if (type == Map.class) {
212                         retObj = getParamMapObject(genTypeKey, genTypeVal, paramBytes);
213                 } else
214                         throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
215                 
216                 return retObj;
217         }
218
219
220         /**
221          * getParamObjectArray() converts byte array of certain object type into array of Objects
222          */
223         public static Object getParamObjectArray(Class<?> type, byte[] paramBytes) {
224                 
225                 Object retObj = null;
226                 if ((type == byte[].class)      ||
227                         (type == byte.class)) {
228                         retObj = (Object) paramBytes;
229                 } else if ( (type == Byte[].class) ||
230                                         (type == Byte.class)) {
231                         retObj = (Object) byteArrayToByteArray(paramBytes);
232                 } else if ( (type == short[].class) ||
233                                         (type == short.class)) {
234                         retObj = (Object) byteArrayToShtArray(paramBytes);
235                 } else if ( (type == Short[].class) ||
236                                         (type == Short.class)) {
237                         retObj = (Object) byteArrayToShortArray(paramBytes);
238                 } else if (     (type == int[].class) ||
239                                         (type == int.class)) {
240                         retObj = (Object) byteArrayToIntArray(paramBytes);
241                 } else if (     (type == Integer[].class) ||
242                                         (type == Integer.class)) {
243                         retObj = (Object) byteArrayToIntegerArray(paramBytes);
244                 } else if (     (type == long[].class) ||
245                                         (type == long.class)) {
246                         retObj = (Object) byteArrayToLngArray(paramBytes);
247                 } else if (     (type == Long[].class) ||
248                                         (type == Long.class)) {
249                         retObj = (Object) byteArrayToLongArray(paramBytes);
250                 } else if (     (type == float[].class) ||
251                                         (type == float.class)) {
252                         retObj = (Object) byteArrayToFltArray(paramBytes);
253                 } else if (     (type == Float[].class) ||
254                                         (type == Float.class)) {
255                         retObj = (Object) byteArrayToFloatArray(paramBytes);
256                 } else if (     (type == double[].class) ||
257                                         (type == double.class)) {
258                         retObj = (Object) byteArrayToDblArray(paramBytes);
259                 } else if ( (type == Double[].class) ||
260                                         (type == Double.class)) {
261                         retObj = (Object) byteArrayToDoubleArray(paramBytes);
262                 } else if (     (type == boolean[].class) || 
263                                         (type == boolean.class)) {
264                         retObj = (Object) byteArrayToBolArray(paramBytes);
265                 } else if (     (type == Boolean[].class) ||
266                                         (type == Boolean.class)) {
267                         retObj = (Object) byteArrayToBooleanArray(paramBytes);
268                 } else if (     (type == char[].class) ||
269                                         (type == char.class)) {
270                         retObj = (Object) byteArrayToChrArray(paramBytes);
271                 } else if (     (type == Character[].class) ||
272                                         (type == Character.class)) {
273                         retObj = (Object) byteArrayToCharacterArray(paramBytes);
274                 } else if ( (type == String[].class) ||
275                                         (type == String.class)) {
276                         retObj = (Object) byteArrayToStringArray(paramBytes);
277                 } else
278                         throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
279                 
280                 return retObj;
281         }
282
283
284         /**
285          * getObjectBytes() converts an object into byte array
286          */
287         public static byte[] getObjectBytes(Object obj) {
288                 
289                 byte[] retObjBytes = null;
290                 if (obj instanceof Byte) {
291                         retObjBytes = (byte[]) obj;
292                 } else if (obj instanceof Short) {
293                         retObjBytes = shortToByteArray((short) obj);
294                 } else if (obj instanceof Integer) {
295                         retObjBytes = intToByteArray((int) obj);
296                 } else if (obj instanceof Long) {
297                         retObjBytes = longToByteArray((long) obj);
298                 } else if (obj instanceof Float) {
299                         retObjBytes = floatToByteArray((float) obj);
300                 } else if (obj instanceof Double) {
301                         retObjBytes = doubleToByteArray((double) obj);
302                 } else if (obj instanceof Character) {
303                         retObjBytes = charToByteArray((char) obj);
304                 } else if (obj instanceof Boolean) {
305                         retObjBytes = booleanToByteArray((boolean) obj);
306                 } else if (obj instanceof String) {
307                         retObjBytes = stringToByteArray((String) obj);
308                 // Arrays
309                 } else if (obj.getClass().isArray()) {
310                         retObjBytes = getArrayObjectBytes(obj);
311                 // Set and its implementations
312                 } else if (obj instanceof Set<?>) {
313                         retObjBytes = setToByteArray((Set<?>) obj);
314                 // List and its implementations
315                 } else if (obj instanceof List<?>) {
316                         retObjBytes = listToByteArray((List<?>) obj);
317                 // Map and its implementations
318                 } else if (obj instanceof Map<?,?>) {
319                         retObjBytes = mapToByteArray((Map<?,?>) obj);
320                 } else
321                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
322
323                 return retObjBytes;
324         }
325
326
327         /**
328          * getArrayObjectBytes() converts array of objects into bytes array
329          */
330         public static byte[] getArrayObjectBytes(Object obj) {
331
332                 byte[] retObjBytes = null;
333                 if (obj instanceof byte[]) {
334                         retObjBytes = (byte[]) obj;
335                 } else if (obj instanceof Byte[]) {
336                         retObjBytes = arrByteToByteArray((Byte[]) obj);
337                 } else if (obj instanceof short[]) {
338                         retObjBytes = arrShortToByteArray((short[]) obj);
339                 } else if (obj instanceof Short[]) {
340                         retObjBytes = arrShortToByteArray((Short[]) obj);
341                 } else if (obj instanceof int[]) {
342                         retObjBytes = arrIntToByteArray((int[]) obj);
343                 } else if (obj instanceof Integer[]) {
344                         retObjBytes = arrIntToByteArray((Integer[]) obj);
345                 } else if (obj instanceof long[]) {
346                         retObjBytes = arrLongToByteArray((long[]) obj);
347                 } else if (obj instanceof Long[]) {
348                         retObjBytes = arrLongToByteArray((Long[]) obj);
349                 } else if (obj instanceof float[]) {
350                         retObjBytes = arrFloatToByteArray((float[]) obj);
351                 } else if (obj instanceof Float[]) {
352                         retObjBytes = arrFloatToByteArray((Float[]) obj);
353                 } else if (obj instanceof double[]) {
354                         retObjBytes = arrDoubleToByteArray((double[]) obj);
355                 } else if (obj instanceof Double[]) {
356                         retObjBytes = arrDoubleToByteArray((Double[]) obj);
357                 } else if (obj instanceof char[]) {
358                         retObjBytes = arrCharToByteArray((char[]) obj);
359                 } else if (obj instanceof Character[]) {
360                         retObjBytes = arrCharToByteArray((Character[]) obj);
361                 } else if (obj instanceof boolean[]) {
362                         retObjBytes = arrBooleanToByteArray((boolean[]) obj);
363                 } else if (obj instanceof Boolean[]) {
364                         retObjBytes = arrBooleanToByteArray((Boolean[]) obj);
365                 } else if (obj instanceof String[]) {
366                         retObjBytes = arrStringToByteArray((String[]) obj);
367                 } else
368                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
369
370                 return retObjBytes;     
371         }
372
373
374         // Collection data structures
375         public static byte[] setToByteArray(Set<?> set) {
376
377                 // Find out the class of the type
378                 Iterator<?> it = set.iterator();
379                 Object[] arrObj = null;
380                 Object obj = it.next();
381
382                 if (obj instanceof Byte) {
383                         arrObj = set.toArray(new Byte[set.size()]);
384                 } else if (obj instanceof Short) {
385                         arrObj = set.toArray(new Short[set.size()]);
386                 } else if (obj instanceof Integer) {
387                         arrObj = set.toArray(new Integer[set.size()]);
388                 } else if (obj instanceof Long) {
389                         arrObj = set.toArray(new Long[set.size()]);
390                 } else if (obj instanceof Float) {
391                         arrObj = set.toArray(new Float[set.size()]);
392                 } else if (obj instanceof Double) {
393                         arrObj = set.toArray(new Double[set.size()]);
394                 } else if (obj instanceof Character) {
395                         arrObj = set.toArray(new Character[set.size()]);
396                 } else if (obj instanceof Boolean) {
397                         arrObj = set.toArray(new Boolean[set.size()]);
398                 } else if (obj instanceof String) {
399                         arrObj = set.toArray(new String[set.size()]);
400                 } else
401                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
402
403                 byte[] arrObjBytes = getArrayObjectBytes(arrObj);
404                 return arrObjBytes;
405         }
406
407
408         public static byte[] listToByteArray(List<?> list) {
409
410                 // Find out the class of the type
411                 Iterator<?> it = list.iterator();
412                 Object[] arrObj = null;
413                 Object obj = it.next();
414
415                 if (obj instanceof Byte) {
416                         arrObj = list.toArray(new Byte[list.size()]);
417                 } else if (obj instanceof Short) {
418                         arrObj = list.toArray(new Short[list.size()]);
419                 } else if (obj instanceof Integer) {
420                         arrObj = list.toArray(new Integer[list.size()]);
421                 } else if (obj instanceof Long) {
422                         arrObj = list.toArray(new Long[list.size()]);
423                 } else if (obj instanceof Float) {
424                         arrObj = list.toArray(new Float[list.size()]);
425                 } else if (obj instanceof Double) {
426                         arrObj = list.toArray(new Double[list.size()]);
427                 } else if (obj instanceof Character) {
428                         arrObj = list.toArray(new Character[list.size()]);
429                 } else if (obj instanceof Boolean) {
430                         arrObj = list.toArray(new Boolean[list.size()]);
431                 } else if (obj instanceof String) {
432                         arrObj = list.toArray(new String[list.size()]);
433                 } else
434                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
435
436                 byte[] arrObjBytes = getArrayObjectBytes(arrObj);
437                 return arrObjBytes;
438         }
439
440
441         // Convert keySet of a Map
442         public static byte[] mapKeyToByteArray(Map<?,?> map) {
443
444                 // Map<K,V>
445                 // Find out the class of the type for K
446                 Iterator<?> it = map.keySet().iterator();
447                 Object[] arrObj = null;
448                 Object obj = it.next();
449
450                 if (obj instanceof Byte) {
451                         arrObj = map.keySet().toArray(new Byte[map.size()]);
452                 } else if (obj instanceof Short) {
453                         arrObj = map.keySet().toArray(new Short[map.size()]);
454                 } else if (obj instanceof Integer) {
455                         arrObj = map.keySet().toArray(new Integer[map.size()]);
456                 } else if (obj instanceof Long) {
457                         arrObj = map.keySet().toArray(new Long[map.size()]);
458                 } else if (obj instanceof Float) {
459                         arrObj = map.keySet().toArray(new Float[map.size()]);
460                 } else if (obj instanceof Double) {
461                         arrObj = map.keySet().toArray(new Double[map.size()]);
462                 } else if (obj instanceof Character) {
463                         arrObj = map.keySet().toArray(new Character[map.size()]);
464                 } else if (obj instanceof Boolean) {
465                         arrObj = map.keySet().toArray(new Boolean[map.size()]);
466                 } else if (obj instanceof String) {
467                         arrObj = map.keySet().toArray(new String[map.size()]);
468                 } else
469                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
470                 byte[] arrObjBytes = getArrayObjectBytes(arrObj);
471
472                 return arrObjBytes;
473         }
474
475
476         // Convert entrySet of a Map
477         public static byte[] mapEntryToByteArray(Map<?,?> map) {
478
479                 // Map<K,V>
480                 // Find out the class of the type for V
481                 Iterator<?> it = map.values().iterator();
482                 Object[] arrObj = null;
483                 Object obj = it.next();
484
485                 if (obj instanceof Byte) {
486                         arrObj = map.values().toArray(new Byte[map.size()]);
487                 } else if (obj instanceof Short) {
488                         arrObj = map.values().toArray(new Short[map.size()]);
489                 } else if (obj instanceof Integer) {
490                         arrObj = map.values().toArray(new Integer[map.size()]);
491                 } else if (obj instanceof Long) {
492                         arrObj = map.values().toArray(new Long[map.size()]);
493                 } else if (obj instanceof Float) {
494                         arrObj = map.values().toArray(new Float[map.size()]);
495                 } else if (obj instanceof Double) {
496                         arrObj = map.values().toArray(new Double[map.size()]);
497                 } else if (obj instanceof Character) {
498                         arrObj = map.values().toArray(new Character[map.size()]);
499                 } else if (obj instanceof Boolean) {
500                         arrObj = map.values().toArray(new Boolean[map.size()]);
501                 } else if (obj instanceof String) {
502                         arrObj = map.values().toArray(new String[map.size()]);
503                 } else
504                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
505
506                 byte[] arrObjBytes = getArrayObjectBytes(arrObj);
507                 return arrObjBytes;
508         }
509
510
511         // Merge keySet and entrySet of a Map into one long byte array
512         public static byte[] mapToByteArray(Map<?,?> map) {
513
514                 // Put map size in the packet
515                 byte[] numEntries = intToByteArray(map.size());
516                 byte[] keySetBytes = mapKeyToByteArray(map);
517                 byte[] entrySetBytes = mapEntryToByteArray(map);
518                 byte[] mapBytes = new byte[INT_LEN + keySetBytes.length + entrySetBytes.length];
519                 // Copy the bytes
520                 System.arraycopy(numEntries, 0, mapBytes, 0, INT_LEN);
521                 System.arraycopy(keySetBytes, 0, mapBytes, INT_LEN, keySetBytes.length);
522                 System.arraycopy(entrySetBytes, 0, mapBytes, (INT_LEN + keySetBytes.length), entrySetBytes.length);
523
524                 return mapBytes;
525         }
526
527
528         // Get a Set object from bytes
529         public static Object getParamSetObject(Class<?> genericType, byte[] paramBytes) {
530
531                 Set<Object> retSet = new HashSet<Object>();
532                 Object retObj = null;
533                 if (genericType == Byte.class) {
534                         Byte[] retArr = byteArrayToByteArray(paramBytes);
535                         Collections.addAll(retSet, retArr);
536                 } else if (genericType == Short.class) {
537                         Short[] retArr = byteArrayToShortArray(paramBytes);
538                         Collections.addAll(retSet, retArr);
539                 } else if (genericType == Integer.class) {
540                         Integer[] retArr = byteArrayToIntegerArray(paramBytes);
541                         Collections.addAll(retSet, retArr);
542                 } else if (genericType == Long.class) {
543                         Long[] retArr = byteArrayToLongArray(paramBytes);
544                         Collections.addAll(retSet, retArr);
545                 } else if (genericType == Float.class) {
546                         Float[] retArr = byteArrayToFloatArray(paramBytes);
547                         Collections.addAll(retSet, retArr);
548                 } else if (genericType == Double.class) {
549                         Double[] retArr = byteArrayToDoubleArray(paramBytes);
550                         Collections.addAll(retSet, retArr);
551                 } else if (genericType == Boolean.class) {
552                         Boolean[] retArr = byteArrayToBooleanArray(paramBytes);
553                         Collections.addAll(retSet, retArr);
554                 } else if (genericType == Character.class) {
555                         Character[] retArr = byteArrayToCharacterArray(paramBytes);
556                         Collections.addAll(retSet, retArr);
557                 } else if (genericType == String.class) {
558                         String[] retArr = byteArrayToStringArray(paramBytes);
559                         Collections.addAll(retSet, retArr);
560                 } else
561                         throw new Error("IoTRMIUtil: Unrecognizable object: " + genericType.getSimpleName());
562
563                 return retSet;
564         }
565
566
567         // Get a List object from bytes
568         public static Object getParamListObject(Class<?> genericType, byte[] paramBytes) {
569
570                 List<Object> retList = new ArrayList<Object>();
571                 Object retObj = null;
572                 if (genericType == Byte.class) {
573                         Byte[] retArr = byteArrayToByteArray(paramBytes);
574                         Collections.addAll(retList, retArr);
575                 } else if (genericType == Short.class) {
576                         Short[] retArr = byteArrayToShortArray(paramBytes);
577                         Collections.addAll(retList, retArr);
578                 } else if (genericType == Integer.class) {
579                         Integer[] retArr = byteArrayToIntegerArray(paramBytes);
580                         Collections.addAll(retList, retArr);
581                 } else if (genericType == Long.class) {
582                         Long[] retArr = byteArrayToLongArray(paramBytes);
583                         Collections.addAll(retList, retArr);
584                 } else if (genericType == Float.class) {
585                         Float[] retArr = byteArrayToFloatArray(paramBytes);
586                         Collections.addAll(retList, retArr);
587                 } else if (genericType == Double.class) {
588                         Double[] retArr = byteArrayToDoubleArray(paramBytes);
589                         Collections.addAll(retList, retArr);
590                 } else if (genericType == Boolean.class) {
591                         Boolean[] retArr = byteArrayToBooleanArray(paramBytes);
592                         Collections.addAll(retList, retArr);
593                 } else if (genericType == Character.class) {
594                         Character[] retArr = byteArrayToCharacterArray(paramBytes);
595                         Collections.addAll(retList, retArr);
596                 } else if (genericType == String.class) {
597                         String[] retArr = byteArrayToStringArray(paramBytes);
598                         Collections.addAll(retList, retArr);
599                 } else
600                         throw new Error("IoTRMIUtil: Unrecognizable object: " + genericType.getSimpleName());
601
602                 return retList;
603         }
604
605
606         // Get a Key array for Map object from bytes
607         public static Object getParamMapObject(Class<?> genTypeKey, Class<?> genTypeVal, byte[] paramBytes) {
608
609                 // The complete set of bytes always consists of all keys followed by all values - <K,V> pairs
610                 // Calculate number of elements
611                 byte[] numElBytes = new byte[INT_LEN];
612                 System.arraycopy(paramBytes, 0, numElBytes, 0, INT_LEN);
613                 int numEl = byteArrayToInt(numElBytes);
614                 int keyLen = numEl * getTypeSize(genTypeKey);
615                 int valLen = numEl * getTypeSize(genTypeVal);
616                 byte[] prmKeyBytes = new byte[keyLen];
617                 byte[] prmValBytes = new byte[valLen];
618                 // Copy bytes
619                 System.arraycopy(paramBytes, INT_LEN, prmKeyBytes, 0, keyLen);
620                 System.arraycopy(paramBytes, (INT_LEN + keyLen), prmValBytes, 0, valLen);
621                 // Get array of keys
622                 Object[] retObjKey = (Object[]) getParamObjectArray(genTypeKey, prmKeyBytes);
623                 Object[] retObjVal = (Object[]) getParamObjectArray(genTypeVal, prmValBytes);
624                 // Put everything back to a Map
625                 Map<Object,Object> retMap = new HashMap<Object,Object>();
626                 IoTRMITypes.arraysToMap(retMap, retObjKey, retObjVal);
627
628                 return retMap;
629         }
630
631
632         /**
633          * Converters to byte array
634          */
635         // Single variables     
636         public static byte[] shortToByteArray(short s) {
637
638                 ByteBuffer bb = ByteBuffer.allocate(SHT_LEN);
639                 bb.putShort(s);
640
641                 return bb.array();
642         }
643
644
645         public static byte[] intToByteArray(int i) {
646
647                 ByteBuffer bb = ByteBuffer.allocate(INT_LEN);
648                 bb.putInt(i);
649
650                 return bb.array();
651         }
652
653
654         public static byte[] longToByteArray(long l) {
655
656                 ByteBuffer bb = ByteBuffer.allocate(LNG_LEN);
657                 bb.putLong(l);
658
659                 return bb.array();
660         }
661
662
663         public static byte[] floatToByteArray(float f) {
664
665                 ByteBuffer bb = ByteBuffer.allocate(FLT_LEN);
666                 bb.putFloat(f);
667
668                 return bb.array();
669         }
670
671
672         public static byte[] doubleToByteArray(double d) {
673
674                 ByteBuffer bb = ByteBuffer.allocate(DBL_LEN);
675                 bb.putDouble(d);
676
677                 return bb.array();
678         }
679
680
681         public static byte[] charToByteArray(char c) {
682
683                 ByteBuffer bb = ByteBuffer.allocate(CHR_LEN);
684                 bb.putChar(c);
685
686                 return bb.array();
687         }
688
689
690         public static byte[] booleanToByteArray(boolean b) {
691
692                 ByteBuffer bb = ByteBuffer.allocate(BOL_LEN);
693                 if (b)
694                         bb.put((byte)1);
695                 else
696                         bb.put((byte)0);
697
698                 return bb.array();
699         }
700
701
702         public static byte[] stringToByteArray(String str) {
703
704                 return str.getBytes();
705         }
706
707
708         // Arrays
709         public static byte[] arrByteToByteArray(Byte[] arrByte) {
710
711                 byte[] arrByt = new byte[arrByte.length];
712                 for(int i = 0; i < arrByte.length; i++) {
713                         arrByt[i] = arrByte[i];
714                 }
715
716                 return arrByt;
717         }
718
719
720         public static byte[] arrShortToByteArray(short[] arrShort) {
721
722                 ByteBuffer bb = ByteBuffer.allocate(SHT_LEN * arrShort.length);
723                 for(short s : arrShort) {
724                         bb.putShort(s);
725                 }
726
727                 return bb.array();
728         }
729
730
731         public static byte[] arrShortToByteArray(Short[] arrShort) {
732
733                 ByteBuffer bb = ByteBuffer.allocate(SHT_LEN * arrShort.length);
734                 for(Short s : arrShort) {
735                         bb.putShort(s);
736                 }
737
738                 return bb.array();
739         }
740
741
742         public static byte[] arrIntToByteArray(int[] arrInt) {
743
744                 ByteBuffer bb = ByteBuffer.allocate(INT_LEN * arrInt.length);
745                 for(int i : arrInt) {
746                         bb.putInt(i);
747                 }
748
749                 return bb.array();
750         }
751
752
753         public static byte[] arrIntToByteArray(Integer[] arrInt) {
754
755                 ByteBuffer bb = ByteBuffer.allocate(INT_LEN * arrInt.length);
756                 for(Integer i : arrInt) {
757                         bb.putInt(i);
758                 }
759
760                 return bb.array();
761         }
762
763
764         public static byte[] arrLongToByteArray(long[] arrLong) {
765
766                 ByteBuffer bb = ByteBuffer.allocate(LNG_LEN * arrLong.length);
767                 for(long l : arrLong) {
768                         bb.putLong(l);
769                 }
770
771                 return bb.array();
772         }
773
774
775         public static byte[] arrLongToByteArray(Long[] arrLong) {
776
777                 ByteBuffer bb = ByteBuffer.allocate(LNG_LEN * arrLong.length);
778                 for(Long l : arrLong) {
779                         bb.putLong(l);
780                 }
781
782                 return bb.array();
783         }
784
785
786         public static byte[] arrFloatToByteArray(float[] arrFloat) {
787
788                 ByteBuffer bb = ByteBuffer.allocate(FLT_LEN * arrFloat.length);
789                 for(float f : arrFloat) {
790                         bb.putFloat(f);
791                 }
792
793                 return bb.array();
794         }
795
796
797         public static byte[] arrFloatToByteArray(Float[] arrFloat) {
798
799                 ByteBuffer bb = ByteBuffer.allocate(FLT_LEN * arrFloat.length);
800                 for(Float f : arrFloat) {
801                         bb.putFloat(f);
802                 }
803
804                 return bb.array();
805         }
806
807
808         public static byte[] arrDoubleToByteArray(double[] arrDouble) {
809
810                 ByteBuffer bb = ByteBuffer.allocate(DBL_LEN * arrDouble.length);
811                 for(double d : arrDouble) {
812                         bb.putDouble(d);
813                 }
814
815                 return bb.array();
816         }
817
818
819         public static byte[] arrDoubleToByteArray(Double[] arrDouble) {
820
821                 ByteBuffer bb = ByteBuffer.allocate(DBL_LEN * arrDouble.length);
822                 for(Double d : arrDouble) {
823                         bb.putDouble(d);
824                 }
825
826                 return bb.array();
827         }
828
829
830         public static byte[] arrCharToByteArray(char[] arrChar) {
831
832                 ByteBuffer bb = ByteBuffer.allocate(CHR_LEN * arrChar.length);
833                 for(char c : arrChar) {
834                         bb.putChar(c);
835                 }
836
837                 return bb.array();
838         }
839
840
841         public static byte[] arrCharToByteArray(Character[] arrChar) {
842
843                 ByteBuffer bb = ByteBuffer.allocate(CHR_LEN * arrChar.length);
844                 for(Character c : arrChar) {
845                         bb.putChar(c);
846                 }
847
848                 return bb.array();
849         }
850
851
852         public static byte[] arrBooleanToByteArray(boolean[] arrBool) {
853
854                 ByteBuffer bb = ByteBuffer.allocate(BOL_LEN * arrBool.length);
855                 for(boolean b : arrBool) {
856                         if (b)
857                                 bb.put((byte)1);
858                         else
859                                 bb.put((byte)0);
860                 }
861
862                 return bb.array();
863         }
864
865
866         public static byte[] arrBooleanToByteArray(Boolean[] arrBool) {
867
868                 ByteBuffer bb = ByteBuffer.allocate(BOL_LEN * arrBool.length);
869                 for(Boolean b : arrBool) {
870                         if (b)
871                                 bb.put((byte)1);
872                         else
873                                 bb.put((byte)0);
874                 }
875
876                 return bb.array();
877         }
878
879
880         public static byte[] arrStringToByteArray(String[] arrString) {
881
882                 // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
883                 // Prepare array of bytes
884                 int arrLen = INT_LEN;   // First allocation for array length
885                 for (int i = 0; i < arrString.length; i++) {
886                         arrLen = arrLen + INT_LEN + arrString[i].length();
887                 }       
888                 byte[] arrStrBytes = new byte[arrLen];
889                 // Copy bytes
890                 int pos = 0;
891                 byte[] strArrLenBytes = intToByteArray(arrString.length);
892                 System.arraycopy(strArrLenBytes, 0, arrStrBytes, pos, INT_LEN);
893                 pos = pos + INT_LEN;
894                 for (String str : arrString) {
895
896                         // Copy string length
897                         int strLen = str.length();
898                         byte[] strLenBytes = intToByteArray(strLen);
899                         System.arraycopy(strLenBytes, 0, arrStrBytes, pos, INT_LEN);
900                         pos = pos + INT_LEN;
901                         // Copy string
902                         byte[] strBytes = stringToByteArray(str);
903                         System.arraycopy(strBytes, 0, arrStrBytes, pos, strLen);
904                         pos = pos + strLen;
905                 }
906
907                 return arrStrBytes;
908         }
909
910
911         /**
912          * Converters from byte array
913          */
914         // Single variables     
915         public static short byteArrayToShort(byte[] bytes) {
916
917                 return ByteBuffer.wrap(bytes).getShort();
918         }
919
920
921         public static int byteArrayToInt(byte[] bytes) {
922
923                 return ByteBuffer.wrap(bytes).getInt();
924         }
925
926
927         public static long byteArrayToLong(byte[] bytes) {
928
929                 return ByteBuffer.wrap(bytes).getLong();
930         }
931
932
933         public static float byteArrayToFloat(byte[] bytes) {
934
935                 return ByteBuffer.wrap(bytes).getFloat();
936         }
937
938
939         public static double byteArrayToDouble(byte[] bytes) {
940
941                 return ByteBuffer.wrap(bytes).getDouble();
942         }
943
944
945         public static char byteArrayToChar(byte[] bytes) {
946
947                 return ByteBuffer.wrap(bytes).getChar();
948         }
949
950
951         public static boolean byteArrayToBoolean(byte[] bytes) {
952
953                 Byte boolValByte = ByteBuffer.wrap(bytes).get();
954                 short boolVal = boolValByte.shortValue();
955                 if (boolVal == 1)
956                         return true;
957                 else
958                         return false;
959         }
960
961
962     public static String byteArrayToString(byte[] bytes) {
963         return new String(bytes);
964     }
965
966
967         // Arrays
968         public static Byte[] byteArrayToByteArray(byte[] arrByt) {
969
970                 Byte[] arrByte = new Byte[arrByt.length];
971                 for(int i = 0; i < arrByt.length; i++) {
972                         arrByte[i] = arrByt[i];
973                 }
974
975                 return arrByte;
976         }
977         
978         
979         public static short[] byteArrayToShtArray(byte[] bytes) {
980
981                 // Single element bytes
982                 byte[] elmt = new byte[SHT_LEN];
983                 // Prepare array
984                 int arrLen = bytes.length / SHT_LEN;
985                 short[] arr = new short[arrLen];
986                 for(int i = 0; i < arrLen; i++) {
987                         int offset = i * SHT_LEN;
988                         System.arraycopy(bytes, offset, elmt, 0, SHT_LEN);              
989                         arr[i] = byteArrayToShort(elmt);
990                 }
991
992                 return arr;
993         }
994
995
996         public static Short[] byteArrayToShortArray(byte[] bytes) {
997
998                 // Single element bytes
999                 byte[] elmt = new byte[SHT_LEN];
1000                 // Prepare array
1001                 int arrLen = bytes.length / SHT_LEN;
1002                 Short[] arr = new Short[arrLen];
1003                 for(int i = 0; i < arrLen; i++) {
1004                         int offset = i * SHT_LEN;
1005                         System.arraycopy(bytes, offset, elmt, 0, SHT_LEN);              
1006                         arr[i] = byteArrayToShort(elmt);
1007                 }
1008
1009                 return arr;
1010         }
1011
1012
1013         public static int[] byteArrayToIntArray(byte[] bytes) {
1014
1015                 // Single element bytes
1016                 byte[] elmt = new byte[INT_LEN];
1017                 // Prepare array
1018                 int arrLen = bytes.length / INT_LEN;
1019                 int[] arr = new int[arrLen];
1020                 for(int i = 0; i < arrLen; i++) {
1021                         int offset = i * INT_LEN;
1022                         System.arraycopy(bytes, offset, elmt, 0, INT_LEN);              
1023                         arr[i] = byteArrayToInt(elmt);
1024                 }
1025
1026                 return arr;
1027         }
1028
1029
1030         public static Integer[] byteArrayToIntegerArray(byte[] bytes) {
1031
1032                 // Single element bytes
1033                 byte[] elmt = new byte[INT_LEN];
1034                 // Prepare array
1035                 int arrLen = bytes.length / INT_LEN;
1036                 Integer[] arr = new Integer[arrLen];
1037                 for(int i = 0; i < arrLen; i++) {
1038                         int offset = i * INT_LEN;
1039                         System.arraycopy(bytes, offset, elmt, 0, INT_LEN);
1040                         arr[i] = byteArrayToInt(elmt);
1041                 }
1042
1043                 return arr;
1044         }
1045
1046
1047         public static long[] byteArrayToLngArray(byte[] bytes) {
1048
1049                 // Single element bytes
1050                 byte[] elmt = new byte[LNG_LEN];
1051                 // Prepare array
1052                 int arrLen = bytes.length / LNG_LEN;
1053                 long[] arr = new long[arrLen];
1054                 for(int i = 0; i < arrLen; i++) {
1055                         int offset = i * LNG_LEN;
1056                         System.arraycopy(bytes, offset, elmt, 0, LNG_LEN);              
1057                         arr[i] = byteArrayToLong(elmt);
1058                 }
1059
1060                 return arr;
1061         }
1062
1063
1064         public static Long[] byteArrayToLongArray(byte[] bytes) {
1065
1066                 // Single element bytes
1067                 byte[] elmt = new byte[LNG_LEN];
1068                 // Prepare array
1069                 int arrLen = bytes.length / LNG_LEN;
1070                 Long[] arr = new Long[arrLen];
1071                 for(int i = 0; i < arrLen; i++) {
1072                         int offset = i * LNG_LEN;
1073                         System.arraycopy(bytes, offset, elmt, 0, LNG_LEN);
1074                         arr[i] = byteArrayToLong(elmt);
1075                 }
1076
1077                 return arr;
1078         }
1079
1080
1081         public static float[] byteArrayToFltArray(byte[] bytes) {
1082
1083                 // Single element bytes
1084                 byte[] elmt = new byte[FLT_LEN];
1085                 // Prepare array
1086                 int arrLen = bytes.length / FLT_LEN;
1087                 float[] arr = new float[arrLen];
1088                 for(int i = 0; i < arrLen; i++) {
1089                         int offset = i * FLT_LEN;
1090                         System.arraycopy(bytes, offset, elmt, 0, FLT_LEN);              
1091                         arr[i] = byteArrayToFloat(elmt);
1092                 }
1093
1094                 return arr;
1095         }
1096
1097
1098         public static Float[] byteArrayToFloatArray(byte[] bytes) {
1099
1100                 // Single element bytes
1101                 byte[] elmt = new byte[FLT_LEN];
1102                 // Prepare array
1103                 int arrLen = bytes.length / FLT_LEN;
1104                 Float[] arr = new Float[arrLen];
1105                 for(int i = 0; i < arrLen; i++) {
1106                         int offset = i * FLT_LEN;
1107                         System.arraycopy(bytes, offset, elmt, 0, FLT_LEN);
1108                         arr[i] = byteArrayToFloat(elmt);
1109                 }
1110
1111                 return arr;
1112         }
1113
1114
1115         public static double[] byteArrayToDblArray(byte[] bytes) {
1116
1117                 // Single element bytes
1118                 byte[] elmt = new byte[DBL_LEN];
1119                 // Prepare array
1120                 int arrLen = bytes.length / DBL_LEN;
1121                 double[] arr = new double[arrLen];
1122                 for(int i = 0; i < arrLen; i++) {
1123                         int offset = i * DBL_LEN;
1124                         System.arraycopy(bytes, offset, elmt, 0, DBL_LEN);
1125                         arr[i] = byteArrayToDouble(elmt);
1126                 }
1127
1128                 return arr;
1129         }
1130
1131
1132         public static Double[] byteArrayToDoubleArray(byte[] bytes) {
1133
1134                 // Single element bytes
1135                 byte[] elmt = new byte[DBL_LEN];
1136                 // Prepare array
1137                 int arrLen = bytes.length / DBL_LEN;
1138                 Double[] arr = new Double[arrLen];
1139                 for(int i = 0; i < arrLen; i++) {
1140                         int offset = i * DBL_LEN;
1141                         System.arraycopy(bytes, offset, elmt, 0, DBL_LEN);
1142                         arr[i] = byteArrayToDouble(elmt);
1143                 }
1144
1145                 return arr;
1146         }
1147
1148
1149         public static char[] byteArrayToChrArray(byte[] bytes) {
1150
1151                 // Single element bytes
1152                 byte[] elmt = new byte[CHR_LEN];
1153                 // Prepare array
1154                 int arrLen = bytes.length / CHR_LEN;
1155                 char[] arr = new char[arrLen];
1156                 for(int i = 0; i < arrLen; i++) {
1157                         int offset = i * CHR_LEN;
1158                         System.arraycopy(bytes, offset, elmt, 0, CHR_LEN);
1159                         arr[i] = byteArrayToChar(elmt);
1160                 }
1161
1162                 return arr;
1163         }
1164
1165
1166         public static Character[] byteArrayToCharacterArray(byte[] bytes) {
1167
1168                 // Single element bytes
1169                 byte[] elmt = new byte[CHR_LEN];
1170                 // Prepare array
1171                 int arrLen = bytes.length / CHR_LEN;
1172                 Character[] arr = new Character[arrLen];
1173                 for(int i = 0; i < arrLen; i++) {
1174                         int offset = i * CHR_LEN;
1175                         System.arraycopy(bytes, offset, elmt, 0, CHR_LEN);
1176                         arr[i] = byteArrayToChar(elmt);
1177                 }
1178
1179                 return arr;
1180         }
1181
1182
1183         public static boolean[] byteArrayToBolArray(byte[] bytes) {
1184
1185                 // Single element bytes
1186                 byte[] elmt = new byte[BOL_LEN];
1187                 // Prepare array
1188                 int arrLen = bytes.length / BOL_LEN;
1189                 boolean[] arr = new boolean[arrLen];
1190                 for(int i = 0; i < arrLen; i++) {
1191                         int offset = i * BOL_LEN;
1192                         System.arraycopy(bytes, offset, elmt, 0, BOL_LEN);
1193                         arr[i] = byteArrayToBoolean(elmt);
1194                 }
1195
1196                 return arr;
1197         }
1198
1199
1200         public static Boolean[] byteArrayToBooleanArray(byte[] bytes) {
1201
1202                 // Single element bytes
1203                 byte[] elmt = new byte[BOL_LEN];
1204                 // Prepare array
1205                 int arrLen = bytes.length / BOL_LEN;
1206                 Boolean[] arr = new Boolean[arrLen];
1207                 for(int i = 0; i < arrLen; i++) {
1208                         int offset = i * BOL_LEN;
1209                         System.arraycopy(bytes, offset, elmt, 0, BOL_LEN);
1210                         arr[i] = byteArrayToBoolean(elmt);
1211                 }
1212
1213                 return arr;
1214         }
1215
1216
1217         public static String[] byteArrayToStringArray(byte[] bytes) {
1218
1219                 // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
1220                 // Get string array length
1221                 int pos = 0;
1222                 byte[] strArrLenBytes = new byte[INT_LEN];
1223                 System.arraycopy(bytes, pos, strArrLenBytes, 0, INT_LEN);
1224                 int strArrLen = byteArrayToInt(strArrLenBytes);
1225                 pos = pos + INT_LEN;
1226                 // Prepare string array
1227                 String[] strArray = new String[strArrLen];
1228                 // Extract array of strings
1229                 for(int i = 0; i < strArrLen; i++) {
1230
1231                         // Extract string length
1232                         byte[] strLenBytes = new byte[INT_LEN];
1233                         System.arraycopy(bytes, pos, strLenBytes, 0, INT_LEN);
1234                         int strLen = byteArrayToInt(strLenBytes);
1235                         pos = pos + INT_LEN;
1236                         // Extract string
1237                         byte[] strBytes = new byte[strLen];
1238                         System.arraycopy(bytes, pos, strBytes, 0, strLen);
1239                         pos = pos + strLen;
1240                         strArray[i] = byteArrayToString(strBytes);
1241                 }
1242
1243                 return strArray;
1244         }
1245
1246
1247         /**
1248          * toByteArray() gets Object and return its byte array
1249          * <p>
1250          * Adapted from http://www.java2s.com/
1251          *              @see <a href="http://www.java2s.com/Code/Java/File-Input-
1252          *              Output/Convertobjecttobytearrayandconvertbytearraytoobject.htm"</a>
1253          */
1254     // toByteArray and toObject are taken from: http://tinyurl.com/69h8l7x
1255     public static byte[] toByteArray(Object obj) throws IOException {
1256
1257         byte[] bytes = null;
1258         ByteArrayOutputStream bos = null;
1259         ObjectOutputStream oos = null;
1260         try {
1261
1262             bos = new ByteArrayOutputStream();
1263             oos = new ObjectOutputStream(bos);
1264             oos.writeObject(obj);
1265             oos.flush();
1266             bytes = bos.toByteArray();
1267         } finally {
1268
1269             if (oos != null) {
1270                 oos.close();
1271             }
1272             if (bos != null) {
1273                 bos.close();
1274             }
1275         }
1276         return bytes;
1277     }
1278
1279
1280         /**
1281          * toObject() gets byte array and return its Object
1282          * <p>
1283          * Adapted from http://www.java2s.com/
1284          *              @see <a href="http://www.java2s.com/Code/Java/File-Input-
1285          *              Output/Convertobjecttobytearrayandconvertbytearraytoobject.htm"</a>
1286          */
1287     public static Object toObject(byte[] bytes) throws IOException, ClassNotFoundException {
1288
1289         Object obj = null;
1290         ByteArrayInputStream bis = null;
1291         ObjectInputStream ois = null;
1292         try {
1293
1294             bis = new ByteArrayInputStream(bytes);
1295             ois = new ObjectInputStream(bis);
1296             obj = ois.readObject();
1297         } finally {
1298
1299             if (bis != null) {
1300                 bis.close();
1301             }
1302             if (ois != null) {
1303                 ois.close();
1304             }
1305         }
1306         return obj;
1307     }
1308
1309
1310         public static void main(String[] args) {
1311
1312                 //boolean data = false;
1313                 //char data = 'c';
1314                 float data = 1234.123f;
1315                 //double data = 12.51231234;
1316                 //long data = 1234l;
1317                 //short data = 1234;
1318                 //int data = 12345678;
1319                 byte[] result = floatToByteArray(data);
1320                 System.out.println("Result: " + Arrays.toString(result));
1321                 System.out.println("Converted back: " + byteArrayToFloat(result));
1322                 
1323                 String str = "methodA(int,string,float,double,double)";
1324                 int hash = str.hashCode();
1325                 System.out.println("Hash value: " + hash);
1326         }
1327 }