Java ByteOrder reduceToSmallestByteArray(byte[] originalBytes, ByteOrder byteOrder, boolean isSigned)

Here you can find the source of reduceToSmallestByteArray(byte[] originalBytes, ByteOrder byteOrder, boolean isSigned)

Description

Reduces the number of bytes to represent the provided number without changing its value.

License

Apache License

Parameter

Parameter Description
originalBytes a parameter
byteOrder a parameter
isSigned a parameter

Return

a byte array which uses the least number of bytes to store the value.

Declaration

private static byte[] reduceToSmallestByteArray(byte[] originalBytes, ByteOrder byteOrder, boolean isSigned) 

Method Source Code

//package com.java2s;
//License from project: Apache License 

import java.nio.ByteOrder;

public class Main {
    public final static int BITS_PER_BYTE = 8;

    /**/*www  .j  a v  a 2 s  .c  o m*/
     * Reduces the number of bytes to represent the provided number without changing its value.
     * 
     * @param originalBytes
     * @param byteOrder
     * @param isSigned
     * @return a byte array which uses the least number of bytes to store the value.
     */
    private static byte[] reduceToSmallestByteArray(byte[] originalBytes, ByteOrder byteOrder, boolean isSigned) {

        byte[] smallestBytes = null;

        byte emptyByte = (byte) 0;// 00000000
        if (isNegative(originalBytes, byteOrder, isSigned)) {
            emptyByte = (byte) -1;// 11111111
        }

        if (byteOrder == ByteOrder.BIG_ENDIAN) {
            int byteIndexOfFirstValuedByte = 0;
            byteLoop: for (int i = 0; i < originalBytes.length; i++) {
                if (originalBytes[i] != emptyByte) {
                    byteIndexOfFirstValuedByte = i;
                    break byteLoop;
                }
            }

            if (byteIndexOfFirstValuedByte > 0) {
                int newByteSize = originalBytes.length - byteIndexOfFirstValuedByte;
                smallestBytes = new byte[newByteSize];
                for (int i = 0; i < newByteSize; i++) {
                    int originalIndex = i + byteIndexOfFirstValuedByte;
                    smallestBytes[i] = originalBytes[originalIndex];
                }
            } else {
                smallestBytes = new byte[] { originalBytes[0] };
            }
        } else if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
            int byteIndexOfFirstValuedByte = 0;
            byteLoop: for (int i = originalBytes.length - 1; i >= 0; i--) {
                if (originalBytes[i] != emptyByte) {
                    byteIndexOfFirstValuedByte = i;
                    break byteLoop;
                }
            }

            if (byteIndexOfFirstValuedByte < originalBytes.length) {
                int newByteSize = byteIndexOfFirstValuedByte + 1;
                smallestBytes = new byte[newByteSize];
                for (int i = 0; i < newByteSize; i++) {
                    smallestBytes[i] = originalBytes[i];
                }
            } else {
                smallestBytes = new byte[] { originalBytes[0] };
            }
        } else {
            throw new IllegalStateException("Unrecognized ByteOrder value[" + byteOrder + "].");
        }

        return smallestBytes;
    }

    /**
     * Detect whether this a negative value.
     * 
     * @param bytes
     * @param byteOrder
     * @param isSigned
     * @return true if the provided details indicate a negative valued number
     */
    private static boolean isNegative(byte[] bytes, ByteOrder byteOrder, boolean isSigned) {
        boolean isNegative = false;

        if (isSigned) {
            byte mostSignificantByte = getMostSignificantByte(bytes, byteOrder);
            isNegative = isBitOn(mostSignificantByte, BITS_PER_BYTE - 1);
        }

        return isNegative;
    }

    /**
     * Return the most significant byte in the provided byte array based on endianess.
     * 
     * @param bytes
     * @param byteOrder
     * @return the most significant byte based on endianess.
     */
    private static byte getMostSignificantByte(byte[] bytes, ByteOrder byteOrder) {
        byte mostSignificantByte = bytes[0];
        if (byteOrder == ByteOrder.BIG_ENDIAN) {
            // do nothing
            // mostSignificantByte = bytes[0];
        } else if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
            mostSignificantByte = bytes[bytes.length - 1];
        } else {
            throw new IllegalStateException("Unrecognized ByteOrder value[" + byteOrder + "].");
        }
        return mostSignificantByte;
    }

    /**
     * Return true is the bit found at the bitIndex position is on (meaning it has a value of 1).
     * 
     * @param aByte
     * @param bitIndex
     * @return true if the bitIndex position is occupied by a 1.
     */
    public static boolean isBitOn(byte aByte, int bitIndex) {
        boolean isBitOn = getBitValue(aByte, bitIndex) == 1;
        return isBitOn;
    }

    /**
     * Return the bit value(0 or 1) for the bit found at the bitIndex position in the provided byte.
     * 
     * @param aByte
     * @param bitIndex
     * @return 0 or 1 based on the bit value at the bitIndex position in the provided byte.
     */
    private static int getBitValue(byte aByte, int bitIndex) {
        if (bitIndex >= BITS_PER_BYTE) {
            throw new ArrayIndexOutOfBoundsException("The provided bitIndex[" + bitIndex
                    + "] is larger than the size of a byte[" + BITS_PER_BYTE + "].");
        }

        if (bitIndex < 0) {
            throw new ArrayIndexOutOfBoundsException(
                    "The provided bitIndex[" + bitIndex + "] must be greater than or equal to zero.");
        }

        int value = (aByte >> bitIndex) & 1;
        return value;
    }
}

Related

  1. getUnsignedShort(final int offset, final byte[] buffer, final ByteOrder byteOrder)
  2. increaseNumberOfBytes(byte[] originalBytes, int desiredNumberOfBytes, ByteOrder byteOrder, boolean isSigned)
  3. isNegative(byte[] bytes, ByteOrder byteOrder, boolean isSigned)
  4. longToBytes(long longValue, ByteOrder byteOrder, boolean isSigned)
  5. opposite(ByteOrder order)
  6. setLong(byte[] bytes, int start, int end, long value, ByteOrder byteOrder)
  7. toBytes(int value, ByteOrder order)
  8. toDoubleByteArray(double val, ByteOrder outOrder, byte[] buf, int off)
  9. toFloatByteArray(float val, ByteOrder outOrder, byte[] buf, int off)