TProtocol.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <?php
  2. /*
  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
  10. *
  11. * 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.
  19. *
  20. * @package thrift.protocol
  21. */
  22. namespace Thrift\Protocol;
  23. use Thrift\Type\TType;
  24. use Thrift\Exception\TProtocolException;
  25. /**
  26. * Protocol base class module.
  27. */
  28. abstract class TProtocol
  29. {
  30. /**
  31. * Underlying transport
  32. *
  33. * @var TTransport
  34. */
  35. protected $trans_;
  36. /**
  37. * Constructor
  38. */
  39. protected function __construct($trans)
  40. {
  41. $this->trans_ = $trans;
  42. }
  43. /**
  44. * Accessor for transport
  45. *
  46. * @return TTransport
  47. */
  48. public function getTransport()
  49. {
  50. return $this->trans_;
  51. }
  52. /**
  53. * Writes the message header
  54. *
  55. * @param string $name Function name
  56. * @param int $type message type TMessageType::CALL or TMessageType::REPLY
  57. * @param int $seqid The sequence id of this message
  58. */
  59. abstract public function writeMessageBegin($name, $type, $seqid);
  60. /**
  61. * Close the message
  62. */
  63. abstract public function writeMessageEnd();
  64. /**
  65. * Writes a struct header.
  66. *
  67. * @param string $name Struct name
  68. * @throws TException on write error
  69. * @return int How many bytes written
  70. */
  71. abstract public function writeStructBegin($name);
  72. /**
  73. * Close a struct.
  74. *
  75. * @throws TException on write error
  76. * @return int How many bytes written
  77. */
  78. abstract public function writeStructEnd();
  79. /*
  80. * Starts a field.
  81. *
  82. * @param string $name Field name
  83. * @param int $type Field type
  84. * @param int $fid Field id
  85. * @throws TException on write error
  86. * @return int How many bytes written
  87. */
  88. abstract public function writeFieldBegin($fieldName, $fieldType, $fieldId);
  89. abstract public function writeFieldEnd();
  90. abstract public function writeFieldStop();
  91. abstract public function writeMapBegin($keyType, $valType, $size);
  92. abstract public function writeMapEnd();
  93. abstract public function writeListBegin($elemType, $size);
  94. abstract public function writeListEnd();
  95. abstract public function writeSetBegin($elemType, $size);
  96. abstract public function writeSetEnd();
  97. abstract public function writeBool($bool);
  98. abstract public function writeByte($byte);
  99. abstract public function writeI16($i16);
  100. abstract public function writeI32($i32);
  101. abstract public function writeI64($i64);
  102. abstract public function writeDouble($dub);
  103. abstract public function writeString($str);
  104. /**
  105. * Reads the message header
  106. *
  107. * @param string $name Function name
  108. * @param int $type message type TMessageType::CALL or TMessageType::REPLY
  109. * @parem int $seqid The sequence id of this message
  110. */
  111. abstract public function readMessageBegin(&$name, &$type, &$seqid);
  112. /**
  113. * Read the close of message
  114. */
  115. abstract public function readMessageEnd();
  116. abstract public function readStructBegin(&$name);
  117. abstract public function readStructEnd();
  118. abstract public function readFieldBegin(&$name, &$fieldType, &$fieldId);
  119. abstract public function readFieldEnd();
  120. abstract public function readMapBegin(&$keyType, &$valType, &$size);
  121. abstract public function readMapEnd();
  122. abstract public function readListBegin(&$elemType, &$size);
  123. abstract public function readListEnd();
  124. abstract public function readSetBegin(&$elemType, &$size);
  125. abstract public function readSetEnd();
  126. abstract public function readBool(&$bool);
  127. abstract public function readByte(&$byte);
  128. abstract public function readI16(&$i16);
  129. abstract public function readI32(&$i32);
  130. abstract public function readI64(&$i64);
  131. abstract public function readDouble(&$dub);
  132. abstract public function readString(&$str);
  133. /**
  134. * The skip function is a utility to parse over unrecognized date without
  135. * causing corruption.
  136. *
  137. * @param TType $type What type is it
  138. */
  139. public function skip($type)
  140. {
  141. switch ($type) {
  142. case TType::BOOL:
  143. return $this->readBool($bool);
  144. case TType::BYTE:
  145. return $this->readByte($byte);
  146. case TType::I16:
  147. return $this->readI16($i16);
  148. case TType::I32:
  149. return $this->readI32($i32);
  150. case TType::I64:
  151. return $this->readI64($i64);
  152. case TType::DOUBLE:
  153. return $this->readDouble($dub);
  154. case TType::STRING:
  155. return $this->readString($str);
  156. case TType::STRUCT:
  157. {
  158. $result = $this->readStructBegin($name);
  159. while (true) {
  160. $result += $this->readFieldBegin($name, $ftype, $fid);
  161. if ($ftype == TType::STOP) {
  162. break;
  163. }
  164. $result += $this->skip($ftype);
  165. $result += $this->readFieldEnd();
  166. }
  167. $result += $this->readStructEnd();
  168. return $result;
  169. }
  170. case TType::MAP:
  171. {
  172. $result = $this->readMapBegin($keyType, $valType, $size);
  173. for ($i = 0; $i < $size; $i++) {
  174. $result += $this->skip($keyType);
  175. $result += $this->skip($valType);
  176. }
  177. $result += $this->readMapEnd();
  178. return $result;
  179. }
  180. case TType::SET:
  181. {
  182. $result = $this->readSetBegin($elemType, $size);
  183. for ($i = 0; $i < $size; $i++) {
  184. $result += $this->skip($elemType);
  185. }
  186. $result += $this->readSetEnd();
  187. return $result;
  188. }
  189. case TType::LST:
  190. {
  191. $result = $this->readListBegin($elemType, $size);
  192. for ($i = 0; $i < $size; $i++) {
  193. $result += $this->skip($elemType);
  194. }
  195. $result += $this->readListEnd();
  196. return $result;
  197. }
  198. default:
  199. throw new TProtocolException('Unknown field type: '.$type,
  200. TProtocolException::INVALID_DATA);
  201. }
  202. }
  203. /**
  204. * Utility for skipping binary data
  205. *
  206. * @param TTransport $itrans TTransport object
  207. * @param int $type Field type
  208. */
  209. public static function skipBinary($itrans, $type)
  210. {
  211. switch ($type) {
  212. case TType::BOOL:
  213. return $itrans->readAll(1);
  214. case TType::BYTE:
  215. return $itrans->readAll(1);
  216. case TType::I16:
  217. return $itrans->readAll(2);
  218. case TType::I32:
  219. return $itrans->readAll(4);
  220. case TType::I64:
  221. return $itrans->readAll(8);
  222. case TType::DOUBLE:
  223. return $itrans->readAll(8);
  224. case TType::STRING:
  225. $len = unpack('N', $itrans->readAll(4));
  226. $len = $len[1];
  227. if ($len > 0x7fffffff) {
  228. $len = 0 - (($len - 1) ^ 0xffffffff);
  229. }
  230. return 4 + $itrans->readAll($len);
  231. case TType::STRUCT:
  232. {
  233. $result = 0;
  234. while (true) {
  235. $ftype = 0;
  236. $fid = 0;
  237. $data = $itrans->readAll(1);
  238. $arr = unpack('c', $data);
  239. $ftype = $arr[1];
  240. if ($ftype == TType::STOP) {
  241. break;
  242. }
  243. // I16 field id
  244. $result += $itrans->readAll(2);
  245. $result += self::skipBinary($itrans, $ftype);
  246. }
  247. return $result;
  248. }
  249. case TType::MAP:
  250. {
  251. // Ktype
  252. $data = $itrans->readAll(1);
  253. $arr = unpack('c', $data);
  254. $ktype = $arr[1];
  255. // Vtype
  256. $data = $itrans->readAll(1);
  257. $arr = unpack('c', $data);
  258. $vtype = $arr[1];
  259. // Size
  260. $data = $itrans->readAll(4);
  261. $arr = unpack('N', $data);
  262. $size = $arr[1];
  263. if ($size > 0x7fffffff) {
  264. $size = 0 - (($size - 1) ^ 0xffffffff);
  265. }
  266. $result = 6;
  267. for ($i = 0; $i < $size; $i++) {
  268. $result += self::skipBinary($itrans, $ktype);
  269. $result += self::skipBinary($itrans, $vtype);
  270. }
  271. return $result;
  272. }
  273. case TType::SET:
  274. case TType::LST:
  275. {
  276. // Vtype
  277. $data = $itrans->readAll(1);
  278. $arr = unpack('c', $data);
  279. $vtype = $arr[1];
  280. // Size
  281. $data = $itrans->readAll(4);
  282. $arr = unpack('N', $data);
  283. $size = $arr[1];
  284. if ($size > 0x7fffffff) {
  285. $size = 0 - (($size - 1) ^ 0xffffffff);
  286. }
  287. $result = 5;
  288. for ($i = 0; $i < $size; $i++) {
  289. $result += self::skipBinary($itrans, $vtype);
  290. }
  291. return $result;
  292. }
  293. default:
  294. throw new TProtocolException('Unknown field type: '.$type,
  295. TProtocolException::INVALID_DATA);
  296. }
  297. }
  298. }