Skip to content

Instantly share code, notes, and snippets.

@cobolfoo
Created February 9, 2016 17:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cobolfoo/0c4124308e7cc05d82b8 to your computer and use it in GitHub Desktop.
Save cobolfoo/0c4124308e7cc05d82b8 to your computer and use it in GitHub Desktop.
Bit packer for JAVA
package org.shadebob.netcode.tools;
import java.util.BitSet;
/**
* Bit packer utility class
*/
public class BitPacker {
private final static int MAX_SIZE = 32768;
private BitSet data = new BitSet(MAX_SIZE);
private int numBits = 0;
private int readCursor = 0;
public void clear() {
data.clear();
numBits = 0;
}
public byte[] toBytes() {
pad();
byte[] output = new byte[numBits / 8];
for (int i=0;i<output.length;i++) {
output[i] = getByte();
}
return output;
}
public void putByte(byte value) {
putByte(value, Byte.SIZE);
}
public void putByte(byte value, int length) {
if (length > Byte.SIZE) {
System.out.println("Invalid length (" + length +") in putByte()");
System.exit(-1);
}
for (int i=0;i<length;i++) {
if (((value >> i) & 1) == 1) {
data.set(numBits++, true);
} else {
data.set(numBits++, false);
}
}
}
public void putShort(short value) {
putShort(value, Short.SIZE);
}
public void putShort(short value, int length) {
if (length > Short.SIZE) {
System.out.println("Invalid length (" + length +") in putShort()");
System.exit(-1);
}
for (int i=0;i<length;i++) {
if (((value >> i) & 1) == 1) {
data.set(numBits++, true);
} else {
data.set(numBits++, false);
}
}
}
public void putInteger(int value) {
putInteger(value, Integer.SIZE);
}
public void putInteger(int value, int length) {
if (length > Integer.SIZE) {
System.out.println("Invalid length (" + length +") in putInteger()");
System.exit(-1);
}
for (int i=0;i<length;i++) {
if (((value >> i) & 1) == 1) {
data.set(numBits++, true);
} else {
data.set(numBits++, false);
}
}
}
public void putLong(long value) {
putLong(value, Long.SIZE);
}
public void putLong(long value, int length) {
if (length > Long.SIZE) {
System.out.println("Invalid length (" + length +") in putLong()");
System.exit(-1);
}
for (int i=0;i<length;i++) {
if (((value >> i) & 1) == 1) {
data.set(numBits++, true);
} else {
data.set(numBits++, false);
}
}
}
public void putFloat(float value) {
int raw = Float.floatToRawIntBits(value);
for (int i=0;i<Float.SIZE;i++) {
if (((raw >> i) & 1) == 1) {
data.set(numBits++, true);
} else {
data.set(numBits++, false);
}
}
}
public void putBoolean(boolean value) {
data.set(numBits++, value);
}
public void putString(String value) {
byte[] payload = value.getBytes();
int length = payload.length;
if (length > 255) {
length = 255;
}
putInteger(length,8);
putBytes(payload);
}
public void putBytes(byte[] value) {
for (int i=0;i<value.length;i++) {
putByte(value[i]);
}
}
public static void dumpBytes(byte[] value) {
System.out.println("+--------------- ------------- ------- ------ --- -- -- - -- -- --");
System.out.println("| Dumping bytes, length: " + (value.length*8) + " (" + value.length + " byte(s))");
System.out.println("+--------------- ------------- ------- ------ --- -- -- - -- -- --");
int count = 0;
for (int j=0;j<value.length;j++) {
byte v = value[j];
for (int i=0;i<Byte.SIZE;i++) {
if (((v >> i) & 1) == 1) {
System.out.print("1");
} else {
System.out.print("0");
}
}
System.out.print(" ");
count++;
if (count == 12) {
System.out.println();
count = 0;
}
}
System.out.println();
System.out.println("+--------------- ------------- ------- ------ --- -- -- - -- -- --");
}
public void dump() {
System.out.println("+--------------- ------------- ------- ------ --- -- -- - -- -- --");
System.out.println("| Dumping bitset, length: " + numBits);
System.out.println("+--------------- ------------- ------- ------ --- -- -- - -- -- --");
int count = 0;
for (int i=0;i<numBits;i++) {
System.out.print(data.get(i)?"1":"0");
if ((i != 0) && (i % 8 == 7)) {
System.out.print(" ");
count++;
if (count == 12) {
System.out.println();
count = 0;
}
}
}
System.out.println();
System.out.println("+--------------- ------------- ------- ------ --- -- -- - -- -- --");
}
public void rewind() {
readCursor = 0;
}
public byte getByte() {
return getByte(Byte.SIZE);
}
public byte getByte(int length) {
byte value = 0;
for (int i=0;i<length;i++) {
value |= (data.get(readCursor++)?1:0) << (i%Byte.SIZE);
}
return value;
}
public short getShort() {
return getShort(Short.SIZE);
}
public short getShort(int length) {
short value = 0;
for (int i=0;i<length;i++) {
value |= (data.get(readCursor++)?1:0) << (i%Short.SIZE);
}
return value;
}
public int getInteger() {
return getInteger(Integer.SIZE);
}
public int getInteger(int length) {
int value = 0;
for (int i=0;i<length;i++) {
if (readCursor > numBits-1) {
System.out.println("Out of bound error, read: " + readCursor +", numBits: " +numBits);
System.exit(-1);
}
value |= (data.get(readCursor++)?1:0) << (i%Integer.SIZE);
}
return value;
}
public long getLong() {
return getLong(Long.SIZE);
}
public long getLong(int length) {
long value = 0;
for (int i=0;i<length;i++) {
if (readCursor > numBits-1) {
System.out.println("Out of bound error, read: " + readCursor +", numBits: " +numBits);
System.exit(-1);
}
value |= (data.get(readCursor++)?1:0) << (i%Long.SIZE);
}
return value;
}
public float getFloat() {
return getFloat(Float.SIZE);
}
public float getFloat(int length) {
int value = 0;
for (int i=0;i<length;i++) {
if (readCursor > numBits-1) {
System.out.println("Out of bound error, read: " + readCursor +", numBits: " +numBits);
System.exit(-1);
}
value |= (data.get(readCursor++)?1:0) << (i%Float.SIZE);
}
return Float.intBitsToFloat(value);
}
public boolean getBoolean() {
if (readCursor > numBits-1) {
System.out.println("Out of bound error, read: " + readCursor +", numBits: " +numBits);
System.exit(-1);
}
return data.get(readCursor++);
}
public byte[] getBytes(int length) {
byte[] output = new byte[length];
for (int i=0;i<length;i++) {
output[i] = getByte();
}
return output;
}
public String getString() {
int length = getInteger(8);
byte[] payload = getBytes(length);
return new String(payload);
}
public void pad() {
int remaining = 8 - (numBits % 8);
for (int i=0;i<remaining;i++) {
putBoolean(false);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment