blob: 4bb02977beefa3ccc64d6e344e0e41878f8f2867 [file] [log] [blame]
Mark Slee6e536442006-06-30 18:28:50 +00001<?php
2
3/** For transport operations */
Mark Sleecfc01932006-09-01 22:18:16 +00004require_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
Marc Slemkod97eb612006-08-24 23:37:36 +000014 public function writeMessageBegin($out, $name, $type, $seqid) {
Mark Sleecfc01932006-09-01 22:18:16 +000015 return
16 $this->writeString($out, $name) +
17 $this->writeByte($out, $type) +
18 $this->writeI32($out, $seqid);
Marc Slemkod97eb612006-08-24 23:37:36 +000019 }
20
21 public function writeMessageEnd($out) {
22 return 0;
23 }
24
Mark Slee6e536442006-06-30 18:28:50 +000025 public function writeStructBegin($out, $name) {
26 return 0;
27 }
28
29 public function writeStructEnd($out) {
30 return 0;
31 }
32
33 public function writeFieldBegin($out, $fieldName, $fieldType, $fieldId) {
34 return
35 $this->writeByte($out, $fieldType) +
Marc Slemkod97eb612006-08-24 23:37:36 +000036 $this->writeI16($out, $fieldId);
Mark Slee6e536442006-06-30 18:28:50 +000037 }
38
39 public function writeFieldEnd($out) {
40 return 0;
41 }
42
43 public function writeFieldStop($out) {
44 return
45 $this->writeByte($out, TType::STOP);
46 }
47
48 public function writeMapBegin($out, $keyType, $valType, $size) {
49 return
50 $this->writeByte($out, $keyType) +
51 $this->writeByte($out, $valType) +
52 $this->writeI32($out, $size);
53 }
54
55 public function writeMapEnd($out) {
56 return 0;
57 }
58
59 public function writeListBegin($out, $elemType, $size) {
60 return
61 $this->writeByte($out, $elemType) +
62 $this->writeI32($out, $size);
63 }
64
65 public function writeListEnd($out) {
66 return 0;
67 }
68
69 public function writeSetBegin($out, $elemType, $size) {
70 return
71 $this->writeByte($out, $elemType) +
72 $this->writeI32($out, $size);
73 }
74
75 public function writeSetEnd($out) {
76 return 0;
77 }
78
Marc Slemkod97eb612006-08-24 23:37:36 +000079 public function writeBool($out, $value) {
80 $data = pack('c', $value ? 1 : 0);
Mark Slee6e536442006-06-30 18:28:50 +000081 $out->write($data, 1);
82 return 1;
83 }
84
Marc Slemkod97eb612006-08-24 23:37:36 +000085 public function writeByte($out, $value) {
86 $data = pack('c', $value);
87 $out->write($data, 1);
88 return 1;
89 }
90
Marc Slemkod97eb612006-08-24 23:37:36 +000091 public function writeI16($out, $value) {
92 $data = pack('n', $value);
93 $out->write($data, 2);
94 return 2;
95 }
96
97 public function writeI32($out, $value) {
98 $data = pack('N', $value);
Mark Slee6e536442006-06-30 18:28:50 +000099 $out->write($data, 4);
100 return 4;
101 }
102
Marc Slemkod97eb612006-08-24 23:37:36 +0000103 public function writeI64($out, $value) {
Mark Sleecfc01932006-09-01 22:18:16 +0000104 // If we are on a 32bit architecture we have to explicitly deal with
105 // 64-bit twos-complement arithmetic since PHP wants to treat all ints
106 // as signed and any int over 2^31 - 1 as a float
107 if (PHP_INT_SIZE == 4) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000108 $neg = $value < 0;
Mark Sleecfc01932006-09-01 22:18:16 +0000109
110 if ($neg) {
111 $value *= -1;
Marc Slemkod97eb612006-08-24 23:37:36 +0000112 }
Mark Sleecfc01932006-09-01 22:18:16 +0000113
Marc Slemkod97eb612006-08-24 23:37:36 +0000114 $hi = (int)($value / 4294967296);
115 $lo = (int)$value;
116
Mark Sleecfc01932006-09-01 22:18:16 +0000117 if ($neg) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000118 $hi = ~$hi;
119 $lo = ~$lo;
Mark Sleecfc01932006-09-01 22:18:16 +0000120 if (($lo & (int)0xffffffff) == (int)0xffffffff) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000121 $lo = 0;
122 $hi++;
123 } else {
124 $lo++;
125 }
126 }
Mark Slee6e536442006-06-30 18:28:50 +0000127 $data = pack('N2', $hi, $lo);
Marc Slemkod97eb612006-08-24 23:37:36 +0000128
Mark Slee6e536442006-06-30 18:28:50 +0000129 } else {
Marc Slemkod97eb612006-08-24 23:37:36 +0000130 $hi = $value >> 32;
131 $lo = $value & 0xFFFFFFFF;
132 $data = pack('N2', $hi, $lo);
Mark Slee6e536442006-06-30 18:28:50 +0000133 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000134
Mark Slee6e536442006-06-30 18:28:50 +0000135 $out->write($data, 8);
136 return 8;
137 }
138
Marc Slemkod97eb612006-08-24 23:37:36 +0000139 public function writeString($out, $value) {
140 $len = strlen($value);
Mark Sleecfc01932006-09-01 22:18:16 +0000141 $result = $this->writeI32($out, $len);
Marc Slemkod97eb612006-08-24 23:37:36 +0000142 $out->write($value, $len);
Mark Slee6e536442006-06-30 18:28:50 +0000143 return $result + $len;
144 }
145
Marc Slemkod97eb612006-08-24 23:37:36 +0000146 public function readMessageBegin($in, &$name, &$type, &$seqid) {
Mark Sleecfc01932006-09-01 22:18:16 +0000147 return
148 $this->readString($in, $name) +
149 $this->readByte($in, $type) +
150 $this->readI32($in, $seqid);
Marc Slemkod97eb612006-08-24 23:37:36 +0000151 }
152
153 public function readMessageEnd($out) {
154 return 0;
155 }
156
Mark Slee6e536442006-06-30 18:28:50 +0000157 public function readStructBegin($in, &$name) {
158 $name = '';
159 return 0;
160 }
161
162 public function readStructEnd($in) {
163 return 0;
164 }
165
166 public function readFieldBegin($in, &$name, &$fieldType, &$fieldId) {
167 $result = $this->readByte($in, $fieldType);
168 if ($fieldType == TType::STOP) {
169 $fieldId = 0;
170 return $result;
171 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000172 $result += $this->readI16($in, $fieldId);
Mark Slee6e536442006-06-30 18:28:50 +0000173 return $result;
174 }
175
176 public function readFieldEnd($in) {
177 return 0;
178 }
179
180 public function readMapBegin($in, &$keyType, &$valType, &$size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000181 return
182 $this->readByte($in, $keyType) +
183 $this->readByte($in, $valType) +
184 $this->readI32($in, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000185 }
186
187 public function readMapEnd($in) {
188 return 0;
189 }
190
191 public function readListBegin($in, &$elemType, &$size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000192 return
193 $this->readByte($in, $elemType) +
194 $this->readI32($in, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000195 }
196
197 public function readListEnd($in) {
198 return 0;
199 }
200
201 public function readSetBegin($in, &$elemType, &$size) {
Mark Sleecfc01932006-09-01 22:18:16 +0000202 return
203 $this->readByte($in, $elemType) +
204 $this->readI32($in, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000205 }
206
207 public function readSetEnd($in) {
208 return 0;
209 }
210
Marc Slemkod97eb612006-08-24 23:37:36 +0000211 public function readBool($in, &$value) {
Mark Slee6e536442006-06-30 18:28:50 +0000212 $data = $in->readAll(1);
213 $arr = unpack('c', $data);
Marc Slemkod97eb612006-08-24 23:37:36 +0000214 $value = $arr[1] == 1;
Mark Slee6e536442006-06-30 18:28:50 +0000215 return 1;
216 }
217
Marc Slemkod97eb612006-08-24 23:37:36 +0000218 public function readByte($in, &$value) {
219 $data = $in->readAll(1);
220 $arr = unpack('c', $data);
221 $value = $arr[1];
222 return 1;
223 }
224
Marc Slemkod97eb612006-08-24 23:37:36 +0000225 public function readI16($in, &$value) {
226 $data = $in->readAll(2);
227 $arr = unpack('n', $data);
228 $value = $arr[1];
Mark Sleecfc01932006-09-01 22:18:16 +0000229 if ($value > 0x7fff) {
230 $value = 0 - (($value - 1) ^ 0xffff);
Mark Slee6e536442006-06-30 18:28:50 +0000231 }
Marc Slemkod97eb612006-08-24 23:37:36 +0000232 return 2;
233 }
234
235 public function readI32($in, &$value) {
236 $data = $in->readAll(4);
237 $arr = unpack('N', $data);
238 $value = $arr[1];
Mark Sleecfc01932006-09-01 22:18:16 +0000239 if ($value > 0x7fffffff) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000240 $value = 0 - (($value - 1) ^ 0xffffffff);
241 }
Mark Slee6e536442006-06-30 18:28:50 +0000242 return 4;
243 }
244
Marc Slemkod97eb612006-08-24 23:37:36 +0000245 public function readI64($in, &$value) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000246 $data = $in->readAll(8);
247
248 $arr = unpack('N2', $data);
249
Mark Sleecfc01932006-09-01 22:18:16 +0000250 // If we are on a 32bit architecture we have to explicitly deal with
251 // 64-bit twos-complement arithmetic since PHP wants to treat all ints
252 // as signed and any int over 2^31 - 1 as a float
253 if (PHP_INT_SIZE == 4) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000254
255 $hi = $arr[1];
256 $lo = $arr[2];
257 $isNeg = $hi < 0;
258
259 // Check for a negative
Mark Sleecfc01932006-09-01 22:18:16 +0000260 if ($isNeg) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000261 $hi = ~$hi & (int)0xffffffff;
262 $lo = ~$lo & (int)0xffffffff;
263
Mark Sleecfc01932006-09-01 22:18:16 +0000264 if ($lo == (int)0xffffffff) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000265 $hi++;
266 $lo = 0;
267 } else {
268 $lo++;
269 }
270 }
271
Mark Sleecfc01932006-09-01 22:18:16 +0000272 // Force 32bit words in excess of 2G to pe positive - we deal wigh sign
273 // explicitly below
Marc Slemkod97eb612006-08-24 23:37:36 +0000274
Mark Sleecfc01932006-09-01 22:18:16 +0000275 if ($hi & (int)0x80000000) {
276 $hi &= (int)0x7fffffff;
Marc Slemkod97eb612006-08-24 23:37:36 +0000277 $hi += 0x80000000;
278 }
279
Mark Sleecfc01932006-09-01 22:18:16 +0000280 if ($lo & (int)0x80000000) {
281 $lo &= (int)0x7fffffff;
Marc Slemkod97eb612006-08-24 23:37:36 +0000282 $lo += 0x80000000;
283 }
284
285 $value = $hi * 4294967296 + $lo;
286
Mark Sleecfc01932006-09-01 22:18:16 +0000287 if ($isNeg) {
Marc Slemkod97eb612006-08-24 23:37:36 +0000288 $value = 0 - $value;
289 }
290 } else {
291
292 // Check for a negative
293 if ($arr[1] & 0x80000000) {
294 $arr[1] = $arr[1] ^ 0xFFFFFFFF;
295 $arr[2] = $arr[2] ^ 0xFFFFFFFF;
296 $value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
297 } else {
298 $value = $arr[1]*4294967296 + $arr[2];
299 }
300 }
301
302 return 8;
303 }
304
Marc Slemkod97eb612006-08-24 23:37:36 +0000305 public function readString($in, &$value) {
Mark Sleecfc01932006-09-01 22:18:16 +0000306 $result = $this->readI32($in, $len);
Marc Slemkod97eb612006-08-24 23:37:36 +0000307 $value = $in->readAll($len);
Mark Slee6e536442006-06-30 18:28:50 +0000308 return $result + $len;
309 }
310}
311
Marc Slemkod97eb612006-08-24 23:37:36 +0000312?>