/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.imaging.common;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;

import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;

public class BinaryFileFunctions implements BinaryConstants
{
    protected boolean debug = false;

    public final void setDebug(boolean b)
    {
        debug = b;
    }

    public final boolean getDebug()
    {
        return debug;
    }

    protected final void readRandomBytes(InputStream is)
            throws IOException
    {

        for (int counter = 0; counter < 100; counter++)
        {
            readByte("" + counter, is, "Random Data");
        }
    }

    public final void debugNumber(String msg, int data)
    {
        debugNumber(msg, data, 1);
    }

    public final void debugNumber(String msg, int data, int bytes)
    {
        PrintWriter pw = new PrintWriter(System.out);
        debugNumber(pw, msg,
                data, bytes);
        pw.flush();
    }


    public final void debugNumber(PrintWriter pw, String msg, int data)
    {
        debugNumber(pw, msg, data, 1);
    }

    public final void debugNumber(PrintWriter pw, String msg, int data,
            int bytes)
    {
        pw.print(msg + ": " + data + " (");
        int byteData = data;
        for (int i = 0; i < bytes; i++)
        {
            if (i > 0)
                pw.print(",");
            int singleByte = 0xff & byteData;
            pw.print((char) singleByte + " [" + singleByte + "]");
            byteData >>= 8;
        }
        pw.println(") [0x" + Integer.toHexString(data) + ", "
                + Integer.toBinaryString(data) + "]");
        pw.flush();
    }

    public final boolean startsWith(byte haystack[], byte needle[])
    {
        if (needle == null)
            return false;
        if (haystack == null)
            return false;
        if (needle.length > haystack.length)
            return false;

        for (int i = 0; i < needle.length; i++)
        {
            if (needle[i] != haystack[i])
                return false;
        }

        return true;
    }

    public final byte[] readBytes(InputStream is, int count)
            throws IOException
    {
        byte result[] = new byte[count];
        for (int i = 0; i < count; i++)
        {
            int data = is.read();
            result[i] = (byte) data;
        }
        return result;
    }
    
    public final void readAndVerifyBytes(InputStream is, byte expected[],
            String exception) throws ImageReadException, IOException
    {
        for (int i = 0; i < expected.length; i++)
        {
            int data = is.read();
            byte b = (byte) (0xff & data);

            if (data < 0)
                throw new ImageReadException("Unexpected EOF.");

            if (b != expected[i])
            {
                // System.out.println("i" + ": " + i);

                // this.debugByteArray("expected", expected);
                // debugNumber("data[" + i + "]", b);
                // debugNumber("expected[" + i + "]", expected[i]);

                throw new ImageReadException(exception);
            }
        }
    }

    public final void readAndVerifyBytes(InputStream is, BinaryConstant expected,
            String exception) throws ImageReadException, IOException
    {
        for (int i = 0; i < expected.size(); i++)
        {
            int data = is.read();
            byte b = (byte) (0xff & data);

            if (data < 0)
                throw new ImageReadException("Unexpected EOF.");

            if (b != expected.get(i))
                throw new ImageReadException(exception);
        }
    }

    protected final void readAndVerifyBytes(String name, InputStream is,
            byte expected[], String exception) throws ImageReadException,
            IOException
    {
        byte bytes[] = readByteArray(name, expected.length, is, exception);

        for (int i = 0; i < expected.length; i++)
        {
            if (bytes[i] != expected[i])
            {
                // System.out.println("i" + ": " + i);
                // debugNumber("bytes[" + i + "]", bytes[i]);
                // debugNumber("expected[" + i + "]", expected[i]);

                throw new ImageReadException(exception);
            }
        }
    }

    public final void skipBytes(InputStream is, int length, String exception)
            throws IOException
    {
        long total = 0;
        while (length != total)
        {
            long skipped = is.skip(length - total);
            if (skipped < 1)
                throw new IOException(exception + " (" + skipped + ")");
            total += skipped;
        }
    }

