blob: ac1facde491bc5c240cdd401261be8509a49cf9c [file] [log] [blame]
Mark Slee6e536442006-06-30 18:28:50 +00001<?php
David Reissea2cba82009-03-30 21:35:00 +00002/*
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
Mark Slee4902c052007-03-01 00:31:30 +000010 *
David Reissea2cba82009-03-30 21:35:00 +000011 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
Mark Slee4902c052007-03-01 00:31:30 +000019 *
20 * @package thrift.protocol
Mark Slee4902c052007-03-01 00:31:30 +000021 */
22
David Reissea2cba82009-03-30 21:35:00 +000023
Mark Slee4902c052007-03-01 00:31:30 +000024/**
Mark Slee5f8237d2006-10-26 04:57:03 +000025 * Protocol module. Contains all the types and definitions needed to implement
26 * a protocol encoder/decoder.
Mark Slee6e536442006-06-30 18:28:50 +000027 *
28 * @package thrift.protocol
Mark Slee6e536442006-06-30 18:28:50 +000029 */
Mark Slee5f8237d2006-10-26 04:57:03 +000030
Mark Slee5f8237d2006-10-26 04:57:03 +000031/**
Mark Sleedac78562007-02-21 07:35:03 +000032 * Protocol exceptions
33 */
34class TProtocolException extends TException {
35 const UNKNOWN = 0;
36 const INVALID_DATA = 1;
37 const NEGATIVE_SIZE = 2;
38 const SIZE_LIMIT = 3;
Mark Slee808454e2007-06-20 21:51:57 +000039 const BAD_VERSION = 4;
Mark Sleedac78562007-02-21 07:35:03 +000040
41 function __construct($message=null, $code=0) {
42 parent::__construct($message, $code);
43 }
44}
45
46/**
Mark Slee5f8237d2006-10-26 04:57:03 +000047 * Protocol base class module.
48 */
Mark Slee6e536442006-06-30 18:28:50 +000049abstract class TProtocol {
Mark Slee97264862007-12-20 03:23:27 +000050 // The below may seem silly, but it is to get around the problem that the
51 // "instanceof" operator can only take in a T_VARIABLE and not a T_STRING
52 // or T_CONSTANT_ENCAPSED_STRING. Using "is_a()" instead of "instanceof" is
53 // a workaround but is deprecated in PHP5. This is used in the generated
54 // deserialization code.
55 static $TBINARYPROTOCOLACCELERATED = 'TBinaryProtocolAccelerated';
Mark Slee6e536442006-06-30 18:28:50 +000056
Mark Slee5f8237d2006-10-26 04:57:03 +000057 /**
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000058 * Underlying transport
Mark Slee5f8237d2006-10-26 04:57:03 +000059 *
60 * @var TTransport
61 */
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000062 protected $trans_;
Mark Slee5f8237d2006-10-26 04:57:03 +000063
64 /**
65 * Constructor
66 */
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000067 protected function __construct($trans) {
68 $this->trans_ = $trans;
Mark Slee5f8237d2006-10-26 04:57:03 +000069 }
70
71 /**
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000072 * Accessor for transport
Mark Slee5f8237d2006-10-26 04:57:03 +000073 *
74 * @return TTransport
75 */
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +000076 public function getTransport() {
77 return $this->trans_;
Mark Slee5f8237d2006-10-26 04:57:03 +000078 }
79
Mark Slee97264862007-12-20 03:23:27 +000080 /**
Mark Sleecfc01932006-09-01 22:18:16 +000081 * Writes the message header
82 *
Mark Sleecfc01932006-09-01 22:18:16 +000083 * @param string $name Function name
84 * @param int $type message type TMessageType::CALL or TMessageType::REPLY
85 * @param int $seqid The sequence id of this message
86 */
Mark Slee5f8237d2006-10-26 04:57:03 +000087 public abstract function writeMessageBegin($name, $type, $seqid);
Marc Slemkod97eb612006-08-24 23:37:36 +000088
Mark Sleecfc01932006-09-01 22:18:16 +000089 /**
90 * Close the message
Mark Sleecfc01932006-09-01 22:18:16 +000091 */
Mark Slee5f8237d2006-10-26 04:57:03 +000092 public abstract function writeMessageEnd();
Marc Slemkod97eb612006-08-24 23:37:36 +000093
Mark Slee6e536442006-06-30 18:28:50 +000094 /**
95 * Writes a struct header.
96 *
Mark Slee6e536442006-06-30 18:28:50 +000097 * @param string $name Struct name
98 * @throws TException on write error
99 * @return int How many bytes written
100 */
Mark Slee5f8237d2006-10-26 04:57:03 +0000101 public abstract function writeStructBegin($name);
Mark Slee6e536442006-06-30 18:28:50 +0000102
103 /**
104 * Close a struct.
105 *
Mark Slee6e536442006-06-30 18:28:50 +0000106 * @throws TException on write error
107 * @return int How many bytes written
108 */
Mark Slee5f8237d2006-10-26 04:57:03 +0000109 public abstract function writeStructEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000110
111 /*
112 * Starts a field.
113 *
Mark Slee6e536442006-06-30 18:28:50 +0000114 * @param string $name Field name
115 * @param int $type Field type
116 * @param int $fid Field id
117 * @throws TException on write error
118 * @return int How many bytes written
119 */
Mark Slee5f8237d2006-10-26 04:57:03 +0000120 public abstract function writeFieldBegin($fieldName, $fieldType, $fieldId);
Mark Slee6e536442006-06-30 18:28:50 +0000121
Mark Slee5f8237d2006-10-26 04:57:03 +0000122 public abstract function writeFieldEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000123
Mark Slee5f8237d2006-10-26 04:57:03 +0000124 public abstract function writeFieldStop();
Mark Slee6e536442006-06-30 18:28:50 +0000125
Mark Slee5f8237d2006-10-26 04:57:03 +0000126 public abstract function writeMapBegin($keyType, $valType, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000127
Mark Slee5f8237d2006-10-26 04:57:03 +0000128 public abstract function writeMapEnd();
Mark Slee97264862007-12-20 03:23:27 +0000129
Mark Slee5f8237d2006-10-26 04:57:03 +0000130 public abstract function writeListBegin($elemType, $size);
Mark Slee97264862007-12-20 03:23:27 +0000131
Mark Slee5f8237d2006-10-26 04:57:03 +0000132 public abstract function writeListEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000133
Mark Slee5f8237d2006-10-26 04:57:03 +0000134 public abstract function writeSetBegin($elemType, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000135
Mark Slee5f8237d2006-10-26 04:57:03 +0000136 public abstract function writeSetEnd();
Mark Slee97264862007-12-20 03:23:27 +0000137
Mark Slee5f8237d2006-10-26 04:57:03 +0000138 public abstract function writeBool($bool);
Mark Slee78f58e22006-09-02 04:17:07 +0000139
Mark Slee5f8237d2006-10-26 04:57:03 +0000140 public abstract function writeByte($byte);
Mark Slee97264862007-12-20 03:23:27 +0000141
Mark Slee5f8237d2006-10-26 04:57:03 +0000142 public abstract function writeI16($i16);
Mark Sleecfc01932006-09-01 22:18:16 +0000143
Mark Slee5f8237d2006-10-26 04:57:03 +0000144 public abstract function writeI32($i32);
Mark Slee6e536442006-06-30 18:28:50 +0000145
Mark Slee5f8237d2006-10-26 04:57:03 +0000146 public abstract function writeI64($i64);
Mark Slee6e536442006-06-30 18:28:50 +0000147
Mark Slee5f8237d2006-10-26 04:57:03 +0000148 public abstract function writeDouble($dub);
Mark Sleec98d0502006-09-06 02:42:25 +0000149
Mark Slee5f8237d2006-10-26 04:57:03 +0000150 public abstract function writeString($str);
Mark Slee6e536442006-06-30 18:28:50 +0000151
Mark Sleecfc01932006-09-01 22:18:16 +0000152 /**
153 * Reads the message header
154 *
Mark Sleecfc01932006-09-01 22:18:16 +0000155 * @param string $name Function name
156 * @param int $type message type TMessageType::CALL or TMessageType::REPLY
157 * @parem int $seqid The sequence id of this message
158 */
Mark Slee5f8237d2006-10-26 04:57:03 +0000159 public abstract function readMessageBegin(&$name, &$type, &$seqid);
Marc Slemkod97eb612006-08-24 23:37:36 +0000160
Mark Sleecfc01932006-09-01 22:18:16 +0000161 /**
162 * Read the close of message
Mark Sleecfc01932006-09-01 22:18:16 +0000163 */
Mark Slee5f8237d2006-10-26 04:57:03 +0000164 public abstract function readMessageEnd();
Marc Slemkod97eb612006-08-24 23:37:36 +0000165
Mark Slee5f8237d2006-10-26 04:57:03 +0000166 public abstract function readStructBegin(&$name);
Mark Slee97264862007-12-20 03:23:27 +0000167
Mark Slee5f8237d2006-10-26 04:57:03 +0000168 public abstract function readStructEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000169
Mark Slee5f8237d2006-10-26 04:57:03 +0000170 public abstract function readFieldBegin(&$name, &$fieldType, &$fieldId);
Mark Slee6e536442006-06-30 18:28:50 +0000171
Mark Slee5f8237d2006-10-26 04:57:03 +0000172 public abstract function readFieldEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000173
Mark Slee5f8237d2006-10-26 04:57:03 +0000174 public abstract function readMapBegin(&$keyType, &$valType, &$size);
Mark Slee6e536442006-06-30 18:28:50 +0000175
Mark Slee5f8237d2006-10-26 04:57:03 +0000176 public abstract function readMapEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000177
Mark Slee5f8237d2006-10-26 04:57:03 +0000178 public abstract function readListBegin(&$elemType, &$size);
Mark Slee97264862007-12-20 03:23:27 +0000179
Mark Slee5f8237d2006-10-26 04:57:03 +0000180 public abstract function readListEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000181
Mark Slee5f8237d2006-10-26 04:57:03 +0000182 public abstract function readSetBegin(&$elemType, &$size);
Mark Slee97264862007-12-20 03:23:27 +0000183
Mark Slee5f8237d2006-10-26 04:57:03 +0000184 public abstract function readSetEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000185
Mark Slee5f8237d2006-10-26 04:57:03 +0000186 public abstract function readBool(&$bool);
Mark Slee97264862007-12-20 03:23:27 +0000187
Mark Slee5f8237d2006-10-26 04:57:03 +0000188 public abstract function readByte(&$byte);
Mark Slee97264862007-12-20 03:23:27 +0000189
Mark Slee5f8237d2006-10-26 04:57:03 +0000190 public abstract function readI16(&$i16);
Mark Sleecfc01932006-09-01 22:18:16 +0000191
Mark Slee5f8237d2006-10-26 04:57:03 +0000192 public abstract function readI32(&$i32);
Mark Slee6e536442006-06-30 18:28:50 +0000193
Mark Slee5f8237d2006-10-26 04:57:03 +0000194 public abstract function readI64(&$i64);
Mark Slee6e536442006-06-30 18:28:50 +0000195
Mark Slee5f8237d2006-10-26 04:57:03 +0000196 public abstract function readDouble(&$dub);
Mark Sleec98d0502006-09-06 02:42:25 +0000197
Mark Slee5f8237d2006-10-26 04:57:03 +0000198 public abstract function readString(&$str);
Mark Slee6e536442006-06-30 18:28:50 +0000199
Mark Sleecfc01932006-09-01 22:18:16 +0000200 /**
201 * The skip function is a utility to parse over unrecognized date without
202 * causing corruption.
203 *
Mark Sleecfc01932006-09-01 22:18:16 +0000204 * @param TType $type What type is it
205 */
Mark Slee5f8237d2006-10-26 04:57:03 +0000206 public function skip($type) {
Mark Slee6e536442006-06-30 18:28:50 +0000207 switch ($type) {
Mark Slee78f58e22006-09-02 04:17:07 +0000208 case TType::BOOL:
Mark Slee5f8237d2006-10-26 04:57:03 +0000209 return $this->readBool($bool);
Mark Slee6e536442006-06-30 18:28:50 +0000210 case TType::BYTE:
Mark Slee5f8237d2006-10-26 04:57:03 +0000211 return $this->readByte($byte);
Adam Nichols2f816f22007-01-11 21:25:29 +0000212 case TType::I16:
Mark Slee5f8237d2006-10-26 04:57:03 +0000213 return $this->readI16($i16);
Mark Slee6e536442006-06-30 18:28:50 +0000214 case TType::I32:
Mark Slee5f8237d2006-10-26 04:57:03 +0000215 return $this->readI32($i32);
Mark Slee6e536442006-06-30 18:28:50 +0000216 case TType::I64:
Mark Slee5f8237d2006-10-26 04:57:03 +0000217 return $this->readI64($i64);
Mark Sleec98d0502006-09-06 02:42:25 +0000218 case TType::DOUBLE:
Mark Slee5f8237d2006-10-26 04:57:03 +0000219 return $this->readDouble($dub);
Mark Slee6e536442006-06-30 18:28:50 +0000220 case TType::STRING:
Mark Slee5f8237d2006-10-26 04:57:03 +0000221 return $this->readString($str);
Mark Slee6e536442006-06-30 18:28:50 +0000222 case TType::STRUCT:
223 {
Mark Slee5f8237d2006-10-26 04:57:03 +0000224 $result = $this->readStructBegin($name);
Mark Slee6e536442006-06-30 18:28:50 +0000225 while (true) {
Mark Slee5f8237d2006-10-26 04:57:03 +0000226 $result += $this->readFieldBegin($name, $ftype, $fid);
Mark Slee6e536442006-06-30 18:28:50 +0000227 if ($ftype == TType::STOP) {
228 break;
229 }
Mark Slee5f8237d2006-10-26 04:57:03 +0000230 $result += $this->skip($ftype);
231 $result += $this->readFieldEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000232 }
Mark Slee5f8237d2006-10-26 04:57:03 +0000233 $result += $this->readStructEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000234 return $result;
235 }
236 case TType::MAP:
237 {
Mark Slee5f8237d2006-10-26 04:57:03 +0000238 $result = $this->readMapBegin($keyType, $valType, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000239 for ($i = 0; $i < $size; $i++) {
Mark Slee5f8237d2006-10-26 04:57:03 +0000240 $result += $this->skip($keyType);
241 $result += $this->skip($valType);
Mark Slee6e536442006-06-30 18:28:50 +0000242 }
Mark Slee5f8237d2006-10-26 04:57:03 +0000243 $result += $this->readMapEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000244 return $result;
245 }
246 case TType::SET:
247 {
Mark Slee5f8237d2006-10-26 04:57:03 +0000248 $result = $this->readSetBegin($elemType, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000249 for ($i = 0; $i < $size; $i++) {
Mark Slee5f8237d2006-10-26 04:57:03 +0000250 $result += $this->skip($elemType);
Mark Slee6e536442006-06-30 18:28:50 +0000251 }
Mark Slee5f8237d2006-10-26 04:57:03 +0000252 $result += $this->readSetEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000253 return $result;
254 }
255 case TType::LST:
256 {
Mark Slee5f8237d2006-10-26 04:57:03 +0000257 $result = $this->readListBegin($elemType, $size);
Mark Slee6e536442006-06-30 18:28:50 +0000258 for ($i = 0; $i < $size; $i++) {
Mark Slee5f8237d2006-10-26 04:57:03 +0000259 $result += $this->skip($elemType);
Mark Slee6e536442006-06-30 18:28:50 +0000260 }
Mark Slee5f8237d2006-10-26 04:57:03 +0000261 $result += $this->readListEnd();
Mark Slee6e536442006-06-30 18:28:50 +0000262 return $result;
263 }
264 default:
265 return 0;
266 }
267 }
Mark Slee99e2b262006-10-10 01:42:29 +0000268
269 /**
270 * Utility for skipping binary data
271 *
272 * @param TTransport $itrans TTransport object
273 * @param int $type Field type
274 */
275 public static function skipBinary($itrans, $type) {
276 switch ($type) {
277 case TType::BOOL:
278 return $itrans->readAll(1);
279 case TType::BYTE:
280 return $itrans->readAll(1);
Adam Nichols2f816f22007-01-11 21:25:29 +0000281 case TType::I16:
Mark Slee99e2b262006-10-10 01:42:29 +0000282 return $itrans->readAll(2);
283 case TType::I32:
284 return $itrans->readAll(4);
285 case TType::I64:
286 return $itrans->readAll(8);
287 case TType::DOUBLE:
288 return $itrans->readAll(8);
289 case TType::STRING:
290 $len = unpack('N', $itrans->readAll(4));
291 $len = $len[1];
292 if ($len > 0x7fffffff) {
293 $len = 0 - (($len - 1) ^ 0xffffffff);
294 }
295 return 4 + $itrans->readAll($len);
296 case TType::STRUCT:
297 {
298 $result = 0;
299 while (true) {
300 $ftype = 0;
301 $fid = 0;
Mark Slee5f8237d2006-10-26 04:57:03 +0000302 $data = $itrans->readAll(1);
Mark Slee99e2b262006-10-10 01:42:29 +0000303 $arr = unpack('c', $data);
304 $ftype = $arr[1];
305 if ($ftype == TType::STOP) {
306 break;
307 }
308 // I16 field id
309 $result += $itrans->readAll(2);
310 $result += self::skipBinary($itrans, $ftype);
311 }
312 return $result;
313 }
314 case TType::MAP:
315 {
316 // Ktype
317 $data = $itrans->readAll(1);
318 $arr = unpack('c', $data);
319 $ktype = $arr[1];
320 // Vtype
321 $data = $itrans->readAll(1);
322 $arr = unpack('c', $data);
323 $vtype = $arr[1];
324 // Size
325 $data = $itrans->readAll(4);
326 $arr = unpack('N', $data);
327 $size = $arr[1];
328 if ($size > 0x7fffffff) {
329 $size = 0 - (($size - 1) ^ 0xffffffff);
330 }
331 $result = 6;
332 for ($i = 0; $i < $size; $i++) {
333 $result += self::skipBinary($itrans, $ktype);
334 $result += self::skipBinary($itrans, $vtype);
335 }
336 return $result;
337 }
338 case TType::SET:
339 case TType::LST:
340 {
341 // Vtype
342 $data = $itrans->readAll(1);
343 $arr = unpack('c', $data);
344 $vtype = $arr[1];
345 // Size
346 $data = $itrans->readAll(4);
347 $arr = unpack('N', $data);
348 $size = $arr[1];
349 if ($size > 0x7fffffff) {
350 $size = 0 - (($size - 1) ^ 0xffffffff);
351 }
352 $result = 5;
353 for ($i = 0; $i < $size; $i++) {
354 $result += self::skipBinary($itrans, $vtype);
355 }
356 return $result;
357 }
358 default:
359 return 0;
Mark Slee97264862007-12-20 03:23:27 +0000360 }
Mark Slee99e2b262006-10-10 01:42:29 +0000361 }
Mark Slee6e536442006-06-30 18:28:50 +0000362}
363
Mark Slee5f8237d2006-10-26 04:57:03 +0000364/**
365 * Protocol factory creates protocol objects from transports
366 */
367interface TProtocolFactory {
368 /**
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000369 * Build a protocol from the base transport
Mark Slee5f8237d2006-10-26 04:57:03 +0000370 *
Bryan Duxbury17115d72010-08-12 16:59:19 +0000371 * @return TProtocol protocol
Mark Slee5f8237d2006-10-26 04:57:03 +0000372 */
Aditya Agarwal6a5bcaa2007-02-06 02:50:56 +0000373 public function getProtocol($trans);
Mark Slee5f8237d2006-10-26 04:57:03 +0000374}