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