diff options
author | Leonard Kugis <leonard@kug.is> | 2022-04-25 18:41:24 +0200 |
---|---|---|
committer | Leonard Kugis <leonard@kug.is> | 2022-04-25 18:41:24 +0200 |
commit | 7abf31ea821a0bbddb836adb1a63d0fec2ceee4f (patch) | |
tree | ad9f4f4a1e6bbf5000b8eeb78180eed3923d72e7 /src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java |
Diffstat (limited to 'src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java')
-rwxr-xr-x | src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java b/src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java new file mode 100755 index 0000000..a05fa7a --- /dev/null +++ b/src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java @@ -0,0 +1,100 @@ +/** + * @author Aleksey Terzi + * + */ + +package com.encrox.instancedregions.chunkmap; + +import java.io.IOException; + +public class ChunkReader { + private byte[] data; + private int bitsPerBlock; + private long maxValueMask; + private int byteIndex; + private int bitIndex; + private long buffer; + + public ChunkReader(byte[] data) { + this.data = data; + this.byteIndex = 0; + this.bitIndex = 0; + } + + public int getByteIndex() { + return this.byteIndex; + } + + public void skip(int count) { + this.byteIndex += count; + this.bitIndex = 0; + } + + public void setBitsPerBlock(int bitsPerBlock) { + this.bitsPerBlock = bitsPerBlock; + this.maxValueMask = (1L << this.bitsPerBlock) - 1; + } + + public int readBlockBits() throws IOException { + if(this.bitIndex == 0 || this.bitIndex >= 64) { + readLong(); + this.bitIndex = 0; + } + + int leftBits = 64 - this.bitIndex; + long result = this.buffer >>> this.bitIndex; + + if(leftBits >= this.bitsPerBlock) { + this.bitIndex += this.bitsPerBlock; + } else { + readLong(); + + result |= this.buffer << leftBits; + + this.bitIndex = this.bitsPerBlock - leftBits; + } + + return (int)(result & this.maxValueMask); + } + + private void readLong() throws IOException { + if(this.byteIndex + 7 >= this.data.length) { + throw new IOException("No data to read."); + } + + this.buffer = ((this.data[this.byteIndex] & 0xffL) << 56) + | ((this.data[this.byteIndex + 1] & 0xffL) << 48) + | ((this.data[this.byteIndex + 2] & 0xffL) << 40) + | ((this.data[this.byteIndex + 3] & 0xffL) << 32) + | ((this.data[this.byteIndex + 4] & 0xffL) << 24) + | ((this.data[this.byteIndex + 5] & 0xffL) << 16) + | ((this.data[this.byteIndex + 6] & 0xffL) << 8) + | (this.data[this.byteIndex + 7] & 0xffL); + + this.byteIndex += 8; + } + + public int readVarInt() throws IOException { + int value = 0; + int size = 0; + int b; + + while(((b = readByte()) & 0x80) == 0x80) { + value |= (b & 0x7F) << (size++ * 7); + + if(size > 5) { + throw new IOException("Invalid VarInt."); + } + } + + return value | ((b & 0x7F) << (size * 7)); + } + + public int readByte() throws IOException { + if(this.byteIndex >= this.data.length) { + throw new IOException("No data to read."); + } + + return this.data[this.byteIndex++] & 0xff; + } +} |