001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.type.collection.array;
020
021import icy.type.DataType;
022
023/**
024 * Utilities class to convert any data array from/to byte array.
025 * 
026 * @author Stephane
027 */
028public class ByteArrayConvert
029{
030    /**
031     * Get maximum length in bytes for a copy from in to out with specified offset.<br>
032     * If specified length != -1 then the value is directly returned (assumed to be in bytes).
033     */
034    static int getCopyLengthInBytes(Object in, int inOffset, Object out, int outOffset, int length)
035    {
036        if (length == -1)
037            return getCopyLengthInBytes(in, inOffset, out, outOffset);
038
039        return length;
040    }
041
042    /**
043     * Get maximum length in bytes for a copy from in to out with specified offset.
044     */
045    public static int getCopyLengthInBytes(Object in, int inOffset, Object out, int outOffset)
046    {
047        // 'in' object can't be null !
048        final int len = getCopyLengthInBytes(in, inOffset);
049
050        if (out == null)
051            return len;
052
053        return Math.min(len, getCopyLengthInBytes(out, outOffset));
054    }
055
056    /**
057     * Get length in bytes for a copy from or to array with specified offset.
058     */
059    public static int getCopyLengthInBytes(Object array, int offset)
060    {
061        return ArrayUtil.getCopyLength(array, offset) * ArrayUtil.getDataType(array).getSize();
062    }
063
064    /**
065     * Read a byte from the input byte array at specified position.
066     */
067    public static byte readByte(byte[] array, int offset)
068    {
069        return array[offset];
070    }
071
072    /**
073     * Read a short value from the input byte array at specified position.
074     */
075    public static short readShort(byte[] array, int offset, boolean littleEndian)
076    {
077        if (littleEndian)
078            return (short) (((array[offset + 0] & 0xFF) << 0) + ((array[offset + 1] & 0xFF) << 8));
079
080        return (short) (((array[offset + 0] & 0xFF) << 8) + ((array[offset + 1] & 0xFF) << 0));
081    }
082
083    /**
084     * Read a int value from the input byte array at specified position.
085     */
086    public static int readInt(byte[] array, int offset, boolean littleEndian)
087    {
088        if (littleEndian)
089            return ((array[offset + 0] & 0xFF) << 0) + ((array[offset + 1] & 0xFF) << 8)
090                    + ((array[offset + 2] & 0xFF) << 16) + ((array[offset + 3] & 0xFF) << 24);
091
092        return ((array[offset + 0] & 0xFF) << 24) + ((array[offset + 1] & 0xFF) << 16)
093                + ((array[offset + 2] & 0xFF) << 8) + ((array[offset + 3] & 0xFF) << 0);
094    }
095
096    /**
097     * Read a long value from the input byte array at specified position.
098     */
099    public static long readLong(byte[] array, int offset, boolean littleEndian)
100    {
101        if (littleEndian)
102        {
103            final int v1 = ((array[offset + 0] & 0xFF) << 0) + ((array[offset + 1] & 0xFF) << 8)
104                    + ((array[offset + 2] & 0xFF) << 16) + ((array[offset + 3] & 0xFF) << 24);
105            final int v2 = ((array[offset + 4] & 0xFF) << 0) + ((array[offset + 5] & 0xFF) << 8)
106                    + ((array[offset + 6] & 0xFF) << 16) + ((array[offset + 7] & 0xFF) << 24);
107            return ((v1 & 0xFFFFFFFFL) << 0) + ((v2 & 0xFFFFFFFFL) << 32);
108        }
109
110        final int v1 = ((array[offset + 0] & 0xFF) << 24) + ((array[offset + 1] & 0xFF) << 16)
111                + ((array[offset + 2] & 0xFF) << 8) + ((array[offset + 3] & 0xFF) << 0);
112        final int v2 = ((array[offset + 4] & 0xFF) << 24) + ((array[offset + 5] & 0xFF) << 16)
113                + ((array[offset + 6] & 0xFF) << 8) + ((array[offset + 7] & 0xFF) << 0);
114        return ((v1 & 0xFFFFFFFFL) << 32) + ((v2 & 0xFFFFFFFFL) << 0);
115    }
116
117    /**
118     * Read a long value from the input byte array at specified position.
119     */
120    public static float readFloat(byte[] array, int offset, boolean littleEndian)
121    {
122        return Float.intBitsToFloat(readInt(array, offset, littleEndian));
123    }
124
125    /**
126     * Read a long value from the input byte array at specified position.
127     */
128    public static double readDouble(byte[] array, int offset, boolean littleEndian)
129    {
130        return Double.longBitsToDouble(readLong(array, offset, littleEndian));
131    }
132
133    /**
134     * Write a byte to the output byte array at specified position.
135     */
136    public static void writeByte(byte[] array, int offset, byte value)
137    {
138        array[offset] = value;
139    }
140
141    /**
142     * Write a short to the output byte array at specified position.
143     */
144    public static void writeShort(byte[] array, int offset, short value, boolean littleEndian)
145    {
146        if (littleEndian)
147        {
148            array[offset + 0] = (byte) (value >> 0);
149            array[offset + 1] = (byte) (value >> 8);
150        }
151        else
152        {
153            array[offset + 0] = (byte) (value >> 8);
154            array[offset + 1] = (byte) (value >> 0);
155        }
156    }
157
158    /**
159     * Write a int to the output byte array at specified position.
160     */
161    public static void writeInt(byte[] array, int offset, int value, boolean littleEndian)
162    {
163        if (littleEndian)
164        {
165            array[offset + 0] = (byte) (value >> 0);
166            array[offset + 1] = (byte) (value >> 8);
167            array[offset + 2] = (byte) (value >> 16);
168            array[offset + 3] = (byte) (value >> 24);
169        }
170        else
171        {
172            array[offset + 0] = (byte) (value >> 24);
173            array[offset + 1] = (byte) (value >> 16);
174            array[offset + 2] = (byte) (value >> 8);
175            array[offset + 3] = (byte) (value >> 0);
176        }
177    }
178
179    /**
180     * Write a long to the output byte array at specified position.
181     */
182    public static void writeLong(byte[] array, int offset, long value, boolean littleEndian)
183    {
184        int v;
185
186        if (littleEndian)
187        {
188            v = (int) (value >> 0);
189            array[offset + 0] = (byte) (v >> 0);
190            array[offset + 1] = (byte) (v >> 8);
191            array[offset + 2] = (byte) (v >> 16);
192            array[offset + 3] = (byte) (v >> 24);
193            v = (int) (value >> 32);
194            array[offset + 4] = (byte) (v >> 0);
195            array[offset + 5] = (byte) (v >> 8);
196            array[offset + 6] = (byte) (v >> 16);
197            array[offset + 7] = (byte) (v >> 24);
198        }
199        else
200        {
201            v = (int) (value >> 32);
202            array[offset + 0] = (byte) (v >> 24);
203            array[offset + 1] = (byte) (v >> 16);
204            array[offset + 2] = (byte) (v >> 8);
205            array[offset + 3] = (byte) (v >> 0);
206            v = (int) (value >> 0);
207            array[offset + 4] = (byte) (v >> 24);
208            array[offset + 5] = (byte) (v >> 16);
209            array[offset + 6] = (byte) (v >> 8);
210            array[offset + 7] = (byte) (v >> 0);
211        }
212    }
213
214    /**
215     * Write a float to the output byte array at specified position.
216     */
217    public static void writeFloat(byte[] array, int offset, float value, boolean littleEndian)
218    {
219        writeInt(array, offset, Float.floatToRawIntBits(value), littleEndian);
220    }
221
222    /**
223     * Write a double to the output byte array at specified position.
224     */
225    public static void writeDouble(byte[] array, int offset, double value, boolean littleEndian)
226    {
227        writeLong(array, offset, Double.doubleToRawLongBits(value), littleEndian);
228    }
229
230    /**
231     * Bit transform and return the 'in' byte array in the specified data type array
232     * 
233     * @param in
234     *        input array
235     * @param inOffset
236     *        position where we start read data from
237     * @param out
238     *        output array which is used to receive result (and so define wanted type)
239     * @param outOffset
240     *        position where we start to write data to
241     * @param length
242     *        number of bytes to compute (-1 means we will use the maximum possible)
243     */
244    public static byte[] byteArrayToByteArray(byte[] in, int inOffset, byte[] out, int outOffset, int length)
245    {
246        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length);
247        final byte[] result = Array1DUtil.allocIfNull(out, outOffset + len);
248
249        // simple copy
250        System.arraycopy(in, inOffset, result, outOffset, len);
251
252        return result;
253    }
254
255    /**
256     * Bit transform and return the 'in' byte array in the specified data type array
257     * 
258     * @param in
259     *        input array
260     * @param out
261     *        output array which is used to receive result (and so define wanted type)
262     */
263    public static byte[] byteArrayToByteArray(byte[] in, byte[] out)
264    {
265        return byteArrayToByteArray(in, 0, out, 0, -1);
266    }
267
268    /**
269     * Bit transform and return the 'in' byte array in the specified data type array
270     * 
271     * @param in
272     *        input array
273     */
274    public static byte[] byteArrayToByteArray(byte[] in)
275    {
276        return byteArrayToByteArray(in, 0, null, 0, -1);
277    }
278
279    /**
280     * Bit transform and return the 'in' byte array in the specified data type array
281     * 
282     * @param in
283     *        input array
284     * @param inOffset
285     *        position where we start read data from
286     * @param out
287     *        output array which is used to receive result (and so define wanted type)
288     * @param outOffset
289     *        position where we start to write data to
290     * @param length
291     *        number of bytes to compute (-1 means we will use the maximum possible)
292     * @param little
293     *        little endian order
294     */
295    public static short[] byteArrayToShortArray(byte[] in, int inOffset, short[] out, int outOffset, int length,
296            boolean little)
297    {
298        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length) / 2;
299        final short[] result = Array1DUtil.allocIfNull(out, outOffset + len);
300
301        int inOff = inOffset;
302        int outOff = outOffset;
303
304        for (int i = 0; i < len; i++)
305        {
306            result[outOff++] = readShort(in, inOff, little);
307            inOff += 2;
308        }
309
310        return result;
311    }
312
313    /**
314     * Bit transform and return the 'in' byte array in the specified data type array
315     * 
316     * @param in
317     *        input array
318     * @param out
319     *        output array which is used to receive result (and so define wanted type)
320     * @param little
321     *        little endian order
322     */
323    public static short[] byteArrayToShortArray(byte[] in, short[] out, boolean little)
324    {
325        return byteArrayToShortArray(in, 0, out, 0, -1, little);
326    }
327
328    /**
329     * Bit transform and return the 'in' byte array in the specified data type array
330     * 
331     * @param in
332     *        input array
333     * @param little
334     *        little endian order
335     */
336    public static short[] byteArrayToShortArray(byte[] in, boolean little)
337    {
338        return byteArrayToShortArray(in, 0, null, 0, -1, little);
339    }
340
341    /**
342     * Bit transform and return the 'in' byte array in the specified data type array
343     * 
344     * @param in
345     *        input array
346     * @param inOffset
347     *        position where we start read data from
348     * @param out
349     *        output array which is used to receive result (and so define wanted type)
350     * @param outOffset
351     *        position where we start to write data to
352     * @param length
353     *        number of bytes to compute (-1 means we will use the maximum possible)
354     * @param little
355     *        little endian order
356     */
357    public static int[] byteArrayToIntArray(byte[] in, int inOffset, int[] out, int outOffset, int length,
358            boolean little)
359    {
360        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length) / 4;
361        final int[] result = Array1DUtil.allocIfNull(out, outOffset + len);
362
363        int inOff = inOffset;
364        int outOff = outOffset;
365
366        for (int i = 0; i < len; i++)
367        {
368            result[outOff++] = readInt(in, inOff, little);
369            inOff += 4;
370        }
371
372        return result;
373    }
374
375    /**
376     * Bit transform and return the 'in' byte array in the specified data type array
377     * 
378     * @param in
379     *        input array
380     * @param out
381     *        output array which is used to receive result (and so define wanted type)
382     * @param little
383     *        little endian order
384     */
385    public static int[] byteArrayToIntArray(byte[] in, int[] out, boolean little)
386    {
387        return byteArrayToIntArray(in, 0, out, 0, -1, little);
388    }
389
390    /**
391     * Bit transform and return the 'in' byte array in the specified data type array
392     * 
393     * @param in
394     *        input array
395     * @param little
396     *        little endian order
397     */
398    public static int[] byteArrayToIntArray(byte[] in, boolean little)
399    {
400        return byteArrayToIntArray(in, 0, null, 0, -1, little);
401    }
402
403    /**
404     * Bit transform and return the 'in' byte array in the specified data type array
405     * 
406     * @param in
407     *        input array
408     * @param inOffset
409     *        position where we start read data from
410     * @param out
411     *        output array which is used to receive result (and so define wanted type)
412     * @param outOffset
413     *        position where we start to write data to
414     * @param length
415     *        number of bytes to compute (-1 means we will use the maximum possible)
416     * @param little
417     *        little endian order
418     */
419    public static long[] byteArrayToLongArray(byte[] in, int inOffset, long[] out, int outOffset, int length,
420            boolean little)
421    {
422        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length) / 8;
423        final long[] result = Array1DUtil.allocIfNull(out, outOffset + len);
424
425        int inOff = inOffset;
426        int outOff = outOffset;
427
428        for (int i = 0; i < len; i++)
429        {
430            result[outOff++] = readLong(in, inOff, little);
431            inOff += 8;
432        }
433
434        return result;
435    }
436
437    /**
438     * Bit transform and return the 'in' byte array in the specified data type array
439     * 
440     * @param in
441     *        input array
442     * @param out
443     *        output array which is used to receive result (and so define wanted type)
444     * @param little
445     *        little endian order
446     */
447    public static long[] byteArrayToLongArray(byte[] in, long[] out, boolean little)
448    {
449        return byteArrayToLongArray(in, 0, out, 0, -1, little);
450    }
451
452    /**
453     * Bit transform and return the 'in' byte array in the specified data type array
454     * 
455     * @param in
456     *        input array
457     * @param little
458     *        little endian order
459     */
460    public static long[] byteArrayToLongArray(byte[] in, boolean little)
461    {
462        return byteArrayToLongArray(in, 0, null, 0, -1, little);
463    }
464
465    /**
466     * Bit transform and return the 'in' byte array in 'out' float array
467     * 
468     * @param in
469     *        input array
470     * @param inOffset
471     *        position where we start read data from
472     * @param out
473     *        output array which is used to receive result (and so define wanted type)
474     * @param outOffset
475     *        position where we start to write data to
476     * @param length
477     *        number of bytes to compute (-1 means we will use the maximum possible)
478     * @param little
479     *        little endian order
480     */
481    public static float[] byteArrayToFloatArray(byte[] in, int inOffset, float[] out, int outOffset, int length,
482            boolean little)
483    {
484        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length) / 4;
485        final float[] result = Array1DUtil.allocIfNull(out, outOffset + len);
486
487        int inOff = inOffset;
488        int outOff = outOffset;
489
490        for (int i = 0; i < len; i++)
491        {
492            result[outOff++] = readFloat(in, inOff, little);
493            inOff += 4;
494        }
495
496        return result;
497    }
498
499    /**
500     * Bit transform and return the 'in' byte array in the specified data type array
501     * 
502     * @param in
503     *        input array
504     * @param out
505     *        output array which is used to receive result (and so define wanted type)
506     * @param little
507     *        little endian order
508     */
509    public static float[] byteArrayToFloatArray(byte[] in, float[] out, boolean little)
510    {
511        return byteArrayToFloatArray(in, 0, out, 0, -1, little);
512    }
513
514    /**
515     * Bit transform and return the 'in' byte array in the specified data type array
516     * 
517     * @param in
518     *        input array
519     * @param little
520     *        little endian order
521     */
522    public static float[] byteArrayToFloatArray(byte[] in, boolean little)
523    {
524        return byteArrayToFloatArray(in, 0, null, 0, -1, little);
525    }
526
527    /**
528     * Bit transform and return the 'in' byte array in the specified data type array
529     * 
530     * @param in
531     *        input array
532     * @param inOffset
533     *        position where we start read data from
534     * @param out
535     *        output array which is used to receive result (and so define wanted type)
536     * @param outOffset
537     *        position where we start to write data to
538     * @param length
539     *        number of bytes to compute (-1 means we will use the maximum possible)
540     * @param little
541     *        little endian order
542     */
543    public static double[] byteArrayToDoubleArray(byte[] in, int inOffset, double[] out, int outOffset, int length,
544            boolean little)
545    {
546        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length) / 8;
547        final double[] result = Array1DUtil.allocIfNull(out, outOffset + len);
548
549        int inOff = inOffset;
550        int outOff = outOffset;
551
552        for (int i = 0; i < len; i++)
553        {
554            result[outOff++] = readDouble(in, inOff, little);
555            inOff += 8;
556        }
557
558        return result;
559    }
560
561    /**
562     * Bit transform and return the 'in' byte array in the specified data type array
563     * 
564     * @param in
565     *        input array
566     * @param out
567     *        output array which is used to receive result (and so define wanted type)
568     * @param little
569     *        little endian order
570     */
571    public static double[] byteArrayToDoubleArray(byte[] in, double[] out, boolean little)
572    {
573        return byteArrayToDoubleArray(in, 0, out, 0, -1, little);
574    }
575
576    /**
577     * Bit transform and return the 'in' byte array in the specified data type array
578     * 
579     * @param in
580     *        input array
581     * @param little
582     *        little endian order
583     */
584    public static double[] byteArrayToDoubleArray(byte[] in, boolean little)
585    {
586        return byteArrayToDoubleArray(in, 0, null, 0, -1, little);
587    }
588
589    /**
590     * Bit transform and return the 'in' short array as byte array
591     * 
592     * @param in
593     *        input array
594     * @param inOffset
595     *        position where we start read data from
596     * @param out
597     *        output byte array which is used to receive result
598     * @param outOffset
599     *        position where we start to write data to
600     * @param length
601     *        number of <b>bytes</b> to compute (-1 means we will use the maximum possible)
602     * @param little
603     *        little endian order
604     */
605    public static byte[] shortArrayToByteArray(short[] in, int inOffset, byte[] out, int outOffset, int length,
606            boolean little)
607    {
608        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length);
609        final byte[] result = Array1DUtil.allocIfNull(out, outOffset + len);
610
611        int inOff = inOffset;
612        int outOff = outOffset;
613
614        for (int i = 0; i < len / 2; i++)
615        {
616            writeShort(result, outOff, in[inOff++], little);
617            outOff += 2;
618        }
619
620        return result;
621    }
622
623    /**
624     * Bit transform and return the 'in' int array as byte array
625     * 
626     * @param in
627     *        input array
628     * @param inOffset
629     *        position where we start read data from
630     * @param out
631     *        output byte array which is used to receive result
632     * @param outOffset
633     *        position where we start to write data to
634     * @param length
635     *        number of <b>bytes</b> to compute (-1 means we will use the maximum possible)
636     * @param little
637     *        little endian order
638     */
639    public static byte[] intArrayToByteArray(int[] in, int inOffset, byte[] out, int outOffset, int length,
640            boolean little)
641    {
642        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length);
643        final byte[] result = Array1DUtil.allocIfNull(out, outOffset + len);
644
645        int inOff = inOffset;
646        int outOff = outOffset;
647
648        for (int i = 0; i < len / 4; i++)
649        {
650            writeInt(result, outOff, in[inOff++], little);
651            outOff += 4;
652        }
653
654        return result;
655    }
656
657    /**
658     * Bit transform and return the 'in' long array as byte array
659     * 
660     * @param in
661     *        input array
662     * @param inOffset
663     *        position where we start read data from
664     * @param out
665     *        output byte array which is used to receive result
666     * @param outOffset
667     *        position where we start to write data to
668     * @param length
669     *        number of <b>bytes</b> to compute (-1 means we will use the maximum possible)
670     * @param little
671     *        little endian order
672     */
673    public static byte[] longArrayToByteArray(long[] in, int inOffset, byte[] out, int outOffset, int length,
674            boolean little)
675    {
676        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length);
677        final byte[] result = Array1DUtil.allocIfNull(out, outOffset + len);
678
679        int inOff = inOffset;
680        int outOff = outOffset;
681
682        for (int i = 0; i < len / 8; i++)
683        {
684            writeLong(result, outOff, in[inOff++], little);
685            outOff += 8;
686        }
687
688        return result;
689    }
690
691    /**
692     * Bit transform and return the 'in' float array as byte array
693     * 
694     * @param in
695     *        input array
696     * @param inOffset
697     *        position where we start read data from
698     * @param out
699     *        output byte array which is used to receive result
700     * @param outOffset
701     *        position where we start to write data to
702     * @param length
703     *        number of <b>bytes</b> to compute (-1 means we will use the maximum possible)
704     * @param little
705     *        little endian order
706     */
707    public static byte[] floatArrayToByteArray(float[] in, int inOffset, byte[] out, int outOffset, int length,
708            boolean little)
709    {
710        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length);
711        final byte[] result = Array1DUtil.allocIfNull(out, outOffset + len);
712
713        int inOff = inOffset;
714        int outOff = outOffset;
715
716        for (int i = 0; i < len / 4; i++)
717        {
718            writeFloat(result, outOff, in[inOff++], little);
719            outOff += 4;
720        }
721
722        return result;
723    }
724
725    /**
726     * Bit transform and return the 'in' double array as byte array
727     * 
728     * @param in
729     *        input array
730     * @param inOffset
731     *        position where we start read data from
732     * @param out
733     *        output byte array which is used to receive result
734     * @param outOffset
735     *        position where we start to write data to
736     * @param length
737     *        number of <b>bytes</b> to compute (-1 means we will use the maximum possible)
738     * @param little
739     *        little endian order
740     */
741    public static byte[] doubleArrayToByteArray(double[] in, int inOffset, byte[] out, int outOffset, int length,
742            boolean little)
743    {
744        final int len = getCopyLengthInBytes(in, inOffset, out, outOffset, length);
745        final byte[] result = Array1DUtil.allocIfNull(out, outOffset + len);
746
747        int inOff = inOffset;
748        int outOff = outOffset;
749
750        for (int i = 0; i < len / 8; i++)
751        {
752            writeDouble(result, outOff, in[inOff++], little);
753            outOff += 8;
754        }
755
756        return result;
757    }
758
759    /**
760     * Bit transform and return the 'in' byte array in the specified 'out' data type array
761     * 
762     * @param in
763     *        input array
764     * @param inOffset
765     *        position where we start read data from
766     * @param out
767     *        output array which is used to receive result (and so define wanted type)
768     * @param outOffset
769     *        position where we start to write data to
770     * @param length
771     *        number of bytes to compute (-1 means we will use the maximum possible)
772     * @param little
773     *        little endian order
774     */
775    public static Object byteArrayTo(byte[] in, int inOffset, Object out, int outOffset, int length, boolean little)
776    {
777        if (out == null)
778            return null;
779
780        switch (ArrayUtil.getDataType(out).getJavaType())
781        {
782            case BYTE:
783                return byteArrayToByteArray(in, inOffset, (byte[]) out, outOffset, length);
784            case SHORT:
785                return byteArrayToShortArray(in, inOffset, (short[]) out, outOffset, length, little);
786            case INT:
787                return byteArrayToIntArray(in, inOffset, (int[]) out, outOffset, length, little);
788            case LONG:
789                return byteArrayToLongArray(in, inOffset, (long[]) out, outOffset, length, little);
790            case FLOAT:
791                return byteArrayToFloatArray(in, inOffset, (float[]) out, outOffset, length, little);
792            case DOUBLE:
793                return byteArrayToDoubleArray(in, inOffset, (double[]) out, outOffset, length, little);
794            default:
795                return null;
796        }
797    }
798
799    /**
800     * Bit transform and return the 'in' byte array in the specified 'out' data type array
801     * 
802     * @param in
803     *        input array
804     * @param out
805     *        output array which is used to receive result (and so define wanted type)
806     * @param little
807     *        little endian order
808     */
809    public static Object byteArrayTo(byte[] in, Object out, boolean little)
810    {
811        return byteArrayTo(in, 0, out, 0, -1, little);
812    }
813
814    /**
815     * Bit transform and return the 'in' byte array in the specified data type array
816     * 
817     * @param in
818     *        input array
819     * @param inOffset
820     *        position where we start read data from
821     * @param outDataType
822     *        wanted output array data type
823     * @param outOffset
824     *        position where we start to write data to
825     * @param length
826     *        number of bytes to compute (-1 means we will use the maximum possible)
827     * @param little
828     *        little endian order
829     */
830    public static Object byteArrayTo(byte[] in, int inOffset, DataType outDataType, int outOffset, int length,
831            boolean little)
832    {
833        switch (outDataType.getJavaType())
834        {
835            case BYTE:
836                return byteArrayToByteArray(in, inOffset, null, outOffset, length);
837            case SHORT:
838                return byteArrayToShortArray(in, inOffset, null, outOffset, length, little);
839            case INT:
840                return byteArrayToIntArray(in, inOffset, null, outOffset, length, little);
841            case LONG:
842                return byteArrayToLongArray(in, inOffset, null, outOffset, length, little);
843            case FLOAT:
844                return byteArrayToFloatArray(in, inOffset, null, outOffset, length, little);
845            case DOUBLE:
846                return byteArrayToDoubleArray(in, inOffset, null, outOffset, length, little);
847            default:
848                return null;
849        }
850    }
851
852    /**
853     * Bit transform and return the 'in' byte array in the specified data type array
854     * 
855     * @param in
856     *        input array
857     * @param inOffset
858     *        position where we start read data from
859     * @param outDataType
860     *        wanted output array data type
861     * @param length
862     *        number of bytes to compute (-1 means we will use the maximum possible)
863     * @param little
864     *        little endian order
865     */
866    public static Object byteArrayTo(byte[] in, int inOffset, DataType outDataType, int length, boolean little)
867    {
868        return byteArrayTo(in, inOffset, outDataType, 0, length, little);
869    }
870
871    /**
872     * Bit transform and return the 'in' byte array in the specified data type array
873     * 
874     * @param in
875     *        input array
876     * @param outDataType
877     *        wanted output array data type
878     * @param little
879     *        little endian order
880     */
881    public static Object byteArrayTo(byte[] in, DataType outDataType, boolean little)
882    {
883        return byteArrayTo(in, 0, outDataType, 0, -1, little);
884    }
885
886    /**
887     * @deprecated use {@link #byteArrayTo(byte[], int , DataType , int , boolean )} instead
888     */
889    @Deprecated
890    public static Object byteArrayTo(byte[] in, int inOffset, int outDataType, int length, boolean little)
891    {
892        return byteArrayTo(in, inOffset, DataType.getDataType(outDataType), 0, length, little);
893    }
894
895    /**
896     * @deprecated use {@link #byteArrayTo(byte[], DataType , boolean )} instead
897     */
898    @Deprecated
899    public static Object byteArrayTo(byte[] in, int outDataType, boolean little)
900    {
901        return byteArrayTo(in, 0, DataType.getDataType(outDataType), 0, -1, little);
902    }
903
904    /**
905     * Bit transform and return the 'in' array as byte array
906     * 
907     * @param in
908     *        input array (define input type)
909     * @param inOffset
910     *        position where we start read data from
911     * @param out
912     *        output byte array which is used to receive result
913     * @param outOffset
914     *        position where we start to write data to
915     * @param length
916     *        number of bytes to compute (-1 means we will use the maximum possible)
917     * @param little
918     *        little endian order
919     */
920    public static byte[] toByteArray(Object in, int inOffset, byte[] out, int outOffset, int length, boolean little)
921    {
922        switch (ArrayUtil.getDataType(in))
923        {
924            case BYTE:
925                return byteArrayToByteArray((byte[]) in, inOffset, out, outOffset, length);
926            case SHORT:
927                return shortArrayToByteArray((short[]) in, inOffset, out, outOffset, length, little);
928            case INT:
929                return intArrayToByteArray((int[]) in, inOffset, out, outOffset, length, little);
930            case LONG:
931                return longArrayToByteArray((long[]) in, inOffset, out, outOffset, length, little);
932            case FLOAT:
933                return floatArrayToByteArray((float[]) in, inOffset, out, outOffset, length, little);
934            case DOUBLE:
935                return doubleArrayToByteArray((double[]) in, inOffset, out, outOffset, length, little);
936            default:
937                return out;
938        }
939    }
940
941    /**
942     * Bit transform and return the 'in' array as byte array
943     * 
944     * @param in
945     *        input array (define input type)
946     * @param inOffset
947     *        position where we start read data from
948     * @param out
949     *        output byte array which is used to receive result
950     * @param outOffset
951     *        position where we start to write data to
952     * @param little
953     *        little endian order
954     */
955    public static byte[] toByteArray(Object in, int inOffset, byte[] out, int outOffset, boolean little)
956    {
957        return toByteArray(in, inOffset, out, outOffset, -1, little);
958    }
959
960    /**
961     * Bit transform and return the 'in' array as byte array
962     * 
963     * @param in
964     *        input array (define input type)
965     * @param inOffset
966     *        position where we start read data from
967     * @param length
968     *        number of <br>
969     *        bytes</b> to compute (-1 means we will use the maximum possible)
970     * @param little
971     *        little endian order
972     */
973    public static byte[] toByteArray(Object in, int inOffset, int length, boolean little)
974    {
975        return toByteArray(in, inOffset, null, 0, length, little);
976    }
977
978    /**
979     * Bit transform and return the 'in' array as byte array
980     * 
981     * @param in
982     *        input array (define input type)
983     * @param out
984     *        output byte array which is used to receive result
985     * @param little
986     *        little endian order
987     */
988    public static byte[] toByteArray(Object in, byte[] out, boolean little)
989    {
990        return toByteArray(in, 0, out, 0, -1, little);
991    }
992
993    /**
994     * Bit transform and return the 'in' array as byte array
995     * 
996     * @param in
997     *        input array (define input type)
998     * @param little
999     *        little endian order
1000     */
1001    public static byte[] toByteArray(Object in, boolean little)
1002    {
1003        return toByteArray(in, 0, null, 0, -1, little);
1004    }
1005}