* @file
*/
class MWMessagePack {
- /** @var boolean|null Whether current system is bigendian. **/
+ /** @var bool|null Whether current system is bigendian. **/
public static $bigendian = null;
/**
}
switch ( gettype( $value ) ) {
- case 'NULL':
- return "\xC0";
+ case 'NULL':
+ return "\xC0";
- case 'boolean':
- return $value ? "\xC3" : "\xC2";
+ case 'boolean':
+ return $value ? "\xC3" : "\xC2";
- case 'double':
- case 'float':
- return self::$bigendian
- ? "\xCB" . pack( 'd', $value )
- : "\xCB" . strrev( pack( 'd', $value ) );
+ case 'double':
+ case 'float':
+ return self::$bigendian
+ ? "\xCB" . pack( 'd', $value )
+ : "\xCB" . strrev( pack( 'd', $value ) );
- case 'string':
- $length = strlen( $value );
- if ( $length < 32 ) {
- return pack( 'Ca*', 0xA0 | $length, $value );
- } elseif ( $length <= 0xFFFF ) {
- return pack( 'Cna*', 0xDA, $length, $value );
- } elseif ( $length <= 0xFFFFFFFF ) {
- return pack( 'CNa*', 0xDB, $length, $value );
- }
- throw new InvalidArgumentException( __METHOD__
- . ": string too long (length: $length; max: 4294967295)" );
-
- case 'integer':
- if ( $value >= 0 ) {
- if ( $value <= 0x7F ) {
- // positive fixnum
- return chr( $value );
- }
- if ( $value <= 0xFF ) {
- // uint8
- return pack( 'CC', 0xCC, $value );
- }
- if ( $value <= 0xFFFF ) {
- // uint16
- return pack( 'Cn', 0xCD, $value );
- }
- if ( $value <= 0xFFFFFFFF ) {
- // uint32
- return pack( 'CN', 0xCE, $value );
- }
- if ( $value <= 0xFFFFFFFFFFFFFFFF ) {
- // uint64
- $hi = ( $value & 0xFFFFFFFF00000000 ) >> 32;
- $lo = $value & 0xFFFFFFFF;
- return self::$bigendian
- ? pack( 'CNN', 0xCF, $lo, $hi )
- : pack( 'CNN', 0xCF, $hi, $lo );
- }
- } else {
- if ( $value >= -32 ) {
- // negative fixnum
- return pack( 'c', $value );
- }
- if ( $value >= -0x80 ) {
- // int8
- return pack( 'Cc', 0xD0, $value );
- }
- if ( $value >= -0x8000 ) {
- // int16
- $p = pack( 's', $value );
- return self::$bigendian
- ? pack( 'Ca2', 0xD1, $p )
- : pack( 'Ca2', 0xD1, strrev( $p ) );
- }
- if ( $value >= -0x80000000 ) {
- // int32
- $p = pack( 'l', $value );
- return self::$bigendian
- ? pack( 'Ca4', 0xD2, $p )
- : pack( 'Ca4', 0xD2, strrev( $p ) );
- }
- if ( $value >= -0x8000000000000000 ) {
- // int64
- // pack() does not support 64-bit ints either so pack into two 32-bits
- $p1 = pack( 'l', $value & 0xFFFFFFFF );
- $p2 = pack( 'l', ( $value >> 32 ) & 0xFFFFFFFF );
- return self::$bigendian
- ? pack( 'Ca4a4', 0xD3, $p1, $p2 )
- : pack( 'Ca4a4', 0xD3, strrev( $p2 ), strrev( $p1 ) );
+ case 'string':
+ $length = strlen( $value );
+ if ( $length < 32 ) {
+ return pack( 'Ca*', 0xA0 | $length, $value );
+ } elseif ( $length <= 0xFFFF ) {
+ return pack( 'Cna*', 0xDA, $length, $value );
+ } elseif ( $length <= 0xFFFFFFFF ) {
+ return pack( 'CNa*', 0xDB, $length, $value );
}
- }
- throw new InvalidArgumentException( __METHOD__ . ": invalid integer '$value'" );
-
- case 'array':
- $buffer = '';
- $length = count( $value );
- if ( $length > 0xFFFFFFFF ) {
throw new InvalidArgumentException( __METHOD__
- . ": array too long (length: $length, max: 4294967295)" );
- }
+ . ": string too long (length: $length; max: 4294967295)" );
- $index = 0;
- foreach ( $value as $k => $v ) {
- if ( $index !== $k || $index === $length ) {
- break;
+ case 'integer':
+ if ( $value >= 0 ) {
+ if ( $value <= 0x7F ) {
+ // positive fixnum
+ return chr( $value );
+ }
+ if ( $value <= 0xFF ) {
+ // uint8
+ return pack( 'CC', 0xCC, $value );
+ }
+ if ( $value <= 0xFFFF ) {
+ // uint16
+ return pack( 'Cn', 0xCD, $value );
+ }
+ if ( $value <= 0xFFFFFFFF ) {
+ // uint32
+ return pack( 'CN', 0xCE, $value );
+ }
+ if ( $value <= 0xFFFFFFFFFFFFFFFF ) {
+ // uint64
+ $hi = ( $value & 0xFFFFFFFF00000000 ) >> 32;
+ $lo = $value & 0xFFFFFFFF;
+ return self::$bigendian
+ ? pack( 'CNN', 0xCF, $lo, $hi )
+ : pack( 'CNN', 0xCF, $hi, $lo );
+ }
} else {
- $index++;
+ if ( $value >= -32 ) {
+ // negative fixnum
+ return pack( 'c', $value );
+ }
+ if ( $value >= -0x80 ) {
+ // int8
+ return pack( 'Cc', 0xD0, $value );
+ }
+ if ( $value >= -0x8000 ) {
+ // int16
+ $p = pack( 's', $value );
+ return self::$bigendian
+ ? pack( 'Ca2', 0xD1, $p )
+ : pack( 'Ca2', 0xD1, strrev( $p ) );
+ }
+ if ( $value >= -0x80000000 ) {
+ // int32
+ $p = pack( 'l', $value );
+ return self::$bigendian
+ ? pack( 'Ca4', 0xD2, $p )
+ : pack( 'Ca4', 0xD2, strrev( $p ) );
+ }
+ if ( $value >= -0x8000000000000000 ) {
+ // int64
+ // pack() does not support 64-bit ints either so pack into two 32-bits
+ $p1 = pack( 'l', $value & 0xFFFFFFFF );
+ $p2 = pack( 'l', ( $value >> 32 ) & 0xFFFFFFFF );
+ return self::$bigendian
+ ? pack( 'Ca4a4', 0xD3, $p1, $p2 )
+ : pack( 'Ca4a4', 0xD3, strrev( $p2 ), strrev( $p1 ) );
+ }
}
- }
- $associative = $index !== $length;
+ throw new InvalidArgumentException( __METHOD__ . ": invalid integer '$value'" );
- if ( $associative ) {
- if ( $length < 16 ) {
- $buffer .= pack( 'C', 0x80 | $length );
- } elseif ( $length <= 0xFFFF ) {
- $buffer .= pack( 'Cn', 0xDE, $length );
- } else {
- $buffer .= pack( 'CN', 0xDF, $length );
+ case 'array':
+ $buffer = '';
+ $length = count( $value );
+ if ( $length > 0xFFFFFFFF ) {
+ throw new InvalidArgumentException( __METHOD__
+ . ": array too long (length: $length, max: 4294967295)" );
}
+
+ $index = 0;
foreach ( $value as $k => $v ) {
- $buffer .= self::pack( $k );
- $buffer .= self::pack( $v );
+ if ( $index !== $k || $index === $length ) {
+ break;
+ } else {
+ $index++;
+ }
}
- } else {
- if ( $length < 16 ) {
- $buffer .= pack( 'C', 0x90 | $length );
- } elseif ( $length <= 0xFFFF ) {
- $buffer .= pack( 'Cn', 0xDC, $length );
+ $associative = $index !== $length;
+
+ if ( $associative ) {
+ if ( $length < 16 ) {
+ $buffer .= pack( 'C', 0x80 | $length );
+ } elseif ( $length <= 0xFFFF ) {
+ $buffer .= pack( 'Cn', 0xDE, $length );
+ } else {
+ $buffer .= pack( 'CN', 0xDF, $length );
+ }
+ foreach ( $value as $k => $v ) {
+ $buffer .= self::pack( $k );
+ $buffer .= self::pack( $v );
+ }
} else {
- $buffer .= pack( 'CN', 0xDD, $length );
- }
- foreach ( $value as $v ) {
- $buffer .= self::pack( $v );
+ if ( $length < 16 ) {
+ $buffer .= pack( 'C', 0x90 | $length );
+ } elseif ( $length <= 0xFFFF ) {
+ $buffer .= pack( 'Cn', 0xDC, $length );
+ } else {
+ $buffer .= pack( 'CN', 0xDD, $length );
+ }
+ foreach ( $value as $v ) {
+ $buffer .= self::pack( $v );
+ }
}
- }
- return $buffer;
+ return $buffer;
- default:
- throw new InvalidArgumentException( __METHOD__ . ': unsupported type ' . gettype( $value ) );
+ default:
+ throw new InvalidArgumentException( __METHOD__ . ': unsupported type ' . gettype( $value ) );
}
}
}