Added binary reading optimizations, faster 64-bit reading

This commit is contained in:
Shoghi Cervantes 2014-09-10 12:13:15 +02:00
parent 8940360df4
commit 1174b0c45c
2 changed files with 67 additions and 59 deletions

View File

@ -68,8 +68,8 @@ abstract class DataPacket extends \stdClass{
$this->buffer .= $str; $this->buffer .= $str;
} }
protected function getLong($signed = true){ protected function getLong(){
return Binary::readLong($this->get(8), $signed); return Binary::readLong($this->get(8));
} }
protected function putLong($v){ protected function putLong($v){

View File

@ -41,9 +41,7 @@ class Binary{
* @return mixed * @return mixed
*/ */
public static function readTriad($str){ public static function readTriad($str){
list(, $unpacked) = @unpack("N", "\x00" . $str); return @unpack("N", "\x00" . $str)[1];
return $unpacked;
} }
/** /**
@ -206,12 +204,17 @@ class Binary{
*/ */
public static function readByte($c, $signed = true){ public static function readByte($c, $signed = true){
$b = ord($c{0}); $b = ord($c{0});
if($signed === true and ($b & 0x80) === 0x80){ //calculate Two's complement
$b = -0x80 + ($b & 0x7f);
}
if($signed){
if(PHP_INT_SIZE === 8){
return $b << 56 >> 56;
}else{
return $b << 24 >> 24;
}
}else{
return $b; return $b;
} }
}
/** /**
* Writes an unsigned/signed byte * Writes an unsigned/signed byte
@ -221,10 +224,6 @@ class Binary{
* @return string * @return string
*/ */
public static function writeByte($c){ public static function writeByte($c){
if($c < 0 and $c >= -0x80){
$c = 0xff + $c + 1;
}
return chr($c); return chr($c);
} }
@ -238,12 +237,17 @@ class Binary{
*/ */
public static function readShort($str, $signed = true){ public static function readShort($str, $signed = true){
$unpacked = @unpack("n", $str)[1]; $unpacked = @unpack("n", $str)[1];
if($unpacked > 0x7fff and $signed === true){
$unpacked -= 0x10000; // Convert unsigned short to signed short
}
if($signed){
if(PHP_INT_SIZE === 8){
return $unpacked << 48 >> 48;
}else{
return $unpacked << 16 >> 16;
}
}else{
return $unpacked; return $unpacked;
} }
}
/** /**
* Writes a 16-bit signed/unsigned big-endian number * Writes a 16-bit signed/unsigned big-endian number
@ -253,10 +257,6 @@ class Binary{
* @return string * @return string
*/ */
public static function writeShort($value){ public static function writeShort($value){
if($value < 0){
$value += 0x10000;
}
return pack("n", $value); return pack("n", $value);
} }
@ -270,12 +270,17 @@ class Binary{
*/ */
public static function readLShort($str, $signed = true){ public static function readLShort($str, $signed = true){
$unpacked = @unpack("v", $str)[1]; $unpacked = @unpack("v", $str)[1];
if($unpacked > 0x7fff and $signed === true){
$unpacked -= 0x10000; // Convert unsigned short to signed short
}
if($signed){
if(PHP_INT_SIZE === 8){
return $unpacked << 48 >> 48;
}else{
return $unpacked << 16 >> 16;
}
}else{
return $unpacked; return $unpacked;
} }
}
/** /**
* Writes a 16-bit signed/unsigned little-endian number * Writes a 16-bit signed/unsigned little-endian number
@ -285,20 +290,15 @@ class Binary{
* @return string * @return string
*/ */
public static function writeLShort($value){ public static function writeLShort($value){
if($value < 0){
$value += 0x10000;
}
return pack("v", $value); return pack("v", $value);
} }
public static function readInt($str){ public static function readInt($str){
$unpacked = @unpack("N", $str)[1]; if(PHP_INT_SIZE === 8){
if($unpacked > 2147483647){ return @unpack("N", $str)[1] << 32 >> 32;
$unpacked -= 4294967296; }else{
return @unpack("N", $str)[1];
} }
return (int) $unpacked;
} }
public static function writeInt($value){ public static function writeInt($value){
@ -306,12 +306,11 @@ class Binary{
} }
public static function readLInt($str){ public static function readLInt($str){
$unpacked = @unpack("V", $str)[1]; if(PHP_INT_SIZE === 8){
if($unpacked >= 2147483648){ return @unpack("V", $str)[1] << 32 >> 32;
$unpacked -= 4294967296; }else{
return @unpack("V", $str)[1];
} }
return (int) $unpacked;
} }
public static function writeLInt($value){ public static function writeLInt($value){
@ -354,21 +353,29 @@ class Binary{
return ENDIANNESS === self::BIG_ENDIAN ? strrev(pack("d", $value)) : pack("d", $value); return ENDIANNESS === self::BIG_ENDIAN ? strrev(pack("d", $value)) : pack("d", $value);
} }
public static function readLong($x, $signed = true){ public static function readLong($x){
if(PHP_INT_SIZE === 8){
list(, $int1, $int2) = @unpack("N*", $x);
return ($int1 << 32) | $int2;
}else{
$value = "0"; $value = "0";
for($i = 0; $i < 8; $i += 2){ for($i = 0; $i < 8; $i += 2){
$value = bcmul($value, "65536", 0); $value = bcmul($value, "65536", 0);
$value = bcadd($value, self::readShort(substr($x, $i, 2), false), 0); $value = bcadd($value, self::readShort(substr($x, $i, 2), false), 0);
} }
if($signed === true and bccomp($value, "9223372036854775807") == 1){ if(bccomp($value, "9223372036854775807") == 1){
$value = bcadd($value, "-18446744073709551616"); $value = bcadd($value, "-18446744073709551616");
} }
return $value; return $value;
} }
}
public static function writeLong($value){ public static function writeLong($value){
if(PHP_INT_SIZE === 8){
return pack("NN", $value >> 32, $value & 0xFFFFFFFF);
}else{
$x = ""; $x = "";
if(bccomp($value, "0") == -1){ if(bccomp($value, "0") == -1){
@ -382,6 +389,7 @@ class Binary{
return $x; return $x;
} }
}
public static function readLLong($str){ public static function readLLong($str){
return self::readLong(strrev($str)); return self::readLong(strrev($str));