All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.nukkit.utils.VarInt Maven / Gradle / Ivy

There is a newer version: 1.20.40-r1
Show newest version
package cn.nukkit.utils;

import cn.nukkit.api.API;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import static cn.nukkit.api.API.Definition.UNIVERSAL;
import static cn.nukkit.api.API.Usage.EXPERIMENTAL;

/**
 * Tool class for VarInt or VarLong operations.
 * 

* Some code from http://wiki.vg/Protocol. * * @author MagicDroidX * @author lmlstarqaq */ @API(usage = EXPERIMENTAL, definition = UNIVERSAL) public final class VarInt { private VarInt() { //no instance } /** * @param v Signed int * @return Unsigned encoded int */ public static long encodeZigZag32(int v) { // Note: the right-shift must be arithmetic return ((v << 1) ^ (v >> 31)) & 0xFFFFFFFFL; } /** * @param v Unsigned encoded int * @return Signed decoded int */ public static int decodeZigZag32(long v) { return (int) (v >> 1) ^ -(int) (v & 1); } /** * @param v Signed long * @return Unsigned encoded long */ public static long encodeZigZag64(long v) { return (v << 1) ^ (v >> 63); } /** * @param v Signed encoded long * @return Unsigned decoded long */ public static long decodeZigZag64(long v) { return (v >>> 1) ^ -(v & 1); } private static long read(BinaryStream stream, int maxSize) { long value = 0; int size = 0; int b; while (((b = stream.getByte()) & 0x80) == 0x80) { value |= (long) (b & 0x7F) << (size++ * 7); if (size >= maxSize) { throw new IllegalArgumentException("VarLong too big"); } } return value | ((long) (b & 0x7F) << (size * 7)); } private static long read(InputStream stream, int maxSize) throws IOException { long value = 0; int size = 0; int b; while (((b = stream.read()) & 0x80) == 0x80) { value |= (long) (b & 0x7F) << (size++ * 7); if (size >= maxSize) { throw new IllegalArgumentException("VarLong too big"); } } return value | ((long) (b & 0x7F) << (size * 7)); } /** * @param stream BinaryStream * @return Signed int */ public static int readVarInt(BinaryStream stream) { return decodeZigZag32(readUnsignedVarInt(stream)); } /** * @param stream InputStream * @return Signed int */ public static int readVarInt(InputStream stream) throws IOException { return decodeZigZag32(readUnsignedVarInt(stream)); } /** * @param stream BinaryStream * @return Unsigned int */ public static long readUnsignedVarInt(BinaryStream stream) { return read(stream, 5); } /** * @param stream InputStream * @return Unsigned int */ public static long readUnsignedVarInt(InputStream stream) throws IOException { return read(stream, 5); } /** * @param stream BinaryStream * @return Signed long */ public static long readVarLong(BinaryStream stream) { return decodeZigZag64(readUnsignedVarLong(stream)); } /** * @param stream InputStream * @return Signed long */ public static long readVarLong(InputStream stream) throws IOException { return decodeZigZag64(readUnsignedVarLong(stream)); } /** * @param stream BinaryStream * @return Unsigned long */ public static long readUnsignedVarLong(BinaryStream stream) { return read(stream, 10); } /** * @param stream InputStream * @return Unsigned long */ public static long readUnsignedVarLong(InputStream stream) throws IOException { return read(stream, 10); } private static void write(BinaryStream stream, long value) { do { byte temp = (byte) (value & 0b01111111); // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone value >>>= 7; if (value != 0) { temp |= 0b10000000; } stream.putByte(temp); } while (value != 0); } private static void write(OutputStream stream, long value) throws IOException { do { byte temp = (byte) (value & 0b01111111); // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone value >>>= 7; if (value != 0) { temp |= 0b10000000; } stream.write(temp); } while (value != 0); } /** * @param stream BinaryStream * @param value Signed int */ public static void writeVarInt(BinaryStream stream, int value) { writeUnsignedVarInt(stream, encodeZigZag32(value)); } /** * @param stream OutputStream * @param value Signed int */ public static void writeVarInt(OutputStream stream, int value) throws IOException { writeUnsignedVarInt(stream, encodeZigZag32(value)); } /** * @param stream BinaryStream * @param value Unsigned int */ public static void writeUnsignedVarInt(BinaryStream stream, long value) { write(stream, value); } /** * @param stream OutputStream * @param value Unsigned int */ public static void writeUnsignedVarInt(OutputStream stream, long value) throws IOException { write(stream, value); } /** * @param stream BinaryStream * @param value Signed long */ public static void writeVarLong(BinaryStream stream, long value) { writeUnsignedVarLong(stream, encodeZigZag64(value)); } /** * @param stream OutputStream * @param value Signed long */ public static void writeVarLong(OutputStream stream, long value) throws IOException { writeUnsignedVarLong(stream, encodeZigZag64(value)); } /** * @param stream BinaryStream * @param value Unsigned long */ public static void writeUnsignedVarLong(BinaryStream stream, long value) { write(stream, value); } /** * @param stream OutputStream * @param value Unsigned long */ public static void writeUnsignedVarLong(OutputStream stream, long value) throws IOException { write(stream, value); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy