/*
 *  ====================================================================
 *  The Apache Software License, Version 1.1
 *
 *  Copyright (c) 2003 The Apache Software Foundation.  All rights
 *  reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in
 *  the documentation and/or other materials provided with the
 *  distribution.
 *
 *  3. The end-user documentation included with the redistribution,
 *  if any, must include the following acknowledgment:
 *  "This product includes software developed by the
 *  Apache Software Foundation (http://www.apache.org/)."
 *  Alternately, this acknowledgment may appear in the software itself,
 *  if and wherever such third-party acknowledgments normally appear.
 *
 *  4. The names "Apache" and "Apache Software Foundation" and
 *  "Apache POI" must not be used to endorse or promote products
 *  derived from this software without prior written permission. For
 *  written permission, please contact apache@apache.org.
 *
 *  5. Products derived from this software may not be called "Apache",
 *  "Apache POI", nor may "Apache" appear in their name, without
 *  prior written permission of the Apache Software Foundation.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *  SUCH DAMAGE.
 *  ====================================================================
 *
 *  This software consists of voluntary contributions made by many
 *  individuals on behalf of the Apache Software Foundation.  For more
 *  information on the Apache Software Foundation, please see
 *  <http://www.apache.org/>.
 */
package org.apache.poi.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 *  a utility class for handling little-endian numbers, which the 80x86 world is
 *  replete with. The methods are all static, and input/output is from/to byte
 *  arrays, or from InputStreams.
 *
 *@author     Marc Johnson (mjohnson at apache dot org)
 *@author     Andrew Oliver (acoliver at apache dot org)
 */