    protected final void scanForByte(InputStream is, byte value)
            throws IOException
    {
        int count = 0;
        for (int i = 0; count < 3; i++)
        // while(count<3)
        {
            int b = is.read();
            if (b < 0)
                return;
            if ((0xff & b) == value)
            {
                System.out.println("\t" + i + ": match.");
                count++;
            }
        }
    }

    public final byte readByte(String name, InputStream is, String exception)
            throws IOException
    {
        int result = is.read();

        if ((result < 0))
        {
            System.out.println(name + ": " + result);
            throw new IOException(exception);
        }

        if (debug)
            debugNumber(name, result);

        return (byte) (0xff & result);
    }

    protected final RationalNumber[] convertByteArrayToRationalArray(
            String name, byte bytes[], int start, int length, int byteOrder)
    {
        int expectedLength = start + length * 8;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        RationalNumber result[] = new RationalNumber[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToRational(name, bytes, start + i * 8,
                    byteOrder);
        }

        return result;
    }

    protected final RationalNumber convertByteArrayToRational(String name,
            byte bytes[], int byteOrder)
    {
        return convertByteArrayToRational(name, bytes, 0, byteOrder);
    }

    protected final RationalNumber convertByteArrayToRational(String name,
            byte bytes[], int start, int byteOrder)
    {
        int numerator = convertByteArrayToInt(name, bytes, start + 0, byteOrder);
        int divisor = convertByteArrayToInt(name, bytes, start + 4, byteOrder);

        return new RationalNumber(numerator, divisor);
    }

    protected final int convertByteArrayToInt(String name, byte bytes[],
            int byteOrder)
    {
        return convertByteArrayToInt(name, bytes, 0, byteOrder);
    }

    protected final int convertByteArrayToInt(String name, byte bytes[],
            int start, int byteOrder)
    {
        byte byte0 = bytes[start + 0];
        byte byte1 = bytes[start + 1];
        byte byte2 = bytes[start + 2];
        byte byte3 = bytes[start + 3];

        int result;

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
        {
            result = ((0xff & byte0) << 24) | ((0xff & byte1) << 16)
                    | ((0xff & byte2) << 8) | ((0xff & byte3) << 0);
        } else
        {
            // intel, little endian
            result = ((0xff & byte3) << 24) | ((0xff & byte2) << 16)
                    | ((0xff & byte1) << 8) | ((0xff & byte0) << 0);
        }

        if (debug)
            debugNumber(name, result, 4);

        return result;
    }

    protected final int[] convertByteArrayToIntArray(String name, byte bytes[],
            int start, int length, int byteOrder)
    {
        int expectedLength = start + length * 4;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        int result[] = new int[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToInt(name, bytes, start + i * 4,
                    byteOrder);
        }

        return result;
    }

    protected final void writeIntInToByteArray(int value, byte bytes[],
            int start, int byteOrder)
    {
        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
        {
            bytes[start + 0] = (byte) (value >> 24);
            bytes[start + 1] = (byte) (value >> 16);
            bytes[start + 2] = (byte) (value >> 8);
            bytes[start + 3] = (byte) (value >> 0);
        } else
        {
            bytes[start + 3] = (byte) (value >> 24);
            bytes[start + 2] = (byte) (value >> 16);
            bytes[start + 1] = (byte) (value >> 8);
            bytes[start + 0] = (byte) (value >> 0);
        }
    }

    protected static final byte[] int2ToByteArray(int value, int byteOrder)
    {
        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            return new byte[] { (byte) (value >> 8), (byte) (value >> 0), };
        else
            return new byte[] { (byte) (value >> 0), (byte) (value >> 8), };
    }

    protected final byte[] convertIntArrayToByteArray(int values[],
            int byteOrder)
    {
        byte result[] = new byte[values.length * 4];

        for (int i = 0; i < values.length; i++)
        {
            writeIntInToByteArray(values[i], result, i * 4, byteOrder);
        }

        return result;
    }

    protected final byte[] convertShortArrayToByteArray(int values[],
            int byteOrder)
    {
        byte result[] = new byte[values.length * 2];

        for (int i = 0; i < values.length; i++)
        {
            int value = values[i];

            if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            {
                result[i * 2 + 0] = (byte) (value >> 8);
                result[i * 2 + 1] = (byte) (value >> 0);
            } else
            {
                result[i * 2 + 1] = (byte) (value >> 8);
                result[i * 2 + 0] = (byte) (value >> 0);
            }
        }

        return result;
    }

