summaryrefslogtreecommitdiff
path: root/src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java')
-rwxr-xr-xsrc/main/java/com/encrox/instancedregions/chunkmap/ChunkReader.java100
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;
+ }
+}