public class LittleEndian
         implements LittleEndianConsts {

    // all methods are static, so an accessible constructor makes no
    // sense
    /**
     *  Constructor for the LittleEndian object
     */
    private LittleEndian() { }


    /**
     *  get a short value from a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@return         the short (16-bit) value
     */

    public static short getShort(final byte[] data, final int offset) {
        return (short) getNumber(data, offset, SHORT_SIZE);
    }


    /**
     *  get an unsigned short value from a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@return         the unsigned short (16-bit) value in an integer
     */
    public static int getUShort(final byte[] data, final int offset) {
        short num = (short) getNumber(data, offset, SHORT_SIZE);
        int retNum;
        if (num < 0) {
            retNum = ((int) Short.MAX_VALUE + 1) * 2 + (int) num;
        } else {
            retNum = (int) num;
        }
        return retNum;
    }


    /**
     *  get a short array from a byte array.
     *
     *@param  data    Description of the Parameter
     *@param  offset  Description of the Parameter
     *@param  size    Description of the Parameter
     *@return         The simpleShortArray value
     */
    public static short[] getSimpleShortArray(final byte[] data, final int offset, final int size) {
        short[] results = new short[size];
        for (int i = 0; i < size; i++) {
            results[i] = getShort(data, offset + 2 + (i * 2));
        }
        return results;
    }


    /**
     *  get a short array from a byte array. The short array is assumed to start
     *  with a word describing the length of the array.
     *
     *@param  data    Description of the Parameter
     *@param  offset  Description of the Parameter
     *@return         The shortArray value
     */
    public static short[] getShortArray(final byte[] data, final int offset) {
        int size = (short) getNumber(data, offset, SHORT_SIZE);
        short[] results = getSimpleShortArray(data, offset, size);
        return results;
    }


    /**
     *  get a short value from the beginning of a byte array
     *
     *@param  data  the byte array
     *@return       the short (16-bit) value
     */

    public static short getShort(final byte[] data) {
        return getShort(data, 0);
    }


    /**
     *  get an unsigned short value from the beginning of a byte array
     *
     *@param  data  the byte array
     *@return       the unsigned short (16-bit) value in an int
     */
    public static int getUShort(final byte[] data) {
        return getUShort(data, 0);
    }


    /**
     *  get an int value from a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@return         the int (32-bit) value
     */

    public static int getInt(final byte[] data, final int offset) {
        return (int) getNumber(data, offset, INT_SIZE);
    }


    /**
     *  get an int value from the beginning of a byte array
     *
     *@param  data  the byte array
     *@return       the int (32-bit) value
     */

    public static int getInt(final byte[] data) {
        return getInt(data, 0);
    }


    /**
     *  get an unsigned int value from a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@return         the unsigned int (32-bit) value in a long
     */
    public static long getUInt(final byte[] data, final int offset) {
        int num = (int) getNumber(data, offset, INT_SIZE);
        long retNum;
        if (num < 0) {
            retNum = ((long) Integer.MAX_VALUE + 1) * 2 + (long) num;
        } else {
            retNum = (int) num;
        }
        return retNum;
    }

    /**
     *  get an unsigned int value from a byte array
     *
     *@param  data    the byte array
     *@return         the unsigned int (32-bit) value in a long
     */
    public static long getUInt(final byte[] data) {
	return getUInt(data,0);
    }

    /**
     *  get a long value from a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@return         the long (64-bit) value
     */

    public static long getLong(final byte[] data, final int offset) {
        return getNumber(data, offset, LONG_SIZE);
    }


    /**
     *  get a long value from the beginning of a byte array
     *
     *@param  data  the byte array
     *@return       the long (64-bit) value
     */

    public static long getLong(final byte[] data) {
        return getLong(data, 0);
    }


    /**
     *  get a double value from a byte array, reads it in little endian format
     *  then converts the resulting revolting IEEE 754 (curse them) floating
     *  point number to a happy java double
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@return         the double (64-bit) value
     */

    public static double getDouble(final byte[] data, final int offset) {
        return Double.longBitsToDouble(getNumber(data, offset, DOUBLE_SIZE));
    }


    /**
     *  get a double value from the beginning of a byte array
     *
     *@param  data  the byte array
     *@return       the double (64-bit) value
     */

    public static double getDouble(final byte[] data) {
        return getDouble(data, 0);
    }


    /**
     *  put a short value into a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@param  value   the short (16-bit) value
     */
    public static void putShort(final byte[] data, final int offset,
            final short value) {
        putNumber(data, offset, value, SHORT_SIZE);
    }


    /**
     *  put a array of shorts into a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@param  value   the short array
     */
    public static void putShortArray(final byte[] data, final int offset, final short[] value) {
        putNumber(data, offset, value.length, SHORT_SIZE);
        for (int i = 0; i < value.length; i++) {
            putNumber(data, offset + 2 + (i * 2), value[i], SHORT_SIZE);
        }
    }

    /**
     * put an unsigned short value into a byte array
     *
     * @param data the byte array
     * @param offset a starting offset into the byte array
     * @param value the short (16-bit) value
     *
     * @exception ArrayIndexOutOfBoundsException may be thrown
     */
    public static void putUShort(final byte[] data, final int offset,
                                final int value)
    {
        putNumber(data, offset, value, SHORT_SIZE);
    }

    /**
     *  put a short value into beginning of a byte array
     *
     *@param  data   the byte array
     *@param  value  the short (16-bit) value
     */

    public static void putShort(final byte[] data, final short value) {
        putShort(data, 0, value);
    }


    /**
     *  put an int value into a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@param  value   the int (32-bit) value
     */

    public static void putInt(final byte[] data, final int offset,
            final int value) {
        putNumber(data, offset, value, INT_SIZE);
    }


    /**
     *  put an int value into beginning of a byte array
     *
     *@param  data   the byte array
     *@param  value  the int (32-bit) value
     */

    public static void putInt(final byte[] data, final int value) {
        putInt(data, 0, value);
    }


    /**
     *  put a long value into a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@param  value   the long (64-bit) value
     */

    public static void putLong(final byte[] data, final int offset,
            final long value) {
        putNumber(data, offset, value, LONG_SIZE);
    }


    /**
     *  put a long value into beginning of a byte array
     *
     *@param  data   the byte array
     *@param  value  the long (64-bit) value
     */

    public static void putLong(final byte[] data, final long value) {
        putLong(data, 0, value);
    }


    /**
     *  put a double value into a byte array
     *
     *@param  data    the byte array
     *@param  offset  a starting offset into the byte array
     *@param  value   the double (64-bit) value
     */

    public static void putDouble(final byte[] data, final int offset,
            final double value) {
        // Excel likes NaN to be a specific value.
        if (Double.isNaN(value))
            putNumber(data, offset, -276939487313920L, DOUBLE_SIZE);
        else
            putNumber(data, offset, Double.doubleToLongBits(value), DOUBLE_SIZE);
    }


    /**
     *  put a double value into beginning of a byte array
     *
     *@param  data   the byte array
     *@param  value  the double (64-bit) value
     */

    public static void putDouble(final byte[] data, final double value) {
        putDouble(data, 0, value);
    }


    /**
     *  Exception to handle buffer underruns
     *
     *@author     Marc Johnson (mjohnson at apache dot org)
     */

    public static class BufferUnderrunException
             extends IOException {

        /**
         *  simple constructor
         */

        BufferUnderrunException() {
            super("buffer underrun");
        }
    }


    /**
     *  get a short value from an InputStream
     *
     *@param  stream                       the InputStream from which the short
     *      is to be read
     *@return                              the short (16-bit) value
     *@exception  IOException              will be propagated back to the caller
     *@exception  BufferUnderrunException  if the stream cannot provide enough
     *      bytes
     */

    public static short readShort(final InputStream stream)
             throws IOException, BufferUnderrunException {
        return getShort(readFromStream(stream, SHORT_SIZE));
    }


    /**
     *  get an int value from an InputStream
     *
     *@param  stream                       the InputStream from which the int is
     *      to be read
     *@return                              the int (32-bit) value
     *@exception  IOException              will be propagated back to the caller
     *@exception  BufferUnderrunException  if the stream cannot provide enough
     *      bytes
     */

    public static int readInt(final InputStream stream)
             throws IOException, BufferUnderrunException {
        return getInt(readFromStream(stream, INT_SIZE));
    }


    /**
     *  get a long value from an InputStream
     *
     *@param  stream                       the InputStream from which the long
     *      is to be read
     *@return                              the long (64-bit) value
     *@exception  IOException              will be propagated back to the caller
     *@exception  BufferUnderrunException  if the stream cannot provide enough
     *      bytes
     */

    public static long readLong(final InputStream stream)
             throws IOException, BufferUnderrunException {
        return getLong(readFromStream(stream, LONG_SIZE));
    }

    /**
     *  Read the appropriate number of bytes from the stream and return them to
     *  the caller. <p>
     *
     *  However, for the purposes of the POI project, this risk is deemed
     *  negligible. It is, however, so noted.
     *
     *@param  stream                       the InputStream we're reading from
     *@param  size                         the number of bytes to read; in
     *      99.99% of cases, this will be SHORT_SIZE, INT_SIZE, or LONG_SIZE --
     *      but it doesn't have to be.
     *@return                              the byte array containing the
     *      required number of bytes. The array will contain all zero's on end
     *      of stream
     *@exception  IOException              will be propagated back to the caller
     *@exception  BufferUnderrunException  if the stream cannot provide enough
     *      bytes
     */

    public static byte[] readFromStream(final InputStream stream,
            final int size)
             throws IOException, BufferUnderrunException {
        byte[] buffer = new byte[size];

        int count = stream.read(buffer);

        if (count == -1) {

            // return a zero-filled buffer
            Arrays.fill(buffer, (byte) 0);
        } else if (count != size) {
            throw new BufferUnderrunException();
        }
        return buffer;
    }


    /**
     *  Gets the number attribute of the LittleEndian class
     *
     *@param  data    Description of the Parameter
     *@param  offset  Description of the Parameter
     *@param  size    Description of the Parameter
     *@return         The number value
     */
    private static long getNumber(final byte[] data, final int offset,
            final int size) {
        long result = 0;

        for (int j = offset + size - 1; j >= offset; j--) {
            result <<= 8;
            result |= 0xff & data[j];
        }
        return result;
    }


    /**
     *  Description of the Method
     *
     *@param  data    Description of the Parameter
     *@param  offset  Description of the Parameter
     *@param  value   Description of the Parameter
     *@param  size    Description of the Parameter
     */
    private static void putNumber(final byte[] data, final int offset,
            final long value, final int size) {
        int limit = size + offset;
        long v = value;

        for (int j = offset; j < limit; j++) {
            data[j] = (byte) (v & 0xFF);
            v >>= 8;
        }
    }


    /**
     *  Convert an 'unsigned' byte to an integer. ie, don't carry across the
     *  sign.
     *
     *@param  b  Description of the Parameter
     *@return    Description of the Return Value
     */
    public static int ubyteToInt(byte b) {
        return ((b & 0x80) == 0 ? (int) b : (int) (b & (byte) 0x7f) + 0x80);
    }


    /**
     *  get the unsigned value of a byte.
     *
     *@param  data    the byte array.
     *@param  offset  a starting offset into the byte array.
     *@return         the unsigned value of the byte as a 32 bit integer
     */
    public static int getUnsignedByte(final byte[] data, final int offset) {
        return (int) getNumber(data, offset, BYTE_SIZE);
    }


    /**
     *  get the unsigned value of a byte.
     *
     *@param  data  the byte array
     *@return       the unsigned value of the byte as a 32 bit integer
     */
    public static int getUnsignedByte(final byte[] data) {
        return getUnsignedByte(data, 0);
    }


    /**
     *  Copy a portion of a byte array
     *
     *@param  data                        the original byte array
     *@param  offset                      Where to start copying from.
     *@param  size                        Number of bytes to copy.
     *@return                             The byteArray value
     *@throws  IndexOutOfBoundsException  - if copying would cause access of
     *      data outside array bounds.
     */
    public static byte[] getByteArray(final byte[] data, int offset, int size) {
        byte[] copy = new byte[size];
        System.arraycopy(data, offset, copy, 0, size);

        return copy;
    }


}
