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