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