MediaWiki REL1_33
MWMessagePack.php
Go to the documentation of this file.
1<?php
37 public static $bigendian = null;
38
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}
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two and(2) offer you this license which gives you legal permission to copy
static bool null $bigendian
Whether current system is bigendian.
static pack( $value)
Encode a value using MessagePack.
$buffer