    protected final byte[] convertShortToByteArray(int value, int byteOrder)
    {
        byte result[] = new byte[2];

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
        {
            result[0] = (byte) (value >> 8);
            result[1] = (byte) (value >> 0);
        } else
        {
            result[1] = (byte) (value >> 8);
            result[0] = (byte) (value >> 0);
        }

        return result;
    }

    protected final byte[] convertIntArrayToRationalArray(int numerators[],
            int denominators[], int byteOrder) throws ImageWriteException
    {
        if (numerators.length != denominators.length)
            throw new ImageWriteException("numerators.length ("
                    + numerators.length + " != denominators.length ("
                    + denominators.length + ")");

        byte result[] = new byte[numerators.length * 8];

        for (int i = 0; i < numerators.length; i++)
        {
            writeIntInToByteArray(numerators[i], result, i * 8, byteOrder);
            writeIntInToByteArray(denominators[i], result, i * 8 + 4, byteOrder);
        }

        return result;
    }

    protected final byte[] convertRationalArrayToByteArray(
            RationalNumber numbers[], int byteOrder)
    {
        // Debug.debug("convertRationalArrayToByteArray 2");
        byte result[] = new byte[numbers.length * 8];

        for (int i = 0; i < numbers.length; i++)
        {
            writeIntInToByteArray(numbers[i].numerator, result, i * 8,
                    byteOrder);
            writeIntInToByteArray(numbers[i].divisor, result, i * 8 + 4,
                    byteOrder);
        }

        return result;
    }

    protected final byte[] convertRationalToByteArray(RationalNumber number,
            int byteOrder)
    {
        byte result[] = new byte[8];

        writeIntInToByteArray(number.numerator, result, 0, byteOrder);
        writeIntInToByteArray(number.divisor, result, 4, byteOrder);

        return result;
    }

    protected final int convertByteArrayToShort(String name, byte bytes[],
            int byteOrder) throws ImageReadException
    {
        return convertByteArrayToShort(name, 0, bytes, byteOrder);
    }

    protected final int convertByteArrayToShort(String name, int index,
            byte bytes[], int byteOrder) throws ImageReadException
    {
        if (index + 1 >= bytes.length)
            throw new ImageReadException("Index out of bounds. Array size: "
                    + bytes.length + ", index: " + index);

        int byte0 = 0xff & bytes[index + 0];
        int byte1 = 0xff & bytes[index + 1];

        int result;

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            result = (byte0 << 8) | byte1;
        else
            // intel, little endian
            result = (byte1 << 8) | byte0;

        if (debug)
            debugNumber(name, result, 2);

        return result;
    }

    protected final int[] convertByteArrayToShortArray(String name,
            byte bytes[], int start, int length, int byteOrder)
            throws ImageReadException

    {
        int expectedLength = start + length * 2;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        int result[] = new int[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToShort(name, start + i * 2, bytes,
                    byteOrder);
        }

        return result;
    }

    public final byte[] readByteArray(String name, int length, InputStream is)
            throws IOException
    {
        String exception = name + " could not be read.";
        return readByteArray(name, length, is, exception);
    }

    public final byte[] readByteArray(String name, int length, InputStream is,
            String exception) throws IOException
    {
        byte result[] = new byte[length];

        int read = 0;
        while (read < length)
        {
            int count = is.read(result, read, length - read);
            // Debug.debug("count", count);
            if (count < 1)
                throw new IOException(exception+" count: "+ count + " read: "+read+" length: "+length);

            read += count;
        }

        if (debug)
        {
            for (int i = 0; ((i < length) && (i < 50)); i++)
            {
                debugNumber(name + " (" + i + ")", 0xff & result[i]);
            }
        }
        return result;
    }

    public final void debugByteArray(String name, byte bytes[])
    {
        System.out.println(name + ": " + bytes.length);

        for (int i = 0; ((i < bytes.length) && (i < 50)); i++)
        {
            debugNumber("\t" + " (" + i + ")", 0xff & bytes[i]);
        }
    }

