150 lines
3.5 KiB
Java
150 lines
3.5 KiB
Java
/**
|
|
* fast data-writing to a byte-array
|
|
*
|
|
* @author ab
|
|
*/
|
|
package btools.util;
|
|
|
|
|
|
public class ByteDataWriter extends ByteDataReader {
|
|
public ByteDataWriter(byte[] byteArray) {
|
|
super(byteArray);
|
|
}
|
|
|
|
public final void writeInt(int v) {
|
|
ab[aboffset++] = (byte) ((v >> 24) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 16) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 8) & 0xff);
|
|
ab[aboffset++] = (byte) ((v) & 0xff);
|
|
}
|
|
|
|
public final void writeLong(long v) {
|
|
ab[aboffset++] = (byte) ((v >> 56) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 48) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 40) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 32) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 24) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 16) & 0xff);
|
|
ab[aboffset++] = (byte) ((v >> 8) & 0xff);
|
|
ab[aboffset++] = (byte) ((v) & 0xff);
|
|
}
|
|
|
|
public final void writeBoolean(boolean v) {
|
|
ab[aboffset++] = (byte) (v ? 1 : 0);
|
|
}
|
|
|
|
public final void writeByte(int v) {
|
|
ab[aboffset++] = (byte) ((v) & 0xff);
|
|
}
|
|
|
|
public final void writeShort(int v) {
|
|
ab[aboffset++] = (byte) ((v >> 8) & 0xff);
|
|
ab[aboffset++] = (byte) ((v) & 0xff);
|
|
}
|
|
|
|
public final void write(byte[] sa) {
|
|
System.arraycopy(sa, 0, ab, aboffset, sa.length);
|
|
aboffset += sa.length;
|
|
}
|
|
|
|
public final void write(byte[] sa, int offset, int len) {
|
|
System.arraycopy(sa, offset, ab, aboffset, len);
|
|
aboffset += len;
|
|
}
|
|
|
|
public final void writeVarBytes(byte[] sa) {
|
|
if (sa == null) {
|
|
writeVarLengthUnsigned(0);
|
|
} else {
|
|
int len = sa.length;
|
|
writeVarLengthUnsigned(len);
|
|
write(sa, 0, len);
|
|
}
|
|
}
|
|
|
|
public final void writeModeAndDesc(boolean isReverse, byte[] sa) {
|
|
int len = sa == null ? 0 : sa.length;
|
|
int sizecode = len << 1 | (isReverse ? 1 : 0);
|
|
writeVarLengthUnsigned(sizecode);
|
|
if (len > 0) {
|
|
write(sa, 0, len);
|
|
}
|
|
}
|
|
|
|
|
|
public final byte[] toByteArray() {
|
|
byte[] c = new byte[aboffset];
|
|
System.arraycopy(ab, 0, c, 0, aboffset);
|
|
return c;
|
|
}
|
|
|
|
|
|
/**
|
|
* Just reserves a single byte and return it' offset.
|
|
* Used in conjunction with injectVarLengthUnsigned
|
|
* to efficiently write a size prefix
|
|
*
|
|
* @return the offset of the placeholder
|
|
*/
|
|
public final int writeSizePlaceHolder() {
|
|
return aboffset++;
|
|
}
|
|
|
|
public final void injectSize(int sizeoffset) {
|
|
int size = 0;
|
|
int datasize = aboffset - sizeoffset - 1;
|
|
int v = datasize;
|
|
do {
|
|
v >>= 7;
|
|
size++;
|
|
}
|
|
while (v != 0);
|
|
if (size > 1) { // doesn't fit -> shift the data after the placeholder
|
|
System.arraycopy(ab, sizeoffset + 1, ab, sizeoffset + size, datasize);
|
|
}
|
|
aboffset = sizeoffset;
|
|
writeVarLengthUnsigned(datasize);
|
|
aboffset = sizeoffset + size + datasize;
|
|
}
|
|
|
|
public final void writeVarLengthSigned(int v) {
|
|
writeVarLengthUnsigned(v < 0 ? ((-v) << 1) | 1 : v << 1);
|
|
}
|
|
|
|
public final void writeVarLengthUnsigned(int v) {
|
|
int i7 = v & 0x7f;
|
|
if ((v >>>= 7) == 0) {
|
|
ab[aboffset++] = (byte) (i7);
|
|
return;
|
|
}
|
|
ab[aboffset++] = (byte) (i7 | 0x80);
|
|
|
|
i7 = v & 0x7f;
|
|
if ((v >>>= 7) == 0) {
|
|
ab[aboffset++] = (byte) (i7);
|
|
return;
|
|
}
|
|
ab[aboffset++] = (byte) (i7 | 0x80);
|
|
|
|
i7 = v & 0x7f;
|
|
if ((v >>>= 7) == 0) {
|
|
ab[aboffset++] = (byte) (i7);
|
|
return;
|
|
}
|
|
ab[aboffset++] = (byte) (i7 | 0x80);
|
|
|
|
i7 = v & 0x7f;
|
|
if ((v >>>= 7) == 0) {
|
|
ab[aboffset++] = (byte) (i7);
|
|
return;
|
|
}
|
|
ab[aboffset++] = (byte) (i7 | 0x80);
|
|
|
|
ab[aboffset++] = (byte) (v);
|
|
}
|
|
|
|
public int size() {
|
|
return aboffset;
|
|
}
|
|
|
|
}
|