/** * fast data-reading from a byte-array * * @author ab */ package btools.util; public class ByteDataReader { protected byte[] ab; protected int aboffset; protected int aboffsetEnd; public ByteDataReader(byte[] byteArray) { ab = byteArray; aboffsetEnd = ab == null ? 0 : ab.length; } public ByteDataReader(byte[] byteArray, int offset) { ab = byteArray; aboffset = offset; aboffsetEnd = ab == null ? 0 : ab.length; } public final void reset(byte[] byteArray) { ab = byteArray; aboffset = 0; aboffsetEnd = ab == null ? 0 : ab.length; } public final int readInt() { int i3 = ab[aboffset++] & 0xff; int i2 = ab[aboffset++] & 0xff; int i1 = ab[aboffset++] & 0xff; int i0 = ab[aboffset++] & 0xff; return (i3 << 24) + (i2 << 16) + (i1 << 8) + i0; } public final long readLong() { long i7 = ab[aboffset++] & 0xff; long i6 = ab[aboffset++] & 0xff; long i5 = ab[aboffset++] & 0xff; long i4 = ab[aboffset++] & 0xff; long i3 = ab[aboffset++] & 0xff; long i2 = ab[aboffset++] & 0xff; long i1 = ab[aboffset++] & 0xff; long i0 = ab[aboffset++] & 0xff; return (i7 << 56) + (i6 << 48) + (i5 << 40) + (i4 << 32) + (i3 << 24) + (i2 << 16) + (i1 << 8) + i0; } public final boolean readBoolean() { int i0 = ab[aboffset++] & 0xff; return i0 != 0; } public final byte readByte() { int i0 = ab[aboffset++] & 0xff; return (byte) (i0); } public final short readShort() { int i1 = ab[aboffset++] & 0xff; int i0 = ab[aboffset++] & 0xff; return (short) ((i1 << 8) | i0); } /** * Read a size value and return a pointer to the end of a data section of that size * * @return the pointer to the first byte after that section */ public final int getEndPointer() { int size = readVarLengthUnsigned(); return aboffset + size; } public final byte[] readDataUntil(int endPointer) { int size = endPointer - aboffset; if (size == 0) { return null; } byte[] data = new byte[size]; readFully(data); return data; } public final byte[] readVarBytes() { int len = readVarLengthUnsigned(); if (len == 0) { return null; } byte[] bytes = new byte[len]; readFully(bytes); return bytes; } public final int readVarLengthSigned() { int v = readVarLengthUnsigned(); return (v & 1) == 0 ? v >> 1 : -(v >> 1); } public final int readVarLengthUnsigned() { byte b; int v = (b = ab[aboffset++]) & 0x7f; if (b >= 0) return v; v |= ((b = ab[aboffset++]) & 0x7f) << 7; if (b >= 0) return v; v |= ((b = ab[aboffset++]) & 0x7f) << 14; if (b >= 0) return v; v |= ((b = ab[aboffset++]) & 0x7f) << 21; if (b >= 0) return v; v |= ((b = ab[aboffset++]) & 0xf) << 28; return v; } public final void readFully(byte[] ta) { System.arraycopy(ab, aboffset, ta, 0, ta.length); aboffset += ta.length; } public final boolean hasMoreData() { return aboffset < aboffsetEnd; } @Override public String toString() { StringBuilder sb = new StringBuilder("["); for (int i = 0; i < ab.length; i++) sb.append(i == 0 ? " " : ", ").append(Integer.toString(ab[i])); sb.append(" ]"); return sb.toString(); } }