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