package org.andengine.util.adt.bit;
/**
* (c) 2013 Nicolas Gramlich
*
* @author Nicolas Gramlich <ngramlich@zynga.com>
* @since 18:14:12 - 02.03.2013
* @author ngramlich
*/
public abstract class BitVector implements IBitVector {
// ===========================================================
// Constants
// ===========================================================
public static final int TRUE = 1;
public static final int FALSE = 0;
// ===========================================================
// Fields
// ===========================================================
// ===========================================================
// Constructors
// ===========================================================
public static IBitVector wrap(final byte[] pData) {
return new ByteBackedBitVector(pData);
}
public static IBitVector wrap(final int pSize, final byte[] pData) {
return new ByteBackedBitVector(pData);
}
public static IBitVector wrap(final long[] pData) {
return new LongBackedBitVector(pData);
}
public static IBitVector wrap(final int pSize, final long[] pData) {
return new LongBackedBitVector(pSize, pData);
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
public static int getByteIndex(final int pIndex) {
return pIndex / Byte.SIZE;
}
public static int getLongIndex(final int pIndex) {
return pIndex / Long.SIZE;
}
public static int getIndexInByte(final int pIndex) {
return pIndex % Byte.SIZE;
}
public static int getIndexInLong(final int pIndex) {
return pIndex % Long.SIZE;
}
public static int getBitInByte(final byte pByte, final int pIndex) throws IllegalArgumentException {
return BitVector.getBitsInByte(pByte, pIndex, 1);
}
public static int getBitsInByte(final byte pByte, final int pIndex, final int pCount) throws IllegalArgumentException {
if ((pIndex < 0) || ((pIndex + pCount) > Byte.SIZE)) {
throw new IllegalArgumentException("pIndex out of bounds: " + pIndex);
}
if ((pCount < 0) || (pCount > Byte.SIZE)) {
throw new IllegalArgumentException("pBitCount out of bounds: " + pCount);
}
final int shift = Byte.SIZE - pIndex - pCount;
final int shiftedByte = ((pByte & 0xFF) >> shift);
final int mask = (0x01 << (pCount)) - 1;
final int result = shiftedByte & mask;
return result;
}
public static byte setBitInByte(final byte pByte, final int pIndex, final boolean pTrue) throws IllegalArgumentException {
if ((pIndex < 0) || (pIndex >= Byte.SIZE)) {
throw new IllegalArgumentException("pIndex out of bounds: " + pIndex);
}
if (pTrue) {
final int mask = (0x80 >> pIndex);
final byte result = (byte)(pByte | mask);
return result;
} else {
final int mask = 0xFF ^ (0x80 >> pIndex);
final byte result = (byte)(pByte & mask);
return result;
}
}
public static byte setBitsInByte(final byte pByte, final int pIndex, final byte pBits, final int pBitIndex, final int pBitCount) throws IllegalArgumentException {
if ((pIndex < 0) || ((pIndex + pBitCount) > Byte.SIZE)) {
throw new IllegalArgumentException("pIndex out of bounds: " + pIndex);
}
if ((pBitIndex + pBitCount) > Byte.SIZE) {
throw new IllegalArgumentException("pBitIndex out of bounds: " + pIndex);
}
if ((pBitCount < 0) || (pBitCount > Byte.SIZE)) {
throw new IllegalArgumentException("pBitCount out of bounds: " + pIndex);
}
final int sizeMask = (0x01 << (pBitCount)) - 1;
final int byteMask = (sizeMask << (Byte.SIZE - (pBitCount + pIndex))) ^ 0xFF;
final int maskedByte = (pByte & byteMask) & 0xFF;
final int bitMask = sizeMask << (Byte.SIZE - (pBitCount + pBitIndex));
final int maskedBits = (pBits & bitMask) & 0xFF;
final int shift = (pBitIndex - pIndex);
final int shiftedBits;
if (shift < 0) {
shiftedBits = maskedBits >> -shift;
} else {
shiftedBits = maskedBits << shift;
}
final byte result = (byte) (maskedByte | shiftedBits);
return result;
}
public static int calculateByteSize(final int pBitSize) {
if (pBitSize < 0) {
throw new IllegalArgumentException("pBitSize out of bounds: " + pBitSize);
}
if (BitVector.getIndexInByte(pBitSize) == 0) {
return pBitSize / Byte.SIZE;
} else {
return 1 + (pBitSize / Byte.SIZE);
}
}
public static int calculateLongSize(final int pBitSize) {
if (pBitSize < 0) {
throw new IllegalArgumentException("pBitSize out of bounds: " + pBitSize);
}
if (BitVector.getIndexInLong(pBitSize) == 0) {
return pBitSize / Byte.SIZE;
} else {
return 1 + (pBitSize / Byte.SIZE);
}
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}