blob: e9ea3b86b2ddc78b168d4f0d31c5cbb9d6109f19 [file] [log] [blame]
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +00001<?php
Mark Slee6e536442006-06-30 18:28:50 +00002
3/** For transport operations */
Mark Slee1c4a5592006-09-25 21:32:05 +00004include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php';
Mark Slee6e536442006-06-30 18:28:50 +00005
6/**
7 * Binary implementation of the Thrift protocol.
8 *
9 * @package thrift.protocol
10 * @author Mark Slee <mcslee@facebook.com>
11 */
12class TBinaryProtocol extends TProtocol {
13
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000014 public function __construct($trans) {
15 parent::__construct($trans);
Mark Slee5f8237d2006-10-26 04:57:03 +000016 }
17
18 public function writeMessageBegin($name, $type, $seqid) {
Mark Sleecfc01932006-09-01 22:18:16 +000019 return
Mark Slee5f8237d2006-10-26 04:57:03 +000020 $this->writeString($name) +
21 $this->writeByte($type) +
22 $this->writeI32($seqid);
Marc Slemkod97eb612006-08-24 23:37:36 +000023 }
24
Mark Slee5f8237d2006-10-26 04:57:03 +000025 public function writeMessageEnd() {
Marc Slemkod97eb612006-08-24 23:37:36 +000026 return 0;
27 }
28
Mark Slee5f8237d2006-10-26 04:57:03 +000029 public function writeStructBegin($name) {
Mark Slee6e536442006-06-30 18:28:50 +000030 return 0;
31 }
32
Mark Slee5f8237d2006-10-26 04:57:03 +000033 public function writeStructEnd() {
Mark Slee6e536442006-06-30 18:28:50 +000034 return 0;
35 }
36
Mark Slee5f8237d2006-10-26 04:57:03 +000037 public function writeFieldBegin($fieldName, $fieldType, $fieldId) {
Mark Slee6e536442006-06-30 18:28:50 +000038 return
Mark Slee5f8237d2006-10-26 04:57:03 +000039 $this->writeByte($fieldType) +
40 $this->writeI16($fieldId);
Mark Slee6e536442006-06-30 18:28:50 +000041 }
42
Mark Slee5f8237d2006-10-26 04:57:03 +000043 public function writeFieldEnd() {
Mark Slee6e536442006-06-30 18:28:50 +000044 return 0;
45 }
46
Mark Slee5f8237d2006-10-26 04:57:03 +000047 public function writeFieldStop() {
Mark Slee6e536442006-06-30 18:28:50 +000048 return
Mark Slee5f8237d2006-10-26 04:57:03 +000049 $this->writeByte(TType::STOP);
Mark Slee6e536442006-06-30 18:28:50 +000050 }
51
Mark Slee5f8237d2006-10-26 04:57:03 +000052 public function writeMapBegin($keyType, $valType, $size) {
Mark Slee6e536442006-06-30 18:28:50 +000053 return
Mark Slee5f8237d2006-10-26 04:57:03 +000054 $this->writeByte($keyType) +
55 $this->writeByte($valType) +
56 $this->writeI32($size);
Mark Slee6e536442006-06-30 18:28:50 +000057 }
58
Mark Slee5f8237d2006-10-26 04:57:03 +000059 public function writeMapEnd() {
Mark Slee6e536442006-06-30 18:28:50 +000060 return 0;
61 }
62
Mark Slee5f8237d2006-10-26 04:57:03 +000063 public function writeListBegin($elemType, $size) {
Mark Slee6e536442006-06-30 18:28:50 +000064 return
Mark Slee5f8237d2006-10-26 04:57:03 +000065 $this->writeByte($elemType) +
66 $this->writeI32($size);
Mark Slee6e536442006-06-30 18:28:50 +000067 }
68
Mark Slee5f8237d2006-10-26 04:57:03 +000069 public function writeListEnd() {
Mark Slee6e536442006-06-30 18:28:50 +000070 return 0;
71 }
72
Mark Slee5f8237d2006-10-26 04:57:03 +000073 public function writeSetBegin($elemType, $size) {
Mark Slee6e536442006-06-30 18:28:50 +000074 return
Mark Slee5f8237d2006-10-26 04:57:03 +000075 $this->writeByte($elemType) +
76 $this->writeI32($size);
Mark Slee6e536442006-06-30 18:28:50 +000077 }
78
Mark Slee5f8237d2006-10-26 04:57:03 +000079 public function writeSetEnd() {
Mark Slee6e536442006-06-30 18:28:50 +000080 return 0;
81 }
82
Mark Slee5f8237d2006-10-26 04:57:03 +000083 public function writeBool($value) {
Marc Slemkod97eb612006-08-24 23:37:36 +000084 $data = pack('c', $value ? 1 : 0);
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000085 $this->trans_->write($data, 1);
Mark Slee6e536442006-06-30 18:28:50 +000086 return 1;
87 }
88
Mark Slee5f8237d2006-10-26 04:57:03 +000089 public function writeByte($value) {
Marc Slemkod97eb612006-08-24 23:37:36 +000090 $data = pack('c', $value);
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000091 $this->trans_->write($data, 1);
Marc Slemkod97eb612006-08-24 23:37:36 +000092 return 1;
93 }
94
Mark Slee5f8237d2006-10-26 04:57:03 +000095 public function writeI16($value) {
Marc Slemkod97eb612006-08-24 23:37:36 +000096 $data = pack('n', $value);
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000097 $this->trans_->write($data, 2);
Marc Slemkod97eb612006-08-24 23:37:36 +000098 return 2;
99 }
100
Mark Slee5f8237d2006-10-26 04:57:03 +0000101 public function writeI32($value) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000102 $data = pack('N', $value);
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000103 $this->trans_->write($data, 4);
Mark Slee6e536442006-06-30 18:28:50 +0000104 return 4;
105 }
106
Mark Slee5f8237d2006-10-26 04:57:03 +0000107 public function writeI64($value) {
Mark Sleecfc01932006-09-01 22:18:16 +0000108 // If we are on a 32bit architecture we have to explicitly deal with
109 // 64-bit twos-complement arithmetic since PHP wants to treat all ints
110 // as signed and any int over 2^31 - 1 as a float
111 if (PHP_INT_SIZE == 4) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000112 $neg = $value < 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000113
114 if ($neg) {
115 $value *= -1;
Marc Slemkod97eb612006-08-24 23:37:36 +0000116 }
Mark Sleecfc01932006-09-01 22:18:16 +0000117
Marc Slemkod97eb612006-08-24 23:37:36 +0000118 $hi = (int)($value / 4294967296);
119 $lo = (int)$value;
120
Mark Sleecfc01932006-09-01 22:18:16 +0000121 if ($neg) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000122 $hi = ~$hi;
123 $lo = ~$lo;
Mark Sleecfc01932006-09-01 22:18:16 +0000124 if (($lo & (int)0xffffffff) == (int)0xffffffff) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000125 $lo = 0;
126 $hi++;
127 } else {
128 $lo++;
129 }
130 }
Mark Slee6e536442006-06-30 18:28:50 +0000131 $data = pack('N2', $hi, $lo);
Marc Slemkod97eb612006-08-24 23:37:36 +0000132
Mark Slee6e536442006-06-30 18:28:50 +0000133 } else {
Marc Slemkod97eb612006-08-24 23:37:36 +0000134 $hi = $value >> 32;
135 $lo = $value & 0xFFFFFFFF;
136 $data = pack('N2', $hi, $lo);
Mark Slee6e536442006-06-30 18:28:50 +0000137 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000138
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000139 $this->trans_->write($data, 8);
Mark Slee6e536442006-06-30 18:28:50 +0000140 return 8;
141 }
142
Mark Slee5f8237d2006-10-26 04:57:03 +0000143 public function writeDouble($value) {
Mark Sleec98d0502006-09-06 02:42:25 +0000144 $data = pack('d', $value);
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000145 $this->trans_->write(strrev($data), 8);
Mark Sleec98d0502006-09-06 02:42:25 +0000146 return 8;
147 }
148
Mark Slee5f8237d2006-10-26 04:57:03 +0000149 public function writeString($value) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000150 $len = strlen($value);
Mark Slee5f8237d2006-10-26 04:57:03 +0000151 $result = $this->writeI32($len);
Mark Sleeade2c832006-09-08 03:41:50 +0000152 if ($len) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000153 $this->trans_->write($value, $len);
Mark Sleeade2c832006-09-08 03:41:50 +0000154 }
Mark Slee6e536442006-06-30 18:28:50 +0000155 return $result + $len;
156 }
157
Mark Slee5f8237d2006-10-26 04:57:03 +0000158 public function readMessageBegin(&$name, &$type, &$seqid) {
Mark Sleecfc01932006-09-01 22:18:16 +0000159 return
Mark Slee5f8237d2006-10-26 04:57:03 +0000160 $this->readString($name) +
161 $this->readByte($type) +
162 $this->readI32($seqid);
Marc Slemkod97eb612006-08-24 23:37:36 +0000163 }
164
Mark Slee5f8237d2006-10-26 04:57:03 +0000165 public function readMessageEnd() {
Marc Slemkod97eb612006-08-24 23:37:36 +0000166 return 0;
167 }
168
Mark Slee5f8237d2006-10-26 04:57:03 +0000169 public function readStructBegin(&$name) {
Mark Slee6e536442006-06-30 18:28:50 +0000170 $name = '';
171 return 0;
172 }
173
Mark Slee5f8237d2006-10-26 04:57:03 +0000174 public function readStructEnd() {
Mark Slee6e536442006-06-30 18:28:50 +0000175 return 0;
176 }
177
Mark Slee5f8237d2006-10-26 04:57:03 +0000178 public function readFieldBegin(&$name, &$fieldType, &$fieldId) {
179 $result = $this->readByte($fieldType);
Mark Slee6e536442006-06-30 18:28:50 +0000180 if ($fieldType == TType::STOP) {
181 $fieldId = 0;
182 return $result;
183 }
Mark Slee5f8237d2006-10-26 04:57:03 +0000184 $result += $this->readI16($fieldId);
Mark Slee6e536442006-06-30 18:28:50 +0000185 return $result;
186 }
187
Mark Slee5f8237d2006-10-26 04:57:03 +0000188 public function readFieldEnd() {
Mark Slee6e536442006-06-30 18:28:50 +0000189 return 0;
190 }
191
Mark Slee5f8237d2006-10-26 04:57:03 +0000192 public function readMapBegin(&$keyType, &$valType, &$size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000193 return
Mark Slee5f8237d2006-10-26 04:57:03 +0000194 $this->readByte($keyType) +
195 $this->readByte($valType) +
196 $this->readI32($size);
Mark Slee6e536442006-06-30 18:28:50 +0000197 }
198
Mark Slee5f8237d2006-10-26 04:57:03 +0000199 public function readMapEnd() {
Mark Slee6e536442006-06-30 18:28:50 +0000200 return 0;
201 }
202
Mark Slee5f8237d2006-10-26 04:57:03 +0000203 public function readListBegin(&$elemType, &$size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000204 return
Mark Slee5f8237d2006-10-26 04:57:03 +0000205 $this->readByte($elemType) +
206 $this->readI32($size);
Mark Slee6e536442006-06-30 18:28:50 +0000207 }
208
Mark Slee5f8237d2006-10-26 04:57:03 +0000209 public function readListEnd() {
Mark Slee6e536442006-06-30 18:28:50 +0000210 return 0;
211 }
212
Mark Slee5f8237d2006-10-26 04:57:03 +0000213 public function readSetBegin(&$elemType, &$size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000214 return
Mark Slee5f8237d2006-10-26 04:57:03 +0000215 $this->readByte($elemType) +
216 $this->readI32($size);
Mark Slee6e536442006-06-30 18:28:50 +0000217 }
218
Mark Slee5f8237d2006-10-26 04:57:03 +0000219 public function readSetEnd() {
Mark Slee6e536442006-06-30 18:28:50 +0000220 return 0;
221 }
222
Mark Slee5f8237d2006-10-26 04:57:03 +0000223 public function readBool(&$value) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000224 $data = $this->trans_->readAll(1);
Mark Slee6e536442006-06-30 18:28:50 +0000225 $arr = unpack('c', $data);
Marc Slemkod97eb612006-08-24 23:37:36 +0000226 $value = $arr[1] == 1;
Mark Slee6e536442006-06-30 18:28:50 +0000227 return 1;
228 }
229
Mark Slee5f8237d2006-10-26 04:57:03 +0000230 public function readByte(&$value) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000231 $data = $this->trans_->readAll(1);
Marc Slemkod97eb612006-08-24 23:37:36 +0000232 $arr = unpack('c', $data);
233 $value = $arr[1];
234 return 1;
235 }
236
Mark Slee5f8237d2006-10-26 04:57:03 +0000237 public function readI16(&$value) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000238 $data = $this->trans_->readAll(2);
Marc Slemkod97eb612006-08-24 23:37:36 +0000239 $arr = unpack('n', $data);
240 $value = $arr[1];
Mark Sleecfc01932006-09-01 22:18:16 +0000241 if ($value > 0x7fff) {
242 $value = 0 - (($value - 1) ^ 0xffff);
Mark Slee6e536442006-06-30 18:28:50 +0000243 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000244 return 2;
245 }
246
Mark Slee5f8237d2006-10-26 04:57:03 +0000247 public function readI32(&$value) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000248 $data = $this->trans_->readAll(4);
Marc Slemkod97eb612006-08-24 23:37:36 +0000249 $arr = unpack('N', $data);
250 $value = $arr[1];
Mark Sleecfc01932006-09-01 22:18:16 +0000251 if ($value > 0x7fffffff) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000252 $value = 0 - (($value - 1) ^ 0xffffffff);
253 }
Mark Slee6e536442006-06-30 18:28:50 +0000254 return 4;
255 }
256
Mark Slee5f8237d2006-10-26 04:57:03 +0000257 public function readI64(&$value) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000258 $data = $this->trans_->readAll(8);
Marc Slemkod97eb612006-08-24 23:37:36 +0000259
260 $arr = unpack('N2', $data);
261
Mark Sleecfc01932006-09-01 22:18:16 +0000262 // If we are on a 32bit architecture we have to explicitly deal with
263 // 64-bit twos-complement arithmetic since PHP wants to treat all ints
264 // as signed and any int over 2^31 - 1 as a float
265 if (PHP_INT_SIZE == 4) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000266
267 $hi = $arr[1];
268 $lo = $arr[2];
269 $isNeg = $hi < 0;
270
271 // Check for a negative
Mark Sleecfc01932006-09-01 22:18:16 +0000272 if ($isNeg) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000273 $hi = ~$hi & (int)0xffffffff;
274 $lo = ~$lo & (int)0xffffffff;
275
Mark Sleecfc01932006-09-01 22:18:16 +0000276 if ($lo == (int)0xffffffff) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000277 $hi++;
278 $lo = 0;
279 } else {
280 $lo++;
281 }
282 }
283
Mark Sleecfc01932006-09-01 22:18:16 +0000284 // Force 32bit words in excess of 2G to pe positive - we deal wigh sign
285 // explicitly below
Marc Slemkod97eb612006-08-24 23:37:36 +0000286
Mark Sleecfc01932006-09-01 22:18:16 +0000287 if ($hi & (int)0x80000000) {
288 $hi &= (int)0x7fffffff;
Marc Slemkod97eb612006-08-24 23:37:36 +0000289 $hi += 0x80000000;
290 }
291
Mark Sleecfc01932006-09-01 22:18:16 +0000292 if ($lo & (int)0x80000000) {
293 $lo &= (int)0x7fffffff;
Marc Slemkod97eb612006-08-24 23:37:36 +0000294 $lo += 0x80000000;
295 }
296
297 $value = $hi * 4294967296 + $lo;
298
Mark Sleecfc01932006-09-01 22:18:16 +0000299 if ($isNeg) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000300 $value = 0 - $value;
301 }
302 } else {
303
304 // Check for a negative
305 if ($arr[1] & 0x80000000) {
306 $arr[1] = $arr[1] ^ 0xFFFFFFFF;
307 $arr[2] = $arr[2] ^ 0xFFFFFFFF;
308 $value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
309 } else {
310 $value = $arr[1]*4294967296 + $arr[2];
311 }
312 }
313
314 return 8;
315 }
316
Mark Slee5f8237d2006-10-26 04:57:03 +0000317 public function readDouble(&$value) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000318 $data = strrev($this->trans_->readAll(8));
Mark Sleec98d0502006-09-06 02:42:25 +0000319 $arr = unpack('d', $data);
320 $value = $arr[1];
321 return 8;
322 }
323
Mark Slee5f8237d2006-10-26 04:57:03 +0000324 public function readString(&$value) {
325 $result = $this->readI32($len);
Mark Sleeade2c832006-09-08 03:41:50 +0000326 if ($len) {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000327 $value = $this->trans_->readAll($len);
Mark Sleeade2c832006-09-08 03:41:50 +0000328 } else {
329 $value = '';
330 }
Mark Slee6e536442006-06-30 18:28:50 +0000331 return $result + $len;
332 }
333}
334
Mark Slee5f8237d2006-10-26 04:57:03 +0000335/**
336 * Binary Protocol Factory
337 */
338class TBinaryProtocolFactory implements TProtocolFactory {
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000339 public function getProtocol($trans) {
340 return new TBinaryProtocol($trans);
Mark Slee5f8237d2006-10-26 04:57:03 +0000341 }
342}
343
Marc Slemkod97eb612006-08-24 23:37:36 +0000344?>