mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-01-20 09:17:29 +07:00
Created ByteOutput and BitOutput
This commit is contained in:
parent
4e2cd665cd
commit
11555397e3
182
core/src/com/riiablo/io/BitOutput.java
Normal file
182
core/src/com/riiablo/io/BitOutput.java
Normal file
@ -0,0 +1,182 @@
|
||||
package com.riiablo.io;
|
||||
|
||||
public class BitOutput {
|
||||
private static final long[] MASKS = BitConstants.UNSIGNED_MASKS;
|
||||
|
||||
private final boolean autoFlush = true;
|
||||
private final ByteOutput byteOutput;
|
||||
private final long numBits;
|
||||
private long bitsWritten;
|
||||
private int bitsCached;
|
||||
private long cache;
|
||||
|
||||
BitOutput(ByteOutput byteOutput) {
|
||||
this(byteOutput, 0, 0L, (long) byteOutput.bytesRemaining() * Byte.SIZE);
|
||||
}
|
||||
|
||||
BitOutput(ByteOutput byteOutput, int bitsCached, long cache, long numBits) {
|
||||
this.byteOutput = byteOutput;
|
||||
this.bitsCached = bitsCached;
|
||||
this.cache = cache;
|
||||
this.numBits = numBits;
|
||||
}
|
||||
|
||||
ByteOutput byteOutput() {
|
||||
return byteOutput;
|
||||
}
|
||||
|
||||
void clearCache() {
|
||||
bitsCached = 0;
|
||||
cache = 0L;
|
||||
}
|
||||
|
||||
long incrementBitsWritten(long bits) {
|
||||
if ((bitsWritten += bits) > numBits) {
|
||||
bitsWritten = numBits;
|
||||
throw new EndOfInput();
|
||||
}
|
||||
|
||||
return bitsWritten;
|
||||
}
|
||||
|
||||
public boolean aligned() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void align() {
|
||||
|
||||
}
|
||||
|
||||
void flush(boolean align) {
|
||||
// write cache and clear it (align stream too?)
|
||||
if (align) {
|
||||
align();
|
||||
// assert cache cleared
|
||||
} else {
|
||||
// write byte
|
||||
// backup writer index 1 byte
|
||||
}
|
||||
|
||||
assert bitsCached < Byte.SIZE : "bitsCached(" + bitsCached + ") > " + (Byte.SIZE - 1);
|
||||
byteOutput._write8(cache);
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void _writeUnsigned(long value, int bits) {
|
||||
assert bits > 0 : "bits(" + bits + ") <= " + 0;
|
||||
assert bits < Long.SIZE : "bits(" + bits + ") > " + (Long.SIZE - 1);
|
||||
assert (value & ~MASKS[bits]) == 0 : "value(" + value + ") is larger than bits(" + bits + ")";
|
||||
incrementBitsWritten(bits);
|
||||
cache |= (value << bitsCached);
|
||||
bitsCached += bits;
|
||||
if (bitsCached > Long.SIZE) {
|
||||
writeCacheSafe(value, bits);
|
||||
} else {
|
||||
writeCacheUnsafe(bits);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeCacheSafe(long value, int bits) {
|
||||
assert bits > 0 : "bits(" + bits + ") < " + 1;
|
||||
assert bits < Long.SIZE : "bits(" + bits + ") > " + (Long.SIZE - 1);
|
||||
assert bitsCached > Long.SIZE : "bitsCached(" + bitsCached + ") <= " + Long.SIZE;
|
||||
assert bitsCached - bits < Byte.SIZE : "bitsCached(" + bitsCached + ") - bits(" + bits + ") > " + (Byte.SIZE - 1);
|
||||
|
||||
final int overflowBits = bitsCached - Long.SIZE;
|
||||
final int overflowShift = Long.SIZE - overflowBits;
|
||||
|
||||
for (; bitsCached >= Byte.SIZE; bitsCached -= Byte.SIZE) {
|
||||
final long octet = cache & 0xFF;
|
||||
byteOutput._write8(octet);
|
||||
cache >>>= Byte.SIZE;
|
||||
}
|
||||
|
||||
assert overflowBits > 0 : "overflowBits(" + overflowBits + ") < " + 1;
|
||||
cache = (value >>> overflowShift) & MASKS[overflowBits];
|
||||
}
|
||||
|
||||
private void writeCacheUnsafe(int bits) {
|
||||
assert bits > 0 : "bits(" + bits + ") < " + 1;
|
||||
assert bits < Long.SIZE : "bits(" + bits + ") > " + (Long.SIZE - 1);
|
||||
assert bitsCached >= bits : "bitsCached(" + bitsCached + ") < bits(" + bits + ")";
|
||||
assert bitsCached <= Long.SIZE : "bitsCached(" + bitsCached + ") > " + Long.SIZE;
|
||||
for (; bitsCached >= Byte.SIZE; bitsCached -= Byte.SIZE) {
|
||||
final long octet = cache & 0xFF;
|
||||
byteOutput._write8(octet);
|
||||
cache >>>= Byte.SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void writeSigned(long value, int bits) {
|
||||
assert bits > 0 : "bits(" + bits + ") <= " + 0;
|
||||
assert bits <= Long.SIZE : "bits(" + bits + ") > " + Long.SIZE;
|
||||
// bits == Long.SIZE write raw?
|
||||
final int shift = Long.SIZE - bits;
|
||||
assert shift > 0 : "shift(" + shift + ") <= " + 0;
|
||||
value = value << shift >> shift;
|
||||
}
|
||||
|
||||
public void writeRaw(long value, int bits) {
|
||||
BitConstraints.validate64(bits);
|
||||
}
|
||||
|
||||
public void writeUnsigned(long value, int bits) {
|
||||
write63u(value, bits);
|
||||
}
|
||||
|
||||
public void write7u(byte value, int bits) {
|
||||
BitConstraints.validate7u(bits);
|
||||
_writeUnsigned(value, bits);
|
||||
}
|
||||
|
||||
public void write15u(short value, int bits) {
|
||||
BitConstraints.validate15u(bits);
|
||||
_writeUnsigned(value, bits);
|
||||
}
|
||||
|
||||
public void write31u(int value, int bits) {
|
||||
BitConstraints.validate31u(bits);
|
||||
_writeUnsigned(value, bits);
|
||||
}
|
||||
|
||||
public void write63u(long value, int bits) {
|
||||
BitConstraints.validate63u(bits);
|
||||
_writeUnsigned(value, bits);
|
||||
}
|
||||
|
||||
// sign-extends bits
|
||||
public void write8(int value, int bits) {
|
||||
BitConstraints.validate8(bits);
|
||||
}
|
||||
|
||||
// sign-extends bits
|
||||
public void write16(int value, int bits) {
|
||||
BitConstraints.validate16(bits);
|
||||
}
|
||||
|
||||
// sign-extends bits
|
||||
public void write32(int value, int bits) {
|
||||
BitConstraints.validate32(bits);
|
||||
}
|
||||
|
||||
// sign-extends bits
|
||||
public void write64(long value, int bits) {
|
||||
BitConstraints.validate64(bits);
|
||||
}
|
||||
|
||||
public void write8(int value) {
|
||||
write8(value, Byte.SIZE);
|
||||
}
|
||||
|
||||
public void write16(int value) {
|
||||
write16(value, Short.SIZE);
|
||||
}
|
||||
|
||||
public void write32(int value) {
|
||||
write32(value, Integer.SIZE);
|
||||
}
|
||||
|
||||
public void write64(long value) {
|
||||
write64(value, Long.SIZE);
|
||||
}
|
||||
}
|
67
core/src/com/riiablo/io/ByteOutput.java
Normal file
67
core/src/com/riiablo/io/ByteOutput.java
Normal file
@ -0,0 +1,67 @@
|
||||
package com.riiablo.io;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class ByteOutput {
|
||||
private final ByteBuf buffer;
|
||||
private BitOutput bitOutput;
|
||||
|
||||
ByteOutput(ByteBuf buffer) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
BitOutput bitOutput() {
|
||||
return bitOutput != null ? bitOutput : (bitOutput = new BitOutput(this));
|
||||
}
|
||||
|
||||
public ByteBuf buffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public int bytesRemaining() {
|
||||
return buffer.writableBytes();
|
||||
}
|
||||
|
||||
public boolean aligned() {
|
||||
throw null;
|
||||
}
|
||||
|
||||
public BitOutput unalign() {
|
||||
return bitOutput();
|
||||
}
|
||||
|
||||
long incrementBitsWritten(long bits) {
|
||||
assert (bits & (Byte.SIZE - 1)) == 0;
|
||||
if (bitOutput == null) return 0;
|
||||
return bitOutput.incrementBitsWritten(bits);
|
||||
}
|
||||
|
||||
void _write8(long octet) {
|
||||
assert 0 <= octet && octet < (1 << Byte.SIZE);
|
||||
buffer.writeByte((int) octet);
|
||||
}
|
||||
|
||||
public void write8(int value) {
|
||||
assert aligned() : "not aligned";
|
||||
incrementBitsWritten(Byte.SIZE);
|
||||
buffer.writeByte(value);
|
||||
}
|
||||
|
||||
public void write16(int value) {
|
||||
assert aligned() : "not aligned";
|
||||
incrementBitsWritten(Short.SIZE);
|
||||
buffer.writeShortLE(value);
|
||||
}
|
||||
|
||||
public void write32(int value) {
|
||||
assert aligned() : "not aligned";
|
||||
incrementBitsWritten(Short.SIZE);
|
||||
buffer.writeIntLE(value);
|
||||
}
|
||||
|
||||
public void write64(long value) {
|
||||
assert aligned() : "not aligned";
|
||||
incrementBitsWritten(Short.SIZE);
|
||||
buffer.writeLongLE(value);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user