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