[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MessagePack serializer 4 * 5 * MessagePack is a space-efficient binary data interchange format. This 6 * class provides a pack() method that encodes native PHP values as MessagePack 7 * binary strings. The implementation is derived from msgpack-php. 8 * 9 * Copyright (c) 2013 Ori Livneh <[email protected]> 10 * Copyright (c) 2011 OnlineCity <https://github.com/onlinecity/msgpack-php>. 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a copy 13 * of this software and associated documentation files (the "Software"), to 14 * deal in the Software without restriction, including without limitation the 15 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 * sell copies of the Software, and to permit persons to whom the Software is 17 * furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included in 20 * all copies or substantial portions of the Software. 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 27 * IN THE SOFTWARE. 28 * 29 * @see <http://msgpack.org/> 30 * @see <http://wiki.msgpack.org/display/MSGPACK/Format+specification> 31 * 32 * @since 1.23 33 * @file 34 */ 35 class MWMessagePack { 36 /** @var boolean|null Whether current system is bigendian. **/ 37 public static $bigendian = null; 38 39 /** 40 * Encode a value using MessagePack 41 * 42 * This method supports null, boolean, integer, float, string and array 43 * (both indexed and associative) types. Object serialization is not 44 * supported. 45 * 46 * @param mixed $value 47 * @return string 48 * @throws InvalidArgumentException if $value is an unsupported type or too long a string 49 */ 50 public static function pack( $value ) { 51 if ( self::$bigendian === null ) { 52 self::$bigendian = pack( 'S', 1 ) === pack( 'n', 1 ); 53 } 54 55 switch ( gettype( $value ) ) { 56 case 'NULL': 57 return "\xC0"; 58 59 case 'boolean': 60 return $value ? "\xC3" : "\xC2"; 61 62 case 'double': 63 case 'float': 64 return self::$bigendian 65 ? "\xCB" . pack( 'd', $value ) 66 : "\xCB" . strrev( pack( 'd', $value ) ); 67 68 case 'string': 69 $length = strlen( $value ); 70 if ( $length < 32 ) { 71 return pack( 'Ca*', 0xA0 | $length, $value ); 72 } elseif ( $length <= 0xFFFF ) { 73 return pack( 'Cna*', 0xDA, $length, $value ); 74 } elseif ( $length <= 0xFFFFFFFF ) { 75 return pack( 'CNa*', 0xDB, $length, $value ); 76 } 77 throw new InvalidArgumentException( __METHOD__ 78 . ": string too long (length: $length; max: 4294967295)" ); 79 80 case 'integer': 81 if ( $value >= 0 ) { 82 if ( $value <= 0x7F ) { 83 // positive fixnum 84 return chr( $value ); 85 } 86 if ( $value <= 0xFF ) { 87 // uint8 88 return pack( 'CC', 0xCC, $value ); 89 } 90 if ( $value <= 0xFFFF ) { 91 // uint16 92 return pack( 'Cn', 0xCD, $value ); 93 } 94 if ( $value <= 0xFFFFFFFF ) { 95 // uint32 96 return pack( 'CN', 0xCE, $value ); 97 } 98 if ( $value <= 0xFFFFFFFFFFFFFFFF ) { 99 // uint64 100 $hi = ( $value & 0xFFFFFFFF00000000 ) >> 32; 101 $lo = $value & 0xFFFFFFFF; 102 return self::$bigendian 103 ? pack( 'CNN', 0xCF, $lo, $hi ) 104 : pack( 'CNN', 0xCF, $hi, $lo ); 105 } 106 } else { 107 if ( $value >= -32 ) { 108 // negative fixnum 109 return pack( 'c', $value ); 110 } 111 if ( $value >= -0x80 ) { 112 // int8 113 return pack( 'Cc', 0xD0, $value ); 114 } 115 if ( $value >= -0x8000 ) { 116 // int16 117 $p = pack( 's', $value ); 118 return self::$bigendian 119 ? pack( 'Ca2', 0xD1, $p ) 120 : pack( 'Ca2', 0xD1, strrev( $p ) ); 121 } 122 if ( $value >= -0x80000000 ) { 123 // int32 124 $p = pack( 'l', $value ); 125 return self::$bigendian 126 ? pack( 'Ca4', 0xD2, $p ) 127 : pack( 'Ca4', 0xD2, strrev( $p ) ); 128 } 129 if ( $value >= -0x8000000000000000 ) { 130 // int64 131 // pack() does not support 64-bit ints either so pack into two 32-bits 132 $p1 = pack( 'l', $value & 0xFFFFFFFF ); 133 $p2 = pack( 'l', ( $value >> 32 ) & 0xFFFFFFFF ); 134 return self::$bigendian 135 ? pack( 'Ca4a4', 0xD3, $p1, $p2 ) 136 : pack( 'Ca4a4', 0xD3, strrev( $p2 ), strrev( $p1 ) ); 137 } 138 } 139 throw new InvalidArgumentException( __METHOD__ . ": invalid integer '$value'" ); 140 141 case 'array': 142 $buffer = ''; 143 $length = count( $value ); 144 if ( $length > 0xFFFFFFFF ) { 145 throw new InvalidArgumentException( __METHOD__ 146 . ": array too long (length: $length, max: 4294967295)" ); 147 } 148 149 $index = 0; 150 foreach ( $value as $k => $v ) { 151 if ( $index !== $k || $index === $length ) { 152 break; 153 } else { 154 $index++; 155 } 156 } 157 $associative = $index !== $length; 158 159 if ( $associative ) { 160 if ( $length < 16 ) { 161 $buffer .= pack( 'C', 0x80 | $length ); 162 } elseif ( $length <= 0xFFFF ) { 163 $buffer .= pack( 'Cn', 0xDE, $length ); 164 } else { 165 $buffer .= pack( 'CN', 0xDF, $length ); 166 } 167 foreach ( $value as $k => $v ) { 168 $buffer .= self::pack( $k ); 169 $buffer .= self::pack( $v ); 170 } 171 } else { 172 if ( $length < 16 ) { 173 $buffer .= pack( 'C', 0x90 | $length ); 174 } elseif ( $length <= 0xFFFF ) { 175 $buffer .= pack( 'Cn', 0xDC, $length ); 176 } else { 177 $buffer .= pack( 'CN', 0xDD, $length ); 178 } 179 foreach ( $value as $v ) { 180 $buffer .= self::pack( $v ); 181 } 182 } 183 return $buffer; 184 185 default: 186 throw new InvalidArgumentException( __METHOD__ . ': unsupported type ' . gettype( $value ) ); 187 } 188 } 189 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |