brouter/brouter-util/src/main/java/btools/util/ByteDataWriter.java
2023-04-29 19:04:52 +02:00

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;
}
}