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;
}
protected function getLong($signed = true){
return Binary::readLong($this->get(8), $signed);
protected function getLong(){
return Binary::readLong($this->get(8));
}
protected function putLong($v){

View File

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