22declare(strict_types=1);
 
   29use InvalidArgumentException;
 
   33use 
function preg_replace;
 
   42    private const SIZEOF_SHORT = 2;
 
   43    private const SIZEOF_INT = 4;
 
   44    private const SIZEOF_LONG = 8;
 
   46    private const SIZEOF_FLOAT = 4;
 
   47    private const SIZEOF_DOUBLE = 8;
 
   49    public static function signByte(
int $value) : 
int{
 
   50        return $value << 56 >> 56;
 
   53    public static function unsignByte(
int $value) : 
int{
 
   57    public static function signShort(
int $value) : 
int{
 
   58        return $value << 48 >> 48;
 
   61    public static function unsignShort(
int $value) : 
int{
 
   62        return $value & 0xffff;
 
   65    public static function signInt(
int $value) : 
int{
 
   66        return $value << 32 >> 32;
 
   69    public static function unsignInt(
int $value) : 
int{
 
   70        return $value & 0xffffffff;
 
   73    public static function flipShortEndianness(
int $value) : 
int{
 
   77    public static function flipIntEndianness(
int $value) : 
int{
 
   81    public static function flipLongEndianness(
int $value) : 
int{
 
   89    private static function safeUnpack(
string $formatCode, 
string $bytes, 
int $needLength) : array{
 
   90        $haveLength = strlen($bytes);
 
   91        if($haveLength < $needLength){
 
   95        $result = unpack($formatCode, $bytes);
 
   96        if($result === 
false){
 
   98            throw new \AssertionError(
"unpack() failed for unknown reason");
 
  107        return $b[0] !== 
"\x00";
 
 
  114        return $b ? 
"\x01" : 
"\x00";
 
 
  138        return self::signByte(ord($c[0]));
 
 
  154        return self::safeUnpack(
"n", $str, self::SIZEOF_SHORT)[1];
 
 
  163        return self::signShort(self::safeUnpack(
"n", $str, self::SIZEOF_SHORT)[1]);
 
 
  170        return pack(
"n", $value);
 
 
  179        return self::safeUnpack(
"v", $str, self::SIZEOF_SHORT)[1];
 
 
  188        return self::signShort(self::safeUnpack(
"v", $str, self::SIZEOF_SHORT)[1]);
 
 
  195        return pack(
"v", $value);
 
 
  204        return self::safeUnpack(
"N", 
"\x00" . $str, self::SIZEOF_INT)[1];
 
 
  211        return substr(pack(
"N", $value), 1);
 
 
  220        return self::safeUnpack(
"V", $str . 
"\x00", self::SIZEOF_INT)[1];
 
 
  227        return substr(pack(
"V", $value), 0, -1);
 
 
  235    public static function readInt(
string $str) : int{
 
  236        return self::signInt(self::safeUnpack(
"N", $str, self::SIZEOF_INT)[1]);
 
 
  242    public static function writeInt(
int $value) : string{
 
  243        return pack(
"N", $value);
 
 
  251    public static function readLInt(
string $str) : int{
 
  252        return self::signInt(self::safeUnpack(
"V", $str, self::SIZEOF_INT)[1]);
 
 
  259        return pack(
"V", $value);
 
 
  268        return self::safeUnpack(
"G", $str, self::SIZEOF_FLOAT)[1];
 
 
  277        return round(self::readFloat($str), $accuracy);
 
 
  284        return pack(
"G", $value);
 
 
  293        return self::safeUnpack(
"g", $str, self::SIZEOF_FLOAT)[1];
 
 
  302        return round(self::readLFloat($str), $accuracy);
 
 
  309        return pack(
"g", $value);
 
 
  316        return preg_replace(
"/(\\.\\d+?)0+$/", 
"$1", sprintf(
"%F", $value));
 
 
  325        return self::safeUnpack(
"E", $str, self::SIZEOF_DOUBLE)[1];
 
 
  332        return pack(
"E", $value);
 
 
  341        return self::safeUnpack(
"e", $str, self::SIZEOF_DOUBLE)[1];
 
 
  348        return pack(
"e", $value);
 
 
  356    public static function readLong(
string $str) : int{
 
  357        return self::safeUnpack(
"J", $str, self::SIZEOF_LONG)[1];
 
 
  364        return pack(
"J", $value);
 
 
  373        return self::safeUnpack(
"P", $str, self::SIZEOF_LONG)[1];
 
 
  380        return pack(
"P", $value);
 
 
  390    public static function readVarInt(
string $buffer, 
int &$offset) : int{
 
  391        $raw = self::readUnsignedVarInt($buffer, $offset);
 
  392        $temp = ((($raw << 63) >> 63) ^ $raw) >> 1;
 
  393        return $temp ^ ($raw & (1 << 63));
 
 
  405        for($i = 0; $i <= 28; $i += 7){
 
  406            if(!isset($buffer[$offset])){
 
  409            $b = ord($buffer[$offset++]);
 
  410            $value |= (($b & 0x7f) << $i);
 
  412            if(($b & 0x80) === 0){
 
 
  424        $v = ($v << 32 >> 32);
 
  425        return self::writeUnsignedVarInt(($v << 1) ^ ($v >> 31));
 
 
  435        $remaining = $value & 0xffffffff;
 
  436        for($i = 0; $i < 5; ++$i){
 
  437            if(($remaining >> 7) !== 0){
 
  438                $buf .= chr($remaining | 0x80);
 
  440                $buf .= chr($remaining & 0x7f);
 
  444            $remaining = (($remaining >> 7) & (PHP_INT_MAX >> 6)); 
 
  447        throw new InvalidArgumentException(
"Value too large to be encoded as a VarInt");
 
 
  457    public static function readVarLong(
string $buffer, 
int &$offset) : int{
 
  458        $raw = self::readUnsignedVarLong($buffer, $offset);
 
  459        $temp = ((($raw << 63) >> 63) ^ $raw) >> 1;
 
  460        return $temp ^ ($raw & (1 << 63));
 
 
  472        for($i = 0; $i <= 63; $i += 7){
 
  473            if(!isset($buffer[$offset])){
 
  476            $b = ord($buffer[$offset++]);
 
  477            $value |= (($b & 0x7f) << $i);
 
  479            if(($b & 0x80) === 0){
 
 
  491        return self::writeUnsignedVarLong(($v << 1) ^ ($v >> 63));
 
 
  500        for($i = 0; $i < 10; ++$i){
 
  501            if(($remaining >> 7) !== 0){
 
  502                $buf .= chr($remaining | 0x80); 
 
  504                $buf .= chr($remaining & 0x7f);
 
  508            $remaining = (($remaining >> 7) & (PHP_INT_MAX >> 6)); 
 
  511        throw new InvalidArgumentException(
"Value too large to be encoded as a VarLong");
 
 
 
static readRoundedLFloat(string $str, int $accuracy)
 
static writeShort(int $value)
 
static readShort(string $str)
 
static readDouble(string $str)
 
static readLLong(string $str)
 
static writeUnsignedVarInt(int $value)
 
static writeLDouble(float $value)
 
static writeUnsignedVarLong(int $value)
 
static readLong(string $str)
 
static writeDouble(float $value)
 
static readFloat(string $str)
 
static readUnsignedVarInt(string $buffer, int &$offset)
 
static writeTriad(int $value)
 
static readInt(string $str)
 
static readSignedShort(string $str)
 
static writeLLong(int $value)
 
static writeFloat(float $value)
 
static writeVarInt(int $v)
 
static writeLTriad(int $value)
 
static writeVarLong(int $v)
 
static writeLShort(int $value)
 
static writeLFloat(float $value)
 
static readLTriad(string $str)
 
static readUnsignedVarLong(string $buffer, int &$offset)
 
static writeLInt(int $value)
 
static writeBool(bool $b)
 
static readLInt(string $str)
 
static printFloat(float $value)
 
static readSignedByte(string $c)
 
static readRoundedFloat(string $str, int $accuracy)
 
static readByte(string $c)
 
static readVarLong(string $buffer, int &$offset)
 
static writeInt(int $value)
 
static readLDouble(string $str)
 
static readVarInt(string $buffer, int &$offset)
 
static writeLong(int $value)
 
static readLFloat(string $str)
 
static readSignedLShort(string $str)
 
static readLShort(string $str)
 
static readTriad(string $str)
 
static readBool(string $b)