    protected final void debugNumberArray(String name, int numbers[], int length)
    {
        System.out.println(name + ": " + numbers.length);

        for (int i = 0; ((i < numbers.length) && (i < 50)); i++)
        {
            debugNumber(name + " (" + i + ")", numbers[i], length);
        }
    }

    public final byte[] readBytearray(String name, byte bytes[], int start,
            int count) throws ImageReadException
    {
        if (bytes.length < (start + count))
        {
            throw new ImageReadException("Invalid read. bytes.length: " + bytes.length+ ", start: " + start + ", count: " + count);
            // return null;
        }

        byte result[] = new byte[count];
        System.arraycopy(bytes, start, result, 0, count);

        if (debug)
            debugByteArray(name, result);

        return result;
    }

    protected final byte[] getByteArrayTail(String name, byte bytes[], int count) throws ImageReadException
    {
        return readBytearray(name, bytes, count, bytes.length - count);
    }

    protected final byte[] getBytearrayHead(String name, byte bytes[], int count) throws ImageReadException
    {
        return readBytearray(name, bytes, 0, bytes.length - count);
    }

    public static final byte[] slice(byte bytes[], int start, int count)
    {
        if (bytes.length < (start + count))
            return null;

        byte result[] = new byte[count];
        System.arraycopy(bytes, start, result, 0, count);

        return result;
    }

    public static final byte[] tail(byte bytes[], int count)
    {
        if (count > bytes.length)
            count = bytes.length;
        return slice(bytes, bytes.length - count, count);
    }

    public static final byte[] head(byte bytes[], int count)
    {
        if (count > bytes.length)
            count = bytes.length;
        return slice(bytes, 0, count);
    }

    public final boolean compareByteArrays(byte a[], byte b[])
    {
        if (a.length != b.length)
            return false;

        return compareByteArrays(a, 0, b, 0, a.length);
    }

    public final boolean compareByteArrays(byte a[], int aStart, byte b[],
            int bStart, int length)
    {
        if (a.length < (aStart + length))
        {
            return false;
        }
        if (b.length < (bStart + length))
            return false;

        for (int i = 0; i < length; i++)
        {
            if (a[aStart + i] != b[bStart + i])
            {
                // debugNumber("\t" + "a[" + (aStart + i) + "]", a[aStart + i]);
                // debugNumber("\t" + "b[" + (bStart + i) + "]", b[bStart + i]);

                return false;
            }
        }

        return true;
    }

    public static final boolean compareBytes(byte a[], byte b[])
    {
        if (a.length != b.length)
            return false;

        return compareBytes(a, 0, b, 0, a.length);
    }

    public static final boolean compareBytes(byte a[], int aStart, byte b[],
            int bStart, int length)
    {
        if (a.length < (aStart + length))
            return false;
        if (b.length < (bStart + length))
            return false;

        for (int i = 0; i < length; i++)
        {
            if (a[aStart + i] != b[bStart + i])
                return false;
        }

        return true;
    }

