/*
* Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see http://www.gnu.org/licenses/
*/
package com.bc.ceres.binio.util;
import java.nio.ByteOrder;
/**
* A utility class used to decode/encode primitive Java types from/to a byte buffer using
* a specified {@link ByteOrder}.
*/
public abstract class ByteArrayCodec {
public final static ByteArrayCodec LITTLE_ENDIAN = new LE();
public final static ByteArrayCodec BIG_ENDIAN = new BE();
public static ByteArrayCodec getInstance(ByteOrder byteOrder) {
if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
return LITTLE_ENDIAN;
} else {
return BIG_ENDIAN;
}
}
protected ByteArrayCodec() {
}
public abstract ByteOrder getByteOrder();
/////////////////////////////////////////////////////////////////////////
// Getter
public final byte getByte(byte[] b, int boff) {
return b[boff];
}
public abstract short getShort(byte[] b, int boff);
public abstract int getInt(byte[] b, int boff);
public abstract long getLong(byte[] b, int boff);
public abstract float getFloat(byte[] b, int boff);
public abstract double getDouble(byte[] b, int boff);
public final void getBytes(byte[] b, int boff, byte[] v, int voff, int vlen) {
System.arraycopy(b, boff, v, voff, vlen);
}
public abstract void getShorts(byte[] b, int boff, short[] v, int voff, int vlen);
public abstract void getInts(byte[] b, int boff, int[] v, int voff, int vlen);
public abstract void getLongs(byte[] b, int boff, long[] v, int voff, int vlen);
public abstract void getFloats(byte[] b, int boff, float[] v, int voff, int vlen);
public abstract void getDoubles(byte[] b, int boff, double[] v, int voff, int vlen);
/////////////////////////////////////////////////////////////////////////
// Setter
public final void setByte(byte[] b, int boff, byte v) {
b[boff] = v;
}
public abstract void setShort(byte[] b, int boff, short v);
public abstract void setInt(byte[] b, int boff, int v);
public abstract void setLong(byte[] b, int boff, long v);
public abstract void setFloat(byte[] b, int boff, float v);
public abstract void setDouble(byte[] b, int boff, double v);
public final void setBytes(byte[] b, int boff, byte[] v, int voff, int vlen) {
System.arraycopy(v, voff, b, boff, vlen);
}
public abstract void setShorts(byte[] b, int boff, short[] v, int voff, int vlen);
public abstract void setInts(byte[] b, int boff, int[] v, int voff, int vlen);
public abstract void setLongs(byte[] b, int boff, long[] v, int voff, int vlen);
public abstract void setFloats(byte[] b, int boff, float[] v, int voff, int vlen);
public abstract void setDoubles(byte[] b, int boff, double[] v, int voff, int vlen);
private static short decodeSLE(byte[] b, int boff) {
int b0 = b[boff + 1];
int b1 = b[boff + 0] & 0xff;
return (short) ((b0 << 8) | b1);
}
private static short decodeSBE(byte[] b, int boff) {
int b0 = b[boff + 0];
int b1 = b[boff + 1] & 0xff;
return (short) ((b0 << 8) | b1);
}
private static int decodeILE(byte[] b, int boff) {
int b0 = b[boff + 3];
int b1 = b[boff + 2] & 0xff;
int b2 = b[boff + 1] & 0xff;
int b3 = b[boff + 0] & 0xff;
return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
}
private static int decodeIBE(byte[] b, int boff) {
int b0 = b[boff + 0];
int b1 = b[boff + 1] & 0xff;
int b2 = b[boff + 2] & 0xff;
int b3 = b[boff + 3] & 0xff;
return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
}
private static long decodeLLE(byte[] b, int boff) {
int b0 = b[boff + 7];
int b1 = b[boff + 6] & 0xff;
int b2 = b[boff + 5] & 0xff;
int b3 = b[boff + 4] & 0xff;
int b4 = b[boff + 3];
int b5 = b[boff + 2] & 0xff;
int b6 = b[boff + 1] & 0xff;
int b7 = b[boff + 0] & 0xff;
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
return ((long) i0 << 32) | (i1 & 0xffffffffL);
}
private static long decodeLBE(byte[] b, int boff) {
int b0 = b[boff + 0];
int b1 = b[boff + 1] & 0xff;
int b2 = b[boff + 2] & 0xff;
int b3 = b[boff + 3] & 0xff;
int b4 = b[boff + 4];
int b5 = b[boff + 5] & 0xff;
int b6 = b[boff + 6] & 0xff;
int b7 = b[boff + 7] & 0xff;
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
return ((long) i0 << 32) | (i1 & 0xffffffffL);
}
private static float decodeFLE(byte[] b, int boff) {
int b0 = b[boff + 3];
int b1 = b[boff + 2] & 0xff;
int b2 = b[boff + 1] & 0xff;
int b3 = b[boff + 0] & 0xff;
int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
return Float.intBitsToFloat(i);
}
private static float decodeFBE(byte[] b, int boff) {
int b0 = b[boff + 0];
int b1 = b[boff + 1] & 0xff;
int b2 = b[boff + 2] & 0xff;
int b3 = b[boff + 3] & 0xff;
int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
return Float.intBitsToFloat(i);
}
private static double decodeDL(byte[] b, int boff) {
int b0 = b[boff + 7];
int b1 = b[boff + 6] & 0xff;
int b2 = b[boff + 5] & 0xff;
int b3 = b[boff + 4] & 0xff;
int b4 = b[boff + 3];
int b5 = b[boff + 2] & 0xff;
int b6 = b[boff + 1] & 0xff;
int b7 = b[boff + 0] & 0xff;
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
long l = ((long) i0 << 32) | (i1 & 0xffffffffL);
return Double.longBitsToDouble(l);
}
private static double decodeDBE(byte[] b, int boff) {
int b0 = b[boff + 0];
int b1 = b[boff + 1] & 0xff;
int b2 = b[boff + 2] & 0xff;
int b3 = b[boff + 3] & 0xff;
int b4 = b[boff + 4];
int b5 = b[boff + 5] & 0xff;
int b6 = b[boff + 6] & 0xff;
int b7 = b[boff + 7] & 0xff;
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
long l = ((long) i0 << 32) | (i1 & 0xffffffffL);
return Double.longBitsToDouble(l);
}
private static void encodeSLE(byte[] b, int boff, short v) {
b[boff + 0] = (byte) (v >>> 0);
b[boff + 1] = (byte) (v >>> 8);
}
private static void encodeSBE(byte[] b, int boff, short v) {
b[boff + 0] = (byte) (v >>> 8);
b[boff + 1] = (byte) (v >>> 0);
}
private static void encodeILE(byte[] b, int boff, int v) {
b[boff + 0] = (byte) (v >>> 0);
b[boff + 1] = (byte) (v >>> 8);
b[boff + 2] = (byte) (v >>> 16);
b[boff + 3] = (byte) (v >>> 24);
}
private static void encodeIBE(byte[] b, int boff, int v) {
b[boff + 0] = (byte) (v >>> 24);
b[boff + 1] = (byte) (v >>> 16);
b[boff + 2] = (byte) (v >>> 8);
b[boff + 3] = (byte) (v >>> 0);
}
private static void encodeLLE(byte[] b, int boff, long v) {
b[boff + 0] = (byte) (v >>> 0);
b[boff + 1] = (byte) (v >>> 8);
b[boff + 2] = (byte) (v >>> 16);
b[boff + 3] = (byte) (v >>> 24);
b[boff + 4] = (byte) (v >>> 32);
b[boff + 5] = (byte) (v >>> 40);
b[boff + 6] = (byte) (v >>> 48);
b[boff + 7] = (byte) (v >>> 56);
}
private static void encodeLBE(byte[] b, int boff, long v) {
b[boff + 0] = (byte) (v >>> 56);
b[boff + 1] = (byte) (v >>> 48);
b[boff + 2] = (byte) (v >>> 40);
b[boff + 3] = (byte) (v >>> 32);
b[boff + 4] = (byte) (v >>> 24);
b[boff + 5] = (byte) (v >>> 16);
b[boff + 6] = (byte) (v >>> 8);
b[boff + 7] = (byte) (v >>> 0);
}
private static void encodeFLE(byte[] b, int boff, float v) {
encodeILE(b, boff, Float.floatToIntBits(v));
}
private static void encodeFBE(byte[] b, int boff, float v) {
encodeIBE(b, boff, Float.floatToIntBits(v));
}
private static void encodeDLE(byte[] b, int boff, double v) {
encodeLLE(b, boff, Double.doubleToLongBits(v));
}
private static void encodeDBE(byte[] b, int boff, double v) {
encodeLBE(b, boff, Double.doubleToLongBits(v));
}
private final static class LE extends ByteArrayCodec {
@Override
public ByteOrder getByteOrder() {
return ByteOrder.LITTLE_ENDIAN;
}
@Override
public short getShort(byte[] b, int boff) {
return decodeSLE(b, boff);
}
@Override
public int getInt(byte[] b, int boff) {
return decodeILE(b, boff);
}
@Override
public long getLong(byte[] b, int boff) {
return decodeLLE(b, boff);
}
@Override
public float getFloat(byte[] b, int boff) {
return decodeFLE(b, boff);
}
@Override
public double getDouble(byte[] b, int boff) {
return decodeDL(b, boff);
}
@Override
public void getShorts(byte[] b, int boff, short[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeSLE(b, boff);
boff += 2;
}
}
@Override
public void getInts(byte[] b, int boff, int[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeILE(b, boff);
boff += 4;
}
}
@Override
public void getLongs(byte[] b, int boff, long[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeLLE(b, boff);
boff += 8;
}
}
@Override
public void getFloats(byte[] b, int boff, float[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeFLE(b, boff);
boff += 4;
}
}
@Override
public void getDoubles(byte[] b, int boff, double[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeDL(b, boff);
boff += 8;
}
}
@Override
public void setShort(byte[] b, int boff, short v) {
encodeSLE(b, boff, v);
}
@Override
public void setInt(byte[] b, int boff, int v) {
encodeILE(b, boff, v);
}
@Override
public void setLong(byte[] b, int boff, long v) {
encodeLLE(b, boff, v);
}
@Override
public void setFloat(byte[] b, int boff, float v) {
encodeFLE(b, boff, v);
}
@Override
public void setDouble(byte[] b, int boff, double v) {
encodeDLE(b, boff, v);
}
@Override
public void setShorts(byte[] b, int boff, short[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeSLE(b, boff, v[voff + i]);
boff += 2;
}
}
@Override
public void setInts(byte[] b, int boff, int[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeILE(b, boff, v[voff + i]);
boff += 4;
}
}
@Override
public void setLongs(byte[] b, int boff, long[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeLLE(b, boff, v[voff + i]);
boff += 8;
}
}
@Override
public void setFloats(byte[] b, int boff, float[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeFLE(b, boff, v[voff + i]);
boff += 4;
}
}
@Override
public void setDoubles(byte[] b, int boff, double[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeDLE(b, boff, v[voff + i]);
boff += 8;
}
}
}
private final static class BE extends ByteArrayCodec {
@Override
public ByteOrder getByteOrder() {
return ByteOrder.BIG_ENDIAN;
}
@Override
public short getShort(byte[] b, int boff) {
return decodeSBE(b, boff);
}
@Override
public int getInt(byte[] b, int boff) {
return decodeIBE(b, boff);
}
@Override
public long getLong(byte[] b, int boff) {
return decodeLBE(b, boff);
}
@Override
public float getFloat(byte[] b, int boff) {
return decodeFBE(b, boff);
}
@Override
public double getDouble(byte[] b, int boff) {
return decodeDBE(b, boff);
}
@Override
public void getShorts(byte[] b, int boff, short[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeSBE(b, boff);
boff += 2;
}
}
@Override
public void getInts(byte[] b, int boff, int[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeIBE(b, boff);
boff += 4;
}
}
@Override
public void getLongs(byte[] b, int boff, long[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeLBE(b, boff);
boff += 8;
}
}
@Override
public void getFloats(byte[] b, int boff, float[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeFBE(b, boff);
boff += 4;
}
}
@Override
public void getDoubles(byte[] b, int boff, double[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
v[voff + i] = decodeDBE(b, boff);
boff += 8;
}
}
@Override
public void setShort(byte[] b, int boff, short v) {
encodeSBE(b, boff, v);
}
@Override
public void setInt(byte[] b, int boff, int v) {
encodeIBE(b, boff, v);
}
@Override
public void setLong(byte[] b, int boff, long v) {
encodeLBE(b, boff, v);
}
@Override
public void setFloat(byte[] b, int boff, float v) {
encodeFBE(b, boff, v);
}
@Override
public void setDouble(byte[] b, int boff, double v) {
encodeDBE(b, boff, v);
}
@Override
public void setShorts(byte[] b, int boff, short[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeSBE(b, boff, v[voff + i]);
boff += 2;
}
}
@Override
public void setInts(byte[] b, int boff, int[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeIBE(b, boff, v[voff + i]);
boff += 4;
}
}
@Override
public void setLongs(byte[] b, int boff, long[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeLBE(b, boff, v[voff + i]);
boff += 8;
}
}
@Override
public void setFloats(byte[] b, int boff, float[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeFBE(b, boff, v[voff + i]);
boff += 4;
}
}
@Override
public void setDoubles(byte[] b, int boff, double[] v, int voff, int vlen) {
for (int i = 0; i < vlen; i++) {
encodeDBE(b, boff, v[voff + i]);
boff += 8;
}
}
}
}