Making classes final to make inheritance impossible
[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 final 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 PACKET_TYPE_LEN = 4;    // 4 bytes = 32 bits
43         public final static int PARAM_LEN = 4;                  // 4 bytes = 32 bits (4-byte field that stores the length of the param)
44         public final static int RETURN_LEN = 4;                 // 4 bytes = 32 bits (4-byte field that stores the length of the return object)
45         public final static int RET_VAL_TYPE = -1;              // Packet type of return value
46         public final static int METHOD_TYPE = 1;                // Packet type of method
47
48         public final static int SHT_LEN = 2;
49         public final static int INT_LEN = 4;
50         public final static int LNG_LEN = 8;
51         public final static int FLT_LEN = 4;
52         public final static int DBL_LEN = 8;
53         public final static int CHR_LEN = 2;
54         public final static int BYT_LEN = 1;
55         public final static int BOL_LEN = 1;
56
57         /**
58          * Public static data structure to keep track of multiple skeletons and stubs
59          */
60         public static Map<Integer,Object> mapStub = new HashMap<Integer,Object>();              // Map object to its stub ID
61         public static Map<Object,Object> mapSkel = new HashMap<Object,Object>();                // Map object to its skeleton
62         public static Map<Object,Integer> mapSkelId = new HashMap<Object,Integer>();    // Map object to its skeleton ID
63
64
65         /**
66          * Constructors
67          */
68         public IoTRMIUtil() {
69
70                 mapPrimitives = new HashMap<String,String>();
71                         IoTRMITypes.arraysToMap(mapPrimitives, 
72                                 IoTRMITypes.primitivesJava, IoTRMITypes.primitivesCplus);
73                 mapPrimitiveSizes = new HashMap<String,Integer>();
74                         IoTRMITypes.arraysToMap(mapPrimitiveSizes, 
75                                 IoTRMITypes.primitivesJava, IoTRMITypes.primitivesSizes);
76                 mapNonPrimitives = new HashMap<String,String>();
77                         IoTRMITypes.arraysToMap(mapNonPrimitives, 
78                                 IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
79         }
80
81         
82         /*public static void initRMICall(int port, String address, int rev) throws IOException {
83                 rmiCall = new IoTRMICall(port, address, rev);
84         }
85         
86         public static void initRMICall(int localPort, int port, String address, int rev) throws IOException {
87                 rmiCall = new IoTRMICall(localPort, port, address, rev);
88         }
89         
90         public static void initRMIObject(int port) throws IOException, ClassNotFoundException, 
91                         InstantiationException, IllegalAccessException {
92                 rmiObj = new IoTRMIObject(port);
93         }*/
94         
95
96         /**
97          * getHashCodeBytes() gets hash value (in bytes) from method name
98          */
99         public static byte[] getHashCodeBytes(String string) {
100
101                 int hash = string.hashCode();
102                 byte[] hashBytes = ByteBuffer.allocate(4).putInt(hash).array();
103                 return hashBytes;
104         }
105
106
107         /**================
108          * Helper methods
109          **================
110          */
111         /**
112          * translateType() try to translate a type
113          * <p>
114          * It returns the original type when fails.
115          */
116         public String translateType(String type) {
117
118                 if (mapPrimitives.containsKey(type))
119                         return mapPrimitives.get(type);
120                 else if (mapNonPrimitives.containsKey(type))
121                         return mapNonPrimitives.get(type);
122                 else
123                         return type;
124         }
125
126
127         /**
128          * getTypeSize() gets the size of a type
129          *
130          */
131         public int getTypeSize(String type) {
132
133                 if (mapPrimitiveSizes.containsKey(type))
134                         return mapPrimitiveSizes.get(type);
135                 else
136                         return -1; // Size is unknown (variable length)
137         }
138         
139
140         /**
141          * getTypeSize() gets the size of a type
142          *
143          */
144         public static int getTypeSize(Class<?> type) {
145
146                 int size = 0;
147                 if (type == byte.class) {
148                         size = BYT_LEN;
149                 } else if (type == Byte.class) {
150                         size = BYT_LEN;
151                 } else if (type == short.class) {
152                         size = SHT_LEN;
153                 } else if (type == Short.class) {
154                         size = SHT_LEN;
155                 } else if (     type == int.class) {
156                         size = INT_LEN;
157                 } else if (     type == Integer.class) {
158                         size = INT_LEN;
159                 } else if (     type == long.class) {
160                         size = LNG_LEN;
161                 } else if (     type == Long.class) {
162                         size = LNG_LEN;
163                 } else if (     type == float.class) {
164                         size = FLT_LEN;
165                 } else if (     type == Float.class) {
166                         size = FLT_LEN;
167                 } else if (     type == double.class) {
168                         size = DBL_LEN;
169                 } else if ( type == Double.class) {
170                         size = DBL_LEN;
171                 } else if (     type == boolean.class) {
172                         size = BOL_LEN;
173                 } else if (     type == Boolean.class) {
174                         size = BOL_LEN;
175                 } else if (     type == char.class) {
176                         size = CHR_LEN;
177                 } else if (     type == Character[].class) {
178                         size = CHR_LEN;
179                 } else if (type == String[].class) {
180                         size = -1;
181                 } else
182                         throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
183
184                 return size;
185         }
186
187         
188         /**
189          * getParamObject() converts byte array of certain object type into Object
190          */
191         public static Object getParamObject(Class<?> type, Class<?> genTypeVal, byte[] paramBytes) {
192                 
193                 Object retObj = null;
194                 if (type == byte.class ||
195                         type == Byte.class) {
196                         retObj = (Object) paramBytes[0];
197                 } else if (     type == short.class ||
198                                         type == Short.class) {
199                         retObj = (Object) byteArrayToShort(paramBytes);
200                 } else if (     type == int.class ||
201                                         type == Integer.class) {
202                         retObj = (Object) byteArrayToInt(paramBytes);
203                 } else if (     type == long.class ||
204                                         type == Long.class) {
205                         retObj = (Object) byteArrayToLong(paramBytes);
206                 } else if (     type == float.class ||
207                                         type == Float.class) {
208                         retObj = (Object) byteArrayToFloat(paramBytes);
209                 } else if (     type == double.class ||
210                                         type == Double.class) {
211                         retObj = (Object) byteArrayToDouble(paramBytes);
212                 } else if (     type == boolean.class ||
213                                         type == Boolean.class) {
214                         retObj = (Object) byteArrayToBoolean(paramBytes);
215                 } else if (     type == char.class ||
216                                         type == Character.class) {
217                         retObj = (Object) byteArrayToChar(paramBytes);
218                 } else if (type == String.class) {
219                         retObj = (Object) byteArrayToString(paramBytes);
220                 // Array
221                 } else if (type.isArray()) {
222                         retObj = getParamObjectArray(type, paramBytes);
223                 // List
224                 } else if (type == List.class) {
225                         retObj = getParamListObject(genTypeVal, paramBytes);
226                 } else
227                         throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
228                 
229                 return retObj;
230         }
231
232
233         /**
234          * getParamObjectArray() converts byte array of certain object type into array of Objects
235          */
236         public static Object getParamObjectArray(Class<?> type, byte[] paramBytes) {
237                 
238                 Object retObj = null;
239                 if ((type == byte[].class)      ||
240                         (type == byte.class)) {
241                         retObj = (Object) paramBytes;
242                 } else if ( (type == Byte[].class) ||
243                                         (type == Byte.class)) {
244                         retObj = (Object) byteArrayToByteArray(paramBytes);
245                 } else if ( (type == short[].class) ||
246                                         (type == short.class)) {
247                         retObj = (Object) byteArrayToShtArray(paramBytes);
248                 } else if ( (type == Short[].class) ||
249                                         (type == Short.class)) {
250                         retObj = (Object) byteArrayToShortArray(paramBytes);
251                 } else if (     (type == int[].class) ||
252                                         (type == int.class)) {
253                         retObj = (Object) byteArrayToIntArray(paramBytes);
254                 } else if (     (type == Integer[].class) ||
255                                         (type == Integer.class)) {
256                         retObj = (Object) byteArrayToIntegerArray(paramBytes);
257                 } else if (     (type == long[].class) ||
258                                         (type == long.class)) {
259                         retObj = (Object) byteArrayToLngArray(paramBytes);
260                 } else if (     (type == Long[].class) ||
261                                         (type == Long.class)) {
262                         retObj = (Object) byteArrayToLongArray(paramBytes);
263                 } else if (     (type == float[].class) ||
264                                         (type == float.class)) {
265                         retObj = (Object) byteArrayToFltArray(paramBytes);
266                 } else if (     (type == Float[].class) ||
267                                         (type == Float.class)) {
268                         retObj = (Object) byteArrayToFloatArray(paramBytes);
269                 } else if (     (type == double[].class) ||
270                                         (type == double.class)) {
271                         retObj = (Object) byteArrayToDblArray(paramBytes);
272                 } else if ( (type == Double[].class) ||
273                                         (type == Double.class)) {
274                         retObj = (Object) byteArrayToDoubleArray(paramBytes);
275                 } else if (     (type == boolean[].class) || 
276                                         (type == boolean.class)) {
277                         retObj = (Object) byteArrayToBolArray(paramBytes);
278                 } else if (     (type == Boolean[].class) ||
279                                         (type == Boolean.class)) {
280                         retObj = (Object) byteArrayToBooleanArray(paramBytes);
281                 } else if (     (type == char[].class) ||
282                                         (type == char.class)) {
283                         retObj = (Object) byteArrayToChrArray(paramBytes);
284                 } else if (     (type == Character[].class) ||
285                                         (type == Character.class)) {
286                         retObj = (Object) byteArrayToCharacterArray(paramBytes);
287                 } else if ( (type == String[].class) ||
288                                         (type == String.class)) {
289                         retObj = (Object) byteArrayToStringArray(paramBytes);
290                 } else
291                         throw new Error("IoTRMIUtil: Unrecognizable type: " + type.getName());
292                 
293                 return retObj;
294         }
295
296
297         /**
298          * getObjectBytes() converts an object into byte array
299          */
300         public static byte[] getObjectBytes(Object obj) {
301                 
302                 byte[] retObjBytes = null;
303                 if (obj instanceof Byte) {
304                         retObjBytes = new byte[] { (byte) obj };
305                 } else if (obj instanceof Short) {
306                         retObjBytes = shortToByteArray((short) obj);
307                 } else if (obj instanceof Integer) {
308                         retObjBytes = intToByteArray((int) obj);
309                 } else if (obj instanceof Long) {
310                         retObjBytes = longToByteArray((long) obj);
311                 } else if (obj instanceof Float) {
312                         retObjBytes = floatToByteArray((float) obj);
313                 } else if (obj instanceof Double) {
314                         retObjBytes = doubleToByteArray((double) obj);
315                 } else if (obj instanceof Character) {
316                         retObjBytes = charToByteArray((char) obj);
317                 } else if (obj instanceof Boolean) {
318                         retObjBytes = booleanToByteArray((boolean) obj);
319                 } else if (obj instanceof String) {
320                         retObjBytes = stringToByteArray((String) obj);
321                 // Arrays
322                 } else if (obj.getClass().isArray()) {
323                         retObjBytes = getArrayObjectBytes(obj);
324                 // List and its implementations
325                 } else if (obj instanceof List<?>) {
326                         retObjBytes = listToByteArray((List<?>) obj);
327                 } else
328                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
329
330                 return retObjBytes;
331         }
332
333
334         /**
335          * getArrayObjectBytes() converts array of objects into bytes array
336          */
337         public static byte[] getArrayObjectBytes(Object obj) {
338
339                 byte[] retObjBytes = null;
340                 if (obj instanceof byte[]) {
341                         retObjBytes = (byte[]) obj;
342                 } else if (obj instanceof Byte[]) {
343                         retObjBytes = arrByteToByteArray((Byte[]) obj);
344                 } else if (obj instanceof short[]) {
345                         retObjBytes = arrShortToByteArray((short[]) obj);
346                 } else if (obj instanceof Short[]) {
347                         retObjBytes = arrShortToByteArray((Short[]) obj);
348                 } else if (obj instanceof int[]) {
349                         retObjBytes = arrIntToByteArray((int[]) obj);
350                 } else if (obj instanceof Integer[]) {
351                         retObjBytes = arrIntToByteArray((Integer[]) obj);
352                 } else if (obj instanceof long[]) {
353                         retObjBytes = arrLongToByteArray((long[]) obj);
354                 } else if (obj instanceof Long[]) {
355                         retObjBytes = arrLongToByteArray((Long[]) obj);
356                 } else if (obj instanceof float[]) {
357                         retObjBytes = arrFloatToByteArray((float[]) obj);
358                 } else if (obj instanceof Float[]) {
359                         retObjBytes = arrFloatToByteArray((Float[]) obj);
360                 } else if (obj instanceof double[]) {
361                         retObjBytes = arrDoubleToByteArray((double[]) obj);
362                 } else if (obj instanceof Double[]) {
363                         retObjBytes = arrDoubleToByteArray((Double[]) obj);
364                 } else if (obj instanceof char[]) {
365                         retObjBytes = arrCharToByteArray((char[]) obj);
366                 } else if (obj instanceof Character[]) {
367                         retObjBytes = arrCharToByteArray((Character[]) obj);
368                 } else if (obj instanceof boolean[]) {
369                         retObjBytes = arrBooleanToByteArray((boolean[]) obj);
370                 } else if (obj instanceof Boolean[]) {
371                         retObjBytes = arrBooleanToByteArray((Boolean[]) obj);
372                 } else if (obj instanceof String[]) {
373                         retObjBytes = arrStringToByteArray((String[]) obj);
374                 } else
375                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
376
377                 return retObjBytes;     
378         }
379
380
381         public static byte[] listToByteArray(List<?> list) {
382
383                 // Find out the class of the type
384                 Iterator<?> it = list.iterator();
385                 Object[] arrObj = null;
386                 Object obj = it.next();
387
388                 if (obj instanceof Byte) {
389                         arrObj = list.toArray(new Byte[list.size()]);
390                 } else if (obj instanceof Short) {
391                         arrObj = list.toArray(new Short[list.size()]);
392                 } else if (obj instanceof Integer) {
393                         arrObj = list.toArray(new Integer[list.size()]);
394                 } else if (obj instanceof Long) {
395                         arrObj = list.toArray(new Long[list.size()]);
396                 } else if (obj instanceof Float) {
397                         arrObj = list.toArray(new Float[list.size()]);
398                 } else if (obj instanceof Double) {
399                         arrObj = list.toArray(new Double[list.size()]);
400                 } else if (obj instanceof Character) {
401                         arrObj = list.toArray(new Character[list.size()]);
402                 } else if (obj instanceof Boolean) {
403                         arrObj = list.toArray(new Boolean[list.size()]);
404                 } else if (obj instanceof String) {
405                         arrObj = list.toArray(new String[list.size()]);
406                 } else
407                         throw new Error("IoTRMIUtil: Unrecognizable object: " + obj.getClass());
408
409                 byte[] arrObjBytes = getArrayObjectBytes(arrObj);
410                 return arrObjBytes;
411         }
412
413
414         // Get a List object from bytes
415         public static Object getParamListObject(Class<?> genericType, byte[] paramBytes) {
416
417                 List<Object> retList = new ArrayList<Object>();
418                 Object retObj = null;
419                 if (genericType == Byte.class) {
420                         Byte[] retArr = byteArrayToByteArray(paramBytes);
421                         Collections.addAll(retList, retArr);
422                 } else if (genericType == Short.class) {
423                         Short[] retArr = byteArrayToShortArray(paramBytes);
424                         Collections.addAll(retList, retArr);
425                 } else if (genericType == Integer.class) {
426                         Integer[] retArr = byteArrayToIntegerArray(paramBytes);
427                         Collections.addAll(retList, retArr);
428                 } else if (genericType == Long.class) {
429                         Long[] retArr = byteArrayToLongArray(paramBytes);
430                         Collections.addAll(retList, retArr);
431                 } else if (genericType == Float.class) {
432                         Float[] retArr = byteArrayToFloatArray(paramBytes);
433                         Collections.addAll(retList, retArr);
434                 } else if (genericType == Double.class) {
435                         Double[] retArr = byteArrayToDoubleArray(paramBytes);
436                         Collections.addAll(retList, retArr);
437                 } else if (genericType == Boolean.class) {
438                         Boolean[] retArr = byteArrayToBooleanArray(paramBytes);
439                         Collections.addAll(retList, retArr);
440                 } else if (genericType == Character.class) {
441                         Character[] retArr = byteArrayToCharacterArray(paramBytes);
442                         Collections.addAll(retList, retArr);
443                 } else if (genericType == String.class) {
444                         String[] retArr = byteArrayToStringArray(paramBytes);
445                         Collections.addAll(retList, retArr);
446                 } else
447                         throw new Error("IoTRMIUtil: Unrecognizable object: " + genericType.getSimpleName());
448
449                 return retList;
450         }
451
452
453         /**
454          * Converters to byte array
455          */
456         // Single variables     
457         public static byte[] shortToByteArray(short s) {
458
459                 ByteBuffer bb = ByteBuffer.allocate(SHT_LEN);
460                 bb.putShort(s);
461
462                 return bb.array();
463         }
464
465
466         public static byte[] intToByteArray(int i) {
467
468                 ByteBuffer bb = ByteBuffer.allocate(INT_LEN);
469                 bb.putInt(i);
470
471                 return bb.array();
472         }
473
474
475         public static byte[] longToByteArray(long l) {
476
477                 ByteBuffer bb = ByteBuffer.allocate(LNG_LEN);
478                 bb.putLong(l);
479
480                 return bb.array();
481         }
482
483
484         public static byte[] floatToByteArray(float f) {
485
486                 ByteBuffer bb = ByteBuffer.allocate(FLT_LEN);
487                 bb.putFloat(f);
488
489                 return bb.array();
490         }
491
492
493         public static byte[] doubleToByteArray(double d) {
494
495                 ByteBuffer bb = ByteBuffer.allocate(DBL_LEN);
496                 bb.putDouble(d);
497
498                 return bb.array();
499         }
500
501
502         public static byte[] charToByteArray(char c) {
503
504                 ByteBuffer bb = ByteBuffer.allocate(CHR_LEN);
505                 bb.putChar(c);
506
507                 return bb.array();
508         }
509
510
511         public static byte[] booleanToByteArray(boolean b) {
512
513                 ByteBuffer bb = ByteBuffer.allocate(BOL_LEN);
514                 if (b)
515                         bb.put((byte)1);
516                 else
517                         bb.put((byte)0);
518
519                 return bb.array();
520         }
521
522
523         public static byte[] stringToByteArray(String str) {
524
525                 return str.getBytes();
526         }
527
528
529         // Arrays
530         public static byte[] arrByteToByteArray(Byte[] arrByte) {
531
532                 byte[] arrByt = new byte[arrByte.length];
533                 for(int i = 0; i < arrByte.length; i++) {
534                         arrByt[i] = arrByte[i];
535                 }
536
537                 return arrByt;
538         }
539
540
541         public static byte[] arrShortToByteArray(short[] arrShort) {
542
543                 ByteBuffer bb = ByteBuffer.allocate(SHT_LEN * arrShort.length);
544                 for(short s : arrShort) {
545                         bb.putShort(s);
546                 }
547
548                 return bb.array();
549         }
550
551
552         public static byte[] arrShortToByteArray(Short[] arrShort) {
553
554                 ByteBuffer bb = ByteBuffer.allocate(SHT_LEN * arrShort.length);
555                 for(Short s : arrShort) {
556                         bb.putShort(s);
557                 }
558
559                 return bb.array();
560         }
561
562
563         public static byte[] arrIntToByteArray(int[] arrInt) {
564
565                 ByteBuffer bb = ByteBuffer.allocate(INT_LEN * arrInt.length);
566                 for(int i : arrInt) {
567                         bb.putInt(i);
568                 }
569
570                 return bb.array();
571         }
572
573
574         public static byte[] arrIntToByteArray(Integer[] arrInt) {
575
576                 ByteBuffer bb = ByteBuffer.allocate(INT_LEN * arrInt.length);
577                 for(Integer i : arrInt) {
578                         bb.putInt(i);
579                 }
580
581                 return bb.array();
582         }
583
584
585         public static byte[] arrLongToByteArray(long[] arrLong) {
586
587                 ByteBuffer bb = ByteBuffer.allocate(LNG_LEN * arrLong.length);
588                 for(long l : arrLong) {
589                         bb.putLong(l);
590                 }
591
592                 return bb.array();
593         }
594
595
596         public static byte[] arrLongToByteArray(Long[] arrLong) {
597
598                 ByteBuffer bb = ByteBuffer.allocate(LNG_LEN * arrLong.length);
599                 for(Long l : arrLong) {
600                         bb.putLong(l);
601                 }
602
603                 return bb.array();
604         }
605
606
607         public static byte[] arrFloatToByteArray(float[] arrFloat) {
608
609                 ByteBuffer bb = ByteBuffer.allocate(FLT_LEN * arrFloat.length);
610                 for(float f : arrFloat) {
611                         bb.putFloat(f);
612                 }
613
614                 return bb.array();
615         }
616
617
618         public static byte[] arrFloatToByteArray(Float[] arrFloat) {
619
620                 ByteBuffer bb = ByteBuffer.allocate(FLT_LEN * arrFloat.length);
621                 for(Float f : arrFloat) {
622                         bb.putFloat(f);
623                 }
624
625                 return bb.array();
626         }
627
628
629         public static byte[] arrDoubleToByteArray(double[] arrDouble) {
630
631                 ByteBuffer bb = ByteBuffer.allocate(DBL_LEN * arrDouble.length);
632                 for(double d : arrDouble) {
633                         bb.putDouble(d);
634                 }
635
636                 return bb.array();
637         }
638
639
640         public static byte[] arrDoubleToByteArray(Double[] arrDouble) {
641
642                 ByteBuffer bb = ByteBuffer.allocate(DBL_LEN * arrDouble.length);
643                 for(Double d : arrDouble) {
644                         bb.putDouble(d);
645                 }
646
647                 return bb.array();
648         }
649
650
651         public static byte[] arrCharToByteArray(char[] arrChar) {
652
653                 ByteBuffer bb = ByteBuffer.allocate(CHR_LEN * arrChar.length);
654                 for(char c : arrChar) {
655                         bb.putChar(c);
656                 }
657
658                 return bb.array();
659         }
660
661
662         public static byte[] arrCharToByteArray(Character[] arrChar) {
663
664                 ByteBuffer bb = ByteBuffer.allocate(CHR_LEN * arrChar.length);
665                 for(Character c : arrChar) {
666                         bb.putChar(c);
667                 }
668
669                 return bb.array();
670         }
671
672
673         public static byte[] arrBooleanToByteArray(boolean[] arrBool) {
674
675                 ByteBuffer bb = ByteBuffer.allocate(BOL_LEN * arrBool.length);
676                 for(boolean b : arrBool) {
677                         if (b)
678                                 bb.put((byte)1);
679                         else
680                                 bb.put((byte)0);
681                 }
682
683                 return bb.array();
684         }
685
686
687         public static byte[] arrBooleanToByteArray(Boolean[] arrBool) {
688
689                 ByteBuffer bb = ByteBuffer.allocate(BOL_LEN * arrBool.length);
690                 for(Boolean b : arrBool) {
691                         if (b)
692                                 bb.put((byte)1);
693                         else
694                                 bb.put((byte)0);
695                 }
696
697                 return bb.array();
698         }
699
700
701         public static byte[] arrStringToByteArray(String[] arrString) {
702
703                 // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
704                 // Prepare array of bytes
705                 int arrLen = INT_LEN;   // First allocation for array length
706                 for (int i = 0; i < arrString.length; i++) {
707                         arrLen = arrLen + INT_LEN + arrString[i].length();
708                 }       
709                 byte[] arrStrBytes = new byte[arrLen];
710                 // Copy bytes
711                 int pos = 0;
712                 byte[] strArrLenBytes = intToByteArray(arrString.length);
713                 System.arraycopy(strArrLenBytes, 0, arrStrBytes, pos, INT_LEN);
714                 pos = pos + INT_LEN;
715                 for (String str : arrString) {
716
717                         // Copy string length
718                         int strLen = str.length();
719                         byte[] strLenBytes = intToByteArray(strLen);
720                         System.arraycopy(strLenBytes, 0, arrStrBytes, pos, INT_LEN);
721                         pos = pos + INT_LEN;
722                         // Copy string
723                         byte[] strBytes = stringToByteArray(str);
724                         System.arraycopy(strBytes, 0, arrStrBytes, pos, strLen);
725                         pos = pos + strLen;
726                 }
727
728                 return arrStrBytes;
729         }
730
731
732         /**
733          * Converters from byte array
734          */
735         // Single variables     
736         public static short byteArrayToShort(byte[] bytes) {
737
738                 return ByteBuffer.wrap(bytes).getShort();
739         }
740
741
742         public static int byteArrayToInt(byte[] bytes) {
743
744                 return ByteBuffer.wrap(bytes).getInt();
745         }
746
747
748         public static long byteArrayToLong(byte[] bytes) {
749
750                 return ByteBuffer.wrap(bytes).getLong();
751         }
752
753
754         public static float byteArrayToFloat(byte[] bytes) {
755
756                 return ByteBuffer.wrap(bytes).getFloat();
757         }
758
759
760         public static double byteArrayToDouble(byte[] bytes) {
761
762                 return ByteBuffer.wrap(bytes).getDouble();
763         }
764
765
766         public static char byteArrayToChar(byte[] bytes) {
767
768                 return ByteBuffer.wrap(bytes).getChar();
769         }
770
771
772         public static boolean byteArrayToBoolean(byte[] bytes) {
773
774                 Byte boolValByte = ByteBuffer.wrap(bytes).get();
775                 short boolVal = boolValByte.shortValue();
776                 if (boolVal == 1)
777                         return true;
778                 else
779                         return false;
780         }
781
782
783     public static String byteArrayToString(byte[] bytes) {
784         return new String(bytes);
785     }
786
787
788         // Arrays
789         public static Byte[] byteArrayToByteArray(byte[] arrByt) {
790
791                 Byte[] arrByte = new Byte[arrByt.length];
792                 for(int i = 0; i < arrByt.length; i++) {
793                         arrByte[i] = arrByt[i];
794                 }
795
796                 return arrByte;
797         }
798         
799         
800         public static short[] byteArrayToShtArray(byte[] bytes) {
801
802                 // Single element bytes
803                 byte[] elmt = new byte[SHT_LEN];
804                 // Prepare array
805                 int arrLen = bytes.length / SHT_LEN;
806                 short[] arr = new short[arrLen];
807                 for(int i = 0; i < arrLen; i++) {
808                         int offset = i * SHT_LEN;
809                         System.arraycopy(bytes, offset, elmt, 0, SHT_LEN);              
810                         arr[i] = byteArrayToShort(elmt);
811                 }
812
813                 return arr;
814         }
815
816
817         public static Short[] byteArrayToShortArray(byte[] bytes) {
818
819                 // Single element bytes
820                 byte[] elmt = new byte[SHT_LEN];
821                 // Prepare array
822                 int arrLen = bytes.length / SHT_LEN;
823                 Short[] arr = new Short[arrLen];
824                 for(int i = 0; i < arrLen; i++) {
825                         int offset = i * SHT_LEN;
826                         System.arraycopy(bytes, offset, elmt, 0, SHT_LEN);              
827                         arr[i] = byteArrayToShort(elmt);
828                 }
829
830                 return arr;
831         }
832
833
834         public static int[] byteArrayToIntArray(byte[] bytes) {
835
836                 // Single element bytes
837                 byte[] elmt = new byte[INT_LEN];
838                 // Prepare array
839                 int arrLen = bytes.length / INT_LEN;
840                 int[] arr = new int[arrLen];
841                 for(int i = 0; i < arrLen; i++) {
842                         int offset = i * INT_LEN;
843                         System.arraycopy(bytes, offset, elmt, 0, INT_LEN);              
844                         arr[i] = byteArrayToInt(elmt);
845                 }
846
847                 return arr;
848         }
849
850
851         public static Integer[] byteArrayToIntegerArray(byte[] bytes) {
852
853                 // Single element bytes
854                 byte[] elmt = new byte[INT_LEN];
855                 // Prepare array
856                 int arrLen = bytes.length / INT_LEN;
857                 Integer[] arr = new Integer[arrLen];
858                 for(int i = 0; i < arrLen; i++) {
859                         int offset = i * INT_LEN;
860                         System.arraycopy(bytes, offset, elmt, 0, INT_LEN);
861                         arr[i] = byteArrayToInt(elmt);
862                 }
863
864                 return arr;
865         }
866
867
868         public static long[] byteArrayToLngArray(byte[] bytes) {
869
870                 // Single element bytes
871                 byte[] elmt = new byte[LNG_LEN];
872                 // Prepare array
873                 int arrLen = bytes.length / LNG_LEN;
874                 long[] arr = new long[arrLen];
875                 for(int i = 0; i < arrLen; i++) {
876                         int offset = i * LNG_LEN;
877                         System.arraycopy(bytes, offset, elmt, 0, LNG_LEN);              
878                         arr[i] = byteArrayToLong(elmt);
879                 }
880
881                 return arr;
882         }
883
884
885         public static Long[] byteArrayToLongArray(byte[] bytes) {
886
887                 // Single element bytes
888                 byte[] elmt = new byte[LNG_LEN];
889                 // Prepare array
890                 int arrLen = bytes.length / LNG_LEN;
891                 Long[] arr = new Long[arrLen];
892                 for(int i = 0; i < arrLen; i++) {
893                         int offset = i * LNG_LEN;
894                         System.arraycopy(bytes, offset, elmt, 0, LNG_LEN);
895                         arr[i] = byteArrayToLong(elmt);
896                 }
897
898                 return arr;
899         }
900
901
902         public static float[] byteArrayToFltArray(byte[] bytes) {
903
904                 // Single element bytes
905                 byte[] elmt = new byte[FLT_LEN];
906                 // Prepare array
907                 int arrLen = bytes.length / FLT_LEN;
908                 float[] arr = new float[arrLen];
909                 for(int i = 0; i < arrLen; i++) {
910                         int offset = i * FLT_LEN;
911                         System.arraycopy(bytes, offset, elmt, 0, FLT_LEN);              
912                         arr[i] = byteArrayToFloat(elmt);
913                 }
914
915                 return arr;
916         }
917
918
919         public static Float[] byteArrayToFloatArray(byte[] bytes) {
920
921                 // Single element bytes
922                 byte[] elmt = new byte[FLT_LEN];
923                 // Prepare array
924                 int arrLen = bytes.length / FLT_LEN;
925                 Float[] arr = new Float[arrLen];
926                 for(int i = 0; i < arrLen; i++) {
927                         int offset = i * FLT_LEN;
928                         System.arraycopy(bytes, offset, elmt, 0, FLT_LEN);
929                         arr[i] = byteArrayToFloat(elmt);
930                 }
931
932                 return arr;
933         }
934
935
936         public static double[] byteArrayToDblArray(byte[] bytes) {
937
938                 // Single element bytes
939                 byte[] elmt = new byte[DBL_LEN];
940                 // Prepare array
941                 int arrLen = bytes.length / DBL_LEN;
942                 double[] arr = new double[arrLen];
943                 for(int i = 0; i < arrLen; i++) {
944                         int offset = i * DBL_LEN;
945                         System.arraycopy(bytes, offset, elmt, 0, DBL_LEN);
946                         arr[i] = byteArrayToDouble(elmt);
947                 }
948
949                 return arr;
950         }
951
952
953         public static Double[] byteArrayToDoubleArray(byte[] bytes) {
954
955                 // Single element bytes
956                 byte[] elmt = new byte[DBL_LEN];
957                 // Prepare array
958                 int arrLen = bytes.length / DBL_LEN;
959                 Double[] arr = new Double[arrLen];
960                 for(int i = 0; i < arrLen; i++) {
961                         int offset = i * DBL_LEN;
962                         System.arraycopy(bytes, offset, elmt, 0, DBL_LEN);
963                         arr[i] = byteArrayToDouble(elmt);
964                 }
965
966                 return arr;
967         }
968
969
970         public static char[] byteArrayToChrArray(byte[] bytes) {
971
972                 // Single element bytes
973                 byte[] elmt = new byte[CHR_LEN];
974                 // Prepare array
975                 int arrLen = bytes.length / CHR_LEN;
976                 char[] arr = new char[arrLen];
977                 for(int i = 0; i < arrLen; i++) {
978                         int offset = i * CHR_LEN;
979                         System.arraycopy(bytes, offset, elmt, 0, CHR_LEN);
980                         arr[i] = byteArrayToChar(elmt);
981                 }
982
983                 return arr;
984         }
985
986
987         public static Character[] byteArrayToCharacterArray(byte[] bytes) {
988
989                 // Single element bytes
990                 byte[] elmt = new byte[CHR_LEN];
991                 // Prepare array
992                 int arrLen = bytes.length / CHR_LEN;
993                 Character[] arr = new Character[arrLen];
994                 for(int i = 0; i < arrLen; i++) {
995                         int offset = i * CHR_LEN;
996                         System.arraycopy(bytes, offset, elmt, 0, CHR_LEN);
997                         arr[i] = byteArrayToChar(elmt);
998                 }
999
1000                 return arr;
1001         }
1002
1003
1004         public static boolean[] byteArrayToBolArray(byte[] bytes) {
1005
1006                 // Single element bytes
1007                 byte[] elmt = new byte[BOL_LEN];
1008                 // Prepare array
1009                 int arrLen = bytes.length / BOL_LEN;
1010                 boolean[] arr = new boolean[arrLen];
1011                 for(int i = 0; i < arrLen; i++) {
1012                         int offset = i * BOL_LEN;
1013                         System.arraycopy(bytes, offset, elmt, 0, BOL_LEN);
1014                         arr[i] = byteArrayToBoolean(elmt);
1015                 }
1016
1017                 return arr;
1018         }
1019
1020
1021         public static Boolean[] byteArrayToBooleanArray(byte[] bytes) {
1022
1023                 // Single element bytes
1024                 byte[] elmt = new byte[BOL_LEN];
1025                 // Prepare array
1026                 int arrLen = bytes.length / BOL_LEN;
1027                 Boolean[] arr = new Boolean[arrLen];
1028                 for(int i = 0; i < arrLen; i++) {
1029                         int offset = i * BOL_LEN;
1030                         System.arraycopy(bytes, offset, elmt, 0, BOL_LEN);
1031                         arr[i] = byteArrayToBoolean(elmt);
1032                 }
1033
1034                 return arr;
1035         }
1036
1037
1038         public static String[] byteArrayToStringArray(byte[] bytes) {
1039
1040                 // Format of bytes: | array length | length #1 | string #1 | length #2 | string #2 | ...
1041                 // Get string array length
1042                 int pos = 0;
1043                 byte[] strArrLenBytes = new byte[INT_LEN];
1044                 System.arraycopy(bytes, pos, strArrLenBytes, 0, INT_LEN);
1045                 int strArrLen = byteArrayToInt(strArrLenBytes);
1046                 pos = pos + INT_LEN;
1047                 // Prepare string array
1048                 String[] strArray = new String[strArrLen];
1049                 // Extract array of strings
1050                 for(int i = 0; i < strArrLen; i++) {
1051
1052                         // Extract string length
1053                         byte[] strLenBytes = new byte[INT_LEN];
1054                         System.arraycopy(bytes, pos, strLenBytes, 0, INT_LEN);
1055                         int strLen = byteArrayToInt(strLenBytes);
1056                         pos = pos + INT_LEN;
1057                         // Extract string
1058                         byte[] strBytes = new byte[strLen];
1059                         System.arraycopy(bytes, pos, strBytes, 0, strLen);
1060                         pos = pos + strLen;
1061                         strArray[i] = byteArrayToString(strBytes);
1062                 }
1063
1064                 return strArray;
1065         }
1066
1067
1068         /**
1069          * toByteArray() gets Object and return its byte array
1070          * <p>
1071          * Adapted from http://www.java2s.com/
1072          *              @see <a href="http://www.java2s.com/Code/Java/File-Input-
1073          *              Output/Convertobjecttobytearrayandconvertbytearraytoobject.htm"</a>
1074          */
1075     // toByteArray and toObject are taken from: http://tinyurl.com/69h8l7x
1076     public static byte[] toByteArray(Object obj) throws IOException {
1077
1078         byte[] bytes = null;
1079         ByteArrayOutputStream bos = null;
1080         ObjectOutputStream oos = null;
1081         try {
1082
1083             bos = new ByteArrayOutputStream();
1084             oos = new ObjectOutputStream(bos);
1085             oos.writeObject(obj);
1086             oos.flush();
1087             bytes = bos.toByteArray();
1088         } finally {
1089
1090             if (oos != null) {
1091                 oos.close();
1092             }
1093             if (bos != null) {
1094                 bos.close();
1095             }
1096         }
1097         return bytes;
1098     }
1099
1100
1101         /**
1102          * toObject() gets byte array and return its Object
1103          * <p>
1104          * Adapted from http://www.java2s.com/
1105          *              @see <a href="http://www.java2s.com/Code/Java/File-Input-
1106          *              Output/Convertobjecttobytearrayandconvertbytearraytoobject.htm"</a>
1107          */
1108     public static Object toObject(byte[] bytes) throws IOException, ClassNotFoundException {
1109
1110         Object obj = null;
1111         ByteArrayInputStream bis = null;
1112         ObjectInputStream ois = null;
1113         try {
1114
1115             bis = new ByteArrayInputStream(bytes);
1116             ois = new ObjectInputStream(bis);
1117             obj = ois.readObject();
1118         } finally {
1119
1120             if (bis != null) {
1121                 bis.close();
1122             }
1123             if (ois != null) {
1124                 ois.close();
1125             }
1126         }
1127         return obj;
1128     }
1129 }