    protected final int read4Bytes(String name, InputStream is,
            String exception, int byteOrder) throws IOException
    {
        int size = 4;
        byte bytes[] = new byte[size];

        int read = 0;
        while (read < size)
        {
            int count = is.read(bytes, read, size - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        return convertByteArrayToInt(name, bytes, byteOrder);
    }

    protected final int read3Bytes(String name, InputStream is,
            String exception, int byteOrder) throws IOException
    {
        byte byte0 = (byte) is.read();
        byte byte1 = (byte) is.read();
        byte byte2 = (byte) is.read();

        int result;

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
            result = ((0xff & byte0) << 16) | ((0xff & byte1) << 8)
                    | ((0xff & byte2) << 0);
        else
            // intel, little endian
            result = ((0xff & byte2) << 16) | ((0xff & byte1) << 8)
                    | ((0xff & byte0) << 0);

        if (debug)
            debugNumber(name, result, 3);

        return result;
        //
        //
        // int size = 3;
        // byte bytes[] = new byte[size];
        //
        // int read = 0;
        // while (read < size)
        // {
        // int count = is.read(bytes, read, size - read);
        // if (count < 1)
        // throw new IOException(exception);
        //
        // read += count;
        // }
        //
        // return convertByteArrayToInt(name, bytes, 0, 3, byteOrder);
    }

    protected final int read2Bytes(String name, InputStream is,
            String exception, int byteOrder) throws ImageReadException,
            IOException
    {
        int size = 2;
        byte bytes[] = new byte[size];

        int read = 0;
        while (read < size)
        {
            int count = is.read(bytes, read, size - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        return convertByteArrayToShort(name, bytes, byteOrder);
    }

    protected final void printCharQuad(String msg, int i)
    {
        System.out.println(msg + ": '" + (char) (0xff & (i >> 24))
                + (char) (0xff & (i >> 16)) + (char) (0xff & (i >> 8))
                + (char) (0xff & (i >> 0)) + "'");

    }

    protected final void printCharQuad(PrintWriter pw, String msg, int i)
    {
        pw.println(msg + ": '" + (char) (0xff & (i >> 24))
                + (char) (0xff & (i >> 16)) + (char) (0xff & (i >> 8))
                + (char) (0xff & (i >> 0)) + "'");

    }

    protected final void printByteBits(String msg, byte i)
    {
        System.out.println(msg + ": '" + Integer.toBinaryString(0xff & i));
    }

    public final static int charsToQuad(char c1, char c2, char c3, char c4)
    {
        return (((0xff & c1) << 24) | ((0xff & c2) << 16) | ((0xff & c3) << 8) | ((0xff & c4) << 0));
    }

    public final int findNull(byte src[])
    {
        return findNull(src, 0);
    }

    public final int findNull(byte src[], int start)
    {
        for (int i = start; i < src.length; i++)
        {
            if (src[i] == 0)
                return i;

        }
        return -1;
    }

    protected final byte[] getRAFBytes(RandomAccessFile raf, long pos,
            int length, String exception) throws IOException
    {
        if (debug)
        {
            System.out.println("getRAFBytes pos" + ": " + pos);
            System.out.println("getRAFBytes length" + ": " + length);
        }

        byte result[] = new byte[length];

        raf.seek(pos);

        int read = 0;
        while (read < length)
        {
            int count = raf.read(result, read, length - read);
            if (count < 1)
                throw new IOException(exception);

            read += count;
        }

        return result;

    }

    protected final float convertByteArrayToFloat(String name, byte bytes[],
            int byteOrder)
    {
        return convertByteArrayToFloat(name, bytes, 0, byteOrder);
    }

    protected final float convertByteArrayToFloat(String name, byte bytes[],
            int start, int byteOrder)
    {
        // TODO: not tested; probably wrong.

        byte byte0 = bytes[start + 0];
        byte byte1 = bytes[start + 1];
        byte byte2 = bytes[start + 2];
        byte byte3 = bytes[start + 3];

        int bits;

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
        {
            bits = ((0xff & byte0) << 24) | ((0xff & byte1) << 16)
                    | ((0xff & byte2) << 8) | ((0xff & byte3) << 0);
        } else
        {
            // intel, little endian
            bits = ((0xff & byte3) << 24) | ((0xff & byte2) << 16)
                    | ((0xff & byte1) << 8) | ((0xff & byte0) << 0);
        }

        float result = Float.intBitsToFloat(bits);

        // if (debug)
        // debugNumber(name, result, 4);

        return result;
    }

    protected final float[] convertByteArrayToFloatArray(String name,
            byte bytes[], int start, int length, int byteOrder)
    {
        int expectedLength = start + length * 4;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        float result[] = new float[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToFloat(name, bytes, start + i * 4,
                    byteOrder);
        }

        return result;
    }

    protected final byte[] convertFloatToByteArray(float value, int byteOrder)
    {
        byte result[] = new byte[4];

        int bits = Float.floatToRawIntBits(value);

        if (byteOrder == BYTE_ORDER_INTEL) // intel, big endian
        {
            result[0] = (byte) (0xff & (bits >> 0));
            result[1] = (byte) (0xff & (bits >> 8));
            result[2] = (byte) (0xff & (bits >> 16));
            result[3] = (byte) (0xff & (bits >> 24));
        } else
        {
            result[3] = (byte) (0xff & (bits >> 0));
            result[2] = (byte) (0xff & (bits >> 8));
            result[1] = (byte) (0xff & (bits >> 16));
            result[0] = (byte) (0xff & (bits >> 24));
        }

        return result;
    }

    protected final byte[] convertFloatArrayToByteArray(float values[],
            int byteOrder)
    {
        byte result[] = new byte[values.length * 4];
        for (int i = 0; i < values.length; i++)
        {
            float value = values[i];
            int bits = Float.floatToRawIntBits(value);

            int start = i * 4;
            if (byteOrder == BYTE_ORDER_INTEL) // intel, little endian
            {
                result[start + 0] = (byte) (0xff & (bits >> 0));
                result[start + 1] = (byte) (0xff & (bits >> 8));
                result[start + 2] = (byte) (0xff & (bits >> 16));
                result[start + 3] = (byte) (0xff & (bits >> 24));
            } else
            {
                result[start + 3] = (byte) (0xff & (bits >> 0));
                result[start + 2] = (byte) (0xff & (bits >> 8));
                result[start + 1] = (byte) (0xff & (bits >> 16));
                result[start + 0] = (byte) (0xff & (bits >> 24));
            }
        }
        return result;
    }

    protected final byte[] convertDoubleToByteArray(double value, int byteOrder)
    {
        byte result[] = new byte[8];

        long bits = Double.doubleToRawLongBits(value);

        if (byteOrder == BYTE_ORDER_INTEL) // intel, little endian
        {
            result[0] = (byte) (0xff & (bits >> 0));
            result[1] = (byte) (0xff & (bits >> 8));
            result[2] = (byte) (0xff & (bits >> 16));
            result[3] = (byte) (0xff & (bits >> 24));
            result[4] = (byte) (0xff & (bits >> 32));
            result[5] = (byte) (0xff & (bits >> 40));
            result[6] = (byte) (0xff & (bits >> 48));
            result[7] = (byte) (0xff & (bits >> 56));
        } else
        {
            result[7] = (byte) (0xff & (bits >> 0));
            result[6] = (byte) (0xff & (bits >> 8));
            result[5] = (byte) (0xff & (bits >> 16));
            result[4] = (byte) (0xff & (bits >> 24));
            result[3] = (byte) (0xff & (bits >> 32));
            result[2] = (byte) (0xff & (bits >> 40));
            result[1] = (byte) (0xff & (bits >> 48));
            result[0] = (byte) (0xff & (bits >> 56));
        }

        return result;
    }

    protected final byte[] convertDoubleArrayToByteArray(double values[],
            int byteOrder)
    {
        byte result[] = new byte[values.length * 8];
        for (int i = 0; i < values.length; i++)
        {
            double value = values[i];
            long bits = Double.doubleToRawLongBits(value);

            int start = i * 8;
            if (byteOrder == BYTE_ORDER_INTEL) // intel, little endian
            {
                result[start + 0] = (byte) (0xff & (bits >> 0));
                result[start + 1] = (byte) (0xff & (bits >> 8));
                result[start + 2] = (byte) (0xff & (bits >> 16));
                result[start + 3] = (byte) (0xff & (bits >> 24));
                result[start + 4] = (byte) (0xff & (bits >> 32));
                result[start + 5] = (byte) (0xff & (bits >> 40));
                result[start + 6] = (byte) (0xff & (bits >> 48));
                result[start + 7] = (byte) (0xff & (bits >> 56));
            } else
            {
                result[start + 7] = (byte) (0xff & (bits >> 0));
                result[start + 6] = (byte) (0xff & (bits >> 8));
                result[start + 5] = (byte) (0xff & (bits >> 16));
                result[start + 4] = (byte) (0xff & (bits >> 24));
                result[start + 3] = (byte) (0xff & (bits >> 32));
                result[start + 2] = (byte) (0xff & (bits >> 40));
                result[start + 1] = (byte) (0xff & (bits >> 48));
                result[start + 0] = (byte) (0xff & (bits >> 56));
            }
        }
        return result;
    }

    protected final double convertByteArrayToDouble(String name, byte bytes[],
            int byteOrder)
    {
        return convertByteArrayToDouble(name, bytes, 0, byteOrder);
    }

    protected final double convertByteArrayToDouble(String name, byte bytes[],
            int start, int byteOrder)
    {
        byte byte0 = bytes[start + 0];
        byte byte1 = bytes[start + 1];
        byte byte2 = bytes[start + 2];
        byte byte3 = bytes[start + 3];
        byte byte4 = bytes[start + 4];
        byte byte5 = bytes[start + 5];
        byte byte6 = bytes[start + 6];
        byte byte7 = bytes[start + 7];

        long bits;

        if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
        {
            bits = ((0xffL & byte0) << 56) | ((0xffL & byte1) << 48)
                    | ((0xffL & byte2) << 40) | ((0xffL & byte3) << 32)
                    | ((0xffL & byte4) << 24) | ((0xffL & byte5) << 16)
                    | ((0xffL & byte6) << 8) | ((0xffL & byte7) << 0);

        } else
        {
            // intel, little endian
            bits = ((0xffL & byte7) << 56) | ((0xffL & byte6) << 48)
                    | ((0xffL & byte5) << 40) | ((0xffL & byte4) << 32)
                    | ((0xffL & byte3) << 24) | ((0xffL & byte2) << 16)
                    | ((0xffL & byte1) << 8) | ((0xffL & byte0) << 0);
        }

        double result = Double.longBitsToDouble(bits);

        // if (debug)
        // debugNumber(name, result, 4);

        return result;

        // byte array[];
        // if (byteOrder == BYTE_ORDER_MOTOROLA) // motorola, big endian
        // // ?? dunno byte order very likely wrong here.
        // array = new byte[]{
        // bytes[start + 0], bytes[start + 1], bytes[start + 2],
        // bytes[start + 3], bytes[start + 4], bytes[start + 5],
        // bytes[start + 6], bytes[start + 7],
        //
        // };
        // else
        // // ?? dunno byte order very likely wrong here.
        // array = new byte[]{
        // bytes[start + 3], bytes[start + 2], bytes[start + 1],
        // bytes[start + 0], bytes[start + 7], bytes[start + 6],
        // bytes[start + 5], bytes[start + 4],
        // };
        //
        // double result = Double.NaN;
        //
        // try
        // {
        // ByteArrayInputStream bais = new ByteArrayInputStream(array);
        // if (start > 0)
        // {
        // skipBytes(bais, start);
        // // bais.skip(start);
        // }
        // DataInputStream dis = new DataInputStream(bais);
        // result = dis.readDouble();
        //
        // dis.close();
        // }
        // catch (Exception e)
        // {
        // Debug.debug(e);
        // }
        //
        // return result;
    }

    protected final double[] convertByteArrayToDoubleArray(String name,
            byte bytes[], int start, int length, int byteOrder)
    {
        int expectedLength = start + length * 8;

        if (bytes.length < expectedLength)
        {
            System.out.println(name + ": expected length: " + expectedLength
                    + ", actual length: " + bytes.length);
            return null;
        }

        double result[] = new double[length];

        for (int i = 0; i < length; i++)
        {
            result[i] = convertByteArrayToDouble(name, bytes, start + i * 8,
                    byteOrder);
        }

        return result;
    }

    protected void skipBytes(InputStream is, int length) throws IOException
    {
        this.skipBytes(is, length, "Couldn't skip bytes");
    }

    public final void copyStreamToStream(InputStream is, OutputStream os)
            throws IOException
    {
        byte buffer[] = new byte[1024];
        int read;
        while ((read = is.read(buffer)) > 0)
        {
            os.write(buffer, 0, read);
        }
    }

    public final byte[] getStreamBytes(InputStream is) throws IOException
    {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        copyStreamToStream(is, os);
        return os.toByteArray();
    }
}