/lib/php/src/Thrift.php

http://github.com/apache/thrift · PHP · 821 lines · 732 code · 40 blank · 49 comment · 124 complexity · a894434f493de2ce513e99e7b0d242e7 MD5 · raw file

  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
  21. */
  22. /**
  23. * Data types that can be sent via Thrift
  24. */
  25. class TType
  26. {
  27. const STOP = 0;
  28. const VOID = 1;
  29. const BOOL = 2;
  30. const BYTE = 3;
  31. const I08 = 3;
  32. const DOUBLE = 4;
  33. const I16 = 6;
  34. const I32 = 8;
  35. const I64 = 10;
  36. const STRING = 11;
  37. const UTF7 = 11;
  38. const STRUCT = 12;
  39. const MAP = 13;
  40. const SET = 14;
  41. const LST = 15; // N.B. cannot use LIST keyword in PHP!
  42. const UTF8 = 16;
  43. const UTF16 = 17;
  44. }
  45. /**
  46. * Message types for RPC
  47. */
  48. class TMessageType
  49. {
  50. const CALL = 1;
  51. const REPLY = 2;
  52. const EXCEPTION = 3;
  53. const ONEWAY = 4;
  54. }
  55. /**
  56. * NOTE(mcslee): This currently contains a ton of duplicated code from TBase
  57. * because we need to save CPU cycles and this is not yet in an extension.
  58. * Ideally we'd multiply-inherit TException from both Exception and Base, but
  59. * that's not possible in PHP and there are no modules either, so for now we
  60. * apologetically take a trip to HackTown.
  61. *
  62. * Can be called with standard Exception constructor (message, code) or with
  63. * Thrift Base object constructor (spec, vals).
  64. *
  65. * @param mixed $p1 Message (string) or type-spec (array)
  66. * @param mixed $p2 Code (integer) or values (array)
  67. */
  68. class TException extends Exception
  69. {
  70. public function __construct($p1=null, $p2=0)
  71. {
  72. if (is_array($p1) && is_array($p2)) {
  73. $spec = $p1;
  74. $vals = $p2;
  75. foreach ($spec as $fid => $fspec) {
  76. $var = $fspec['var'];
  77. if (isset($vals[$var])) {
  78. $this->$var = $vals[$var];
  79. }
  80. }
  81. } else {
  82. parent::__construct($p1, $p2);
  83. }
  84. }
  85. static $tmethod = array(TType::BOOL => 'Bool',
  86. TType::BYTE => 'Byte',
  87. TType::I16 => 'I16',
  88. TType::I32 => 'I32',
  89. TType::I64 => 'I64',
  90. TType::DOUBLE => 'Double',
  91. TType::STRING => 'String');
  92. private function _readMap(&$var, $spec, $input)
  93. {
  94. $xfer = 0;
  95. $ktype = $spec['ktype'];
  96. $vtype = $spec['vtype'];
  97. $kread = $vread = null;
  98. if (isset(TBase::$tmethod[$ktype])) {
  99. $kread = 'read'.TBase::$tmethod[$ktype];
  100. } else {
  101. $kspec = $spec['key'];
  102. }
  103. if (isset(TBase::$tmethod[$vtype])) {
  104. $vread = 'read'.TBase::$tmethod[$vtype];
  105. } else {
  106. $vspec = $spec['val'];
  107. }
  108. $var = array();
  109. $_ktype = $_vtype = $size = 0;
  110. $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
  111. for ($i = 0; $i < $size; ++$i) {
  112. $key = $val = null;
  113. if ($kread !== null) {
  114. $xfer += $input->$kread($key);
  115. } else {
  116. switch ($ktype) {
  117. case TType::STRUCT:
  118. $class = $kspec['class'];
  119. $key = new $class();
  120. $xfer += $key->read($input);
  121. break;
  122. case TType::MAP:
  123. $xfer += $this->_readMap($key, $kspec, $input);
  124. break;
  125. case TType::LST:
  126. $xfer += $this->_readList($key, $kspec, $input, false);
  127. break;
  128. case TType::SET:
  129. $xfer += $this->_readList($key, $kspec, $input, true);
  130. break;
  131. }
  132. }
  133. if ($vread !== null) {
  134. $xfer += $input->$vread($val);
  135. } else {
  136. switch ($vtype) {
  137. case TType::STRUCT:
  138. $class = $vspec['class'];
  139. $val = new $class();
  140. $xfer += $val->read($input);
  141. break;
  142. case TType::MAP:
  143. $xfer += $this->_readMap($val, $vspec, $input);
  144. break;
  145. case TType::LST:
  146. $xfer += $this->_readList($val, $vspec, $input, false);
  147. break;
  148. case TType::SET:
  149. $xfer += $this->_readList($val, $vspec, $input, true);
  150. break;
  151. }
  152. }
  153. $var[$key] = $val;
  154. }
  155. $xfer += $input->readMapEnd();
  156. return $xfer;
  157. }
  158. private function _readList(&$var, $spec, $input, $set=false)
  159. {
  160. $xfer = 0;
  161. $etype = $spec['etype'];
  162. $eread = $vread = null;
  163. if (isset(TBase::$tmethod[$etype])) {
  164. $eread = 'read'.TBase::$tmethod[$etype];
  165. } else {
  166. $espec = $spec['elem'];
  167. }
  168. $var = array();
  169. $_etype = $size = 0;
  170. if ($set) {
  171. $xfer += $input->readSetBegin($_etype, $size);
  172. } else {
  173. $xfer += $input->readListBegin($_etype, $size);
  174. }
  175. for ($i = 0; $i < $size; ++$i) {
  176. $elem = null;
  177. if ($eread !== null) {
  178. $xfer += $input->$eread($elem);
  179. } else {
  180. $espec = $spec['elem'];
  181. switch ($etype) {
  182. case TType::STRUCT:
  183. $class = $espec['class'];
  184. $elem = new $class();
  185. $xfer += $elem->read($input);
  186. break;
  187. case TType::MAP:
  188. $xfer += $this->_readMap($elem, $espec, $input);
  189. break;
  190. case TType::LST:
  191. $xfer += $this->_readList($elem, $espec, $input, false);
  192. break;
  193. case TType::SET:
  194. $xfer += $this->_readList($elem, $espec, $input, true);
  195. break;
  196. }
  197. }
  198. if ($set) {
  199. $var[$elem] = true;
  200. } else {
  201. $var []= $elem;
  202. }
  203. }
  204. if ($set) {
  205. $xfer += $input->readSetEnd();
  206. } else {
  207. $xfer += $input->readListEnd();
  208. }
  209. return $xfer;
  210. }
  211. protected function _read($class, $spec, $input)
  212. {
  213. $xfer = 0;
  214. $fname = null;
  215. $ftype = 0;
  216. $fid = 0;
  217. $xfer += $input->readStructBegin($fname);
  218. while (true) {
  219. $xfer += $input->readFieldBegin($fname, $ftype, $fid);
  220. if ($ftype == TType::STOP) {
  221. break;
  222. }
  223. if (isset($spec[$fid])) {
  224. $fspec = $spec[$fid];
  225. $var = $fspec['var'];
  226. if ($ftype == $fspec['type']) {
  227. $xfer = 0;
  228. if (isset(TBase::$tmethod[$ftype])) {
  229. $func = 'read'.TBase::$tmethod[$ftype];
  230. $xfer += $input->$func($this->$var);
  231. } else {
  232. switch ($ftype) {
  233. case TType::STRUCT:
  234. $class = $fspec['class'];
  235. $this->$var = new $class();
  236. $xfer += $this->$var->read($input);
  237. break;
  238. case TType::MAP:
  239. $xfer += $this->_readMap($this->$var, $fspec, $input);
  240. break;
  241. case TType::LST:
  242. $xfer += $this->_readList($this->$var, $fspec, $input, false);
  243. break;
  244. case TType::SET:
  245. $xfer += $this->_readList($this->$var, $fspec, $input, true);
  246. break;
  247. }
  248. }
  249. } else {
  250. $xfer += $input->skip($ftype);
  251. }
  252. } else {
  253. $xfer += $input->skip($ftype);
  254. }
  255. $xfer += $input->readFieldEnd();
  256. }
  257. $xfer += $input->readStructEnd();
  258. return $xfer;
  259. }
  260. private function _writeMap($var, $spec, $output)
  261. {
  262. $xfer = 0;
  263. $ktype = $spec['ktype'];
  264. $vtype = $spec['vtype'];
  265. $kwrite = $vwrite = null;
  266. if (isset(TBase::$tmethod[$ktype])) {
  267. $kwrite = 'write'.TBase::$tmethod[$ktype];
  268. } else {
  269. $kspec = $spec['key'];
  270. }
  271. if (isset(TBase::$tmethod[$vtype])) {
  272. $vwrite = 'write'.TBase::$tmethod[$vtype];
  273. } else {
  274. $vspec = $spec['val'];
  275. }
  276. $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
  277. foreach ($var as $key => $val) {
  278. if (isset($kwrite)) {
  279. $xfer += $output->$kwrite($key);
  280. } else {
  281. switch ($ktype) {
  282. case TType::STRUCT:
  283. $xfer += $key->write($output);
  284. break;
  285. case TType::MAP:
  286. $xfer += $this->_writeMap($key, $kspec, $output);
  287. break;
  288. case TType::LST:
  289. $xfer += $this->_writeList($key, $kspec, $output, false);
  290. break;
  291. case TType::SET:
  292. $xfer += $this->_writeList($key, $kspec, $output, true);
  293. break;
  294. }
  295. }
  296. if (isset($vwrite)) {
  297. $xfer += $output->$vwrite($val);
  298. } else {
  299. switch ($vtype) {
  300. case TType::STRUCT:
  301. $xfer += $val->write($output);
  302. break;
  303. case TType::MAP:
  304. $xfer += $this->_writeMap($val, $vspec, $output);
  305. break;
  306. case TType::LST:
  307. $xfer += $this->_writeList($val, $vspec, $output, false);
  308. break;
  309. case TType::SET:
  310. $xfer += $this->_writeList($val, $vspec, $output, true);
  311. break;
  312. }
  313. }
  314. }
  315. $xfer += $output->writeMapEnd();
  316. return $xfer;
  317. }
  318. private function _writeList($var, $spec, $output, $set=false)
  319. {
  320. $xfer = 0;
  321. $etype = $spec['etype'];
  322. $ewrite = null;
  323. if (isset(TBase::$tmethod[$etype])) {
  324. $ewrite = 'write'.TBase::$tmethod[$etype];
  325. } else {
  326. $espec = $spec['elem'];
  327. }
  328. if ($set) {
  329. $xfer += $output->writeSetBegin($etype, count($var));
  330. } else {
  331. $xfer += $output->writeListBegin($etype, count($var));
  332. }
  333. foreach ($var as $key => $val) {
  334. $elem = $set ? $key : $val;
  335. if (isset($ewrite)) {
  336. $xfer += $output->$ewrite($elem);
  337. } else {
  338. switch ($etype) {
  339. case TType::STRUCT:
  340. $xfer += $elem->write($output);
  341. break;
  342. case TType::MAP:
  343. $xfer += $this->_writeMap($elem, $espec, $output);
  344. break;
  345. case TType::LST:
  346. $xfer += $this->_writeList($elem, $espec, $output, false);
  347. break;
  348. case TType::SET:
  349. $xfer += $this->_writeList($elem, $espec, $output, true);
  350. break;
  351. }
  352. }
  353. }
  354. if ($set) {
  355. $xfer += $output->writeSetEnd();
  356. } else {
  357. $xfer += $output->writeListEnd();
  358. }
  359. return $xfer;
  360. }
  361. protected function _write($class, $spec, $output)
  362. {
  363. $xfer = 0;
  364. $xfer += $output->writeStructBegin($class);
  365. foreach ($spec as $fid => $fspec) {
  366. $var = $fspec['var'];
  367. if ($this->$var !== null) {
  368. $ftype = $fspec['type'];
  369. $xfer += $output->writeFieldBegin($var, $ftype, $fid);
  370. if (isset(TBase::$tmethod[$ftype])) {
  371. $func = 'write'.TBase::$tmethod[$ftype];
  372. $xfer += $output->$func($this->$var);
  373. } else {
  374. switch ($ftype) {
  375. case TType::STRUCT:
  376. $xfer += $this->$var->write($output);
  377. break;
  378. case TType::MAP:
  379. $xfer += $this->_writeMap($this->$var, $fspec, $output);
  380. break;
  381. case TType::LST:
  382. $xfer += $this->_writeList($this->$var, $fspec, $output, false);
  383. break;
  384. case TType::SET:
  385. $xfer += $this->_writeList($this->$var, $fspec, $output, true);
  386. break;
  387. }
  388. }
  389. $xfer += $output->writeFieldEnd();
  390. }
  391. }
  392. $xfer += $output->writeFieldStop();
  393. $xfer += $output->writeStructEnd();
  394. return $xfer;
  395. }
  396. }
  397. /**
  398. * Base class from which other Thrift structs extend. This is so that we can
  399. * cut back on the size of the generated code which is turning out to have a
  400. * nontrivial cost just to load thanks to the wondrously abysmal implementation
  401. * of PHP. Note that code is intentionally duplicated in here to avoid making
  402. * function calls for every field or member of a container..
  403. */
  404. abstract class TBase
  405. {
  406. static $tmethod = array(TType::BOOL => 'Bool',
  407. TType::BYTE => 'Byte',
  408. TType::I16 => 'I16',
  409. TType::I32 => 'I32',
  410. TType::I64 => 'I64',
  411. TType::DOUBLE => 'Double',
  412. TType::STRING => 'String');
  413. abstract public function read($input);
  414. abstract public function write($output);
  415. public function __construct($spec=null, $vals=null)
  416. {
  417. if (is_array($spec) && is_array($vals)) {
  418. foreach ($spec as $fid => $fspec) {
  419. $var = $fspec['var'];
  420. if (isset($vals[$var])) {
  421. $this->$var = $vals[$var];
  422. }
  423. }
  424. }
  425. }
  426. private function _readMap(&$var, $spec, $input)
  427. {
  428. $xfer = 0;
  429. $ktype = $spec['ktype'];
  430. $vtype = $spec['vtype'];
  431. $kread = $vread = null;
  432. if (isset(TBase::$tmethod[$ktype])) {
  433. $kread = 'read'.TBase::$tmethod[$ktype];
  434. } else {
  435. $kspec = $spec['key'];
  436. }
  437. if (isset(TBase::$tmethod[$vtype])) {
  438. $vread = 'read'.TBase::$tmethod[$vtype];
  439. } else {
  440. $vspec = $spec['val'];
  441. }
  442. $var = array();
  443. $_ktype = $_vtype = $size = 0;
  444. $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
  445. for ($i = 0; $i < $size; ++$i) {
  446. $key = $val = null;
  447. if ($kread !== null) {
  448. $xfer += $input->$kread($key);
  449. } else {
  450. switch ($ktype) {
  451. case TType::STRUCT:
  452. $class = $kspec['class'];
  453. $key = new $class();
  454. $xfer += $key->read($input);
  455. break;
  456. case TType::MAP:
  457. $xfer += $this->_readMap($key, $kspec, $input);
  458. break;
  459. case TType::LST:
  460. $xfer += $this->_readList($key, $kspec, $input, false);
  461. break;
  462. case TType::SET:
  463. $xfer += $this->_readList($key, $kspec, $input, true);
  464. break;
  465. }
  466. }
  467. if ($vread !== null) {
  468. $xfer += $input->$vread($val);
  469. } else {
  470. switch ($vtype) {
  471. case TType::STRUCT:
  472. $class = $vspec['class'];
  473. $val = new $class();
  474. $xfer += $val->read($input);
  475. break;
  476. case TType::MAP:
  477. $xfer += $this->_readMap($val, $vspec, $input);
  478. break;
  479. case TType::LST:
  480. $xfer += $this->_readList($val, $vspec, $input, false);
  481. break;
  482. case TType::SET:
  483. $xfer += $this->_readList($val, $vspec, $input, true);
  484. break;
  485. }
  486. }
  487. $var[$key] = $val;
  488. }
  489. $xfer += $input->readMapEnd();
  490. return $xfer;
  491. }
  492. private function _readList(&$var, $spec, $input, $set=false)
  493. {
  494. $xfer = 0;
  495. $etype = $spec['etype'];
  496. $eread = $vread = null;
  497. if (isset(TBase::$tmethod[$etype])) {
  498. $eread = 'read'.TBase::$tmethod[$etype];
  499. } else {
  500. $espec = $spec['elem'];
  501. }
  502. $var = array();
  503. $_etype = $size = 0;
  504. if ($set) {
  505. $xfer += $input->readSetBegin($_etype, $size);
  506. } else {
  507. $xfer += $input->readListBegin($_etype, $size);
  508. }
  509. for ($i = 0; $i < $size; ++$i) {
  510. $elem = null;
  511. if ($eread !== null) {
  512. $xfer += $input->$eread($elem);
  513. } else {
  514. $espec = $spec['elem'];
  515. switch ($etype) {
  516. case TType::STRUCT:
  517. $class = $espec['class'];
  518. $elem = new $class();
  519. $xfer += $elem->read($input);
  520. break;
  521. case TType::MAP:
  522. $xfer += $this->_readMap($elem, $espec, $input);
  523. break;
  524. case TType::LST:
  525. $xfer += $this->_readList($elem, $espec, $input, false);
  526. break;
  527. case TType::SET:
  528. $xfer += $this->_readList($elem, $espec, $input, true);
  529. break;
  530. }
  531. }
  532. if ($set) {
  533. $var[$elem] = true;
  534. } else {
  535. $var []= $elem;
  536. }
  537. }
  538. if ($set) {
  539. $xfer += $input->readSetEnd();
  540. } else {
  541. $xfer += $input->readListEnd();
  542. }
  543. return $xfer;
  544. }
  545. protected function _read($class, $spec, $input)
  546. {
  547. $xfer = 0;
  548. $fname = null;
  549. $ftype = 0;
  550. $fid = 0;
  551. $xfer += $input->readStructBegin($fname);
  552. while (true) {
  553. $xfer += $input->readFieldBegin($fname, $ftype, $fid);
  554. if ($ftype == TType::STOP) {
  555. break;
  556. }
  557. if (isset($spec[$fid])) {
  558. $fspec = $spec[$fid];
  559. $var = $fspec['var'];
  560. if ($ftype == $fspec['type']) {
  561. $xfer = 0;
  562. if (isset(TBase::$tmethod[$ftype])) {
  563. $func = 'read'.TBase::$tmethod[$ftype];
  564. $xfer += $input->$func($this->$var);
  565. } else {
  566. switch ($ftype) {
  567. case TType::STRUCT:
  568. $class = $fspec['class'];
  569. $this->$var = new $class();
  570. $xfer += $this->$var->read($input);
  571. break;
  572. case TType::MAP:
  573. $xfer += $this->_readMap($this->$var, $fspec, $input);
  574. break;
  575. case TType::LST:
  576. $xfer += $this->_readList($this->$var, $fspec, $input, false);
  577. break;
  578. case TType::SET:
  579. $xfer += $this->_readList($this->$var, $fspec, $input, true);
  580. break;
  581. }
  582. }
  583. } else {
  584. $xfer += $input->skip($ftype);
  585. }
  586. } else {
  587. $xfer += $input->skip($ftype);
  588. }
  589. $xfer += $input->readFieldEnd();
  590. }
  591. $xfer += $input->readStructEnd();
  592. return $xfer;
  593. }
  594. private function _writeMap($var, $spec, $output)
  595. {
  596. $xfer = 0;
  597. $ktype = $spec['ktype'];
  598. $vtype = $spec['vtype'];
  599. $kwrite = $vwrite = null;
  600. if (isset(TBase::$tmethod[$ktype])) {
  601. $kwrite = 'write'.TBase::$tmethod[$ktype];
  602. } else {
  603. $kspec = $spec['key'];
  604. }
  605. if (isset(TBase::$tmethod[$vtype])) {
  606. $vwrite = 'write'.TBase::$tmethod[$vtype];
  607. } else {
  608. $vspec = $spec['val'];
  609. }
  610. $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
  611. foreach ($var as $key => $val) {
  612. if (isset($kwrite)) {
  613. $xfer += $output->$kwrite($key);
  614. } else {
  615. switch ($ktype) {
  616. case TType::STRUCT:
  617. $xfer += $key->write($output);
  618. break;
  619. case TType::MAP:
  620. $xfer += $this->_writeMap($key, $kspec, $output);
  621. break;
  622. case TType::LST:
  623. $xfer += $this->_writeList($key, $kspec, $output, false);
  624. break;
  625. case TType::SET:
  626. $xfer += $this->_writeList($key, $kspec, $output, true);
  627. break;
  628. }
  629. }
  630. if (isset($vwrite)) {
  631. $xfer += $output->$vwrite($val);
  632. } else {
  633. switch ($vtype) {
  634. case TType::STRUCT:
  635. $xfer += $val->write($output);
  636. break;
  637. case TType::MAP:
  638. $xfer += $this->_writeMap($val, $vspec, $output);
  639. break;
  640. case TType::LST:
  641. $xfer += $this->_writeList($val, $vspec, $output, false);
  642. break;
  643. case TType::SET:
  644. $xfer += $this->_writeList($val, $vspec, $output, true);
  645. break;
  646. }
  647. }
  648. }
  649. $xfer += $output->writeMapEnd();
  650. return $xfer;
  651. }
  652. private function _writeList($var, $spec, $output, $set=false)
  653. {
  654. $xfer = 0;
  655. $etype = $spec['etype'];
  656. $ewrite = null;
  657. if (isset(TBase::$tmethod[$etype])) {
  658. $ewrite = 'write'.TBase::$tmethod[$etype];
  659. } else {
  660. $espec = $spec['elem'];
  661. }
  662. if ($set) {
  663. $xfer += $output->writeSetBegin($etype, count($var));
  664. } else {
  665. $xfer += $output->writeListBegin($etype, count($var));
  666. }
  667. foreach ($var as $key => $val) {
  668. $elem = $set ? $key : $val;
  669. if (isset($ewrite)) {
  670. $xfer += $output->$ewrite($elem);
  671. } else {
  672. switch ($etype) {
  673. case TType::STRUCT:
  674. $xfer += $elem->write($output);
  675. break;
  676. case TType::MAP:
  677. $xfer += $this->_writeMap($elem, $espec, $output);
  678. break;
  679. case TType::LST:
  680. $xfer += $this->_writeList($elem, $espec, $output, false);
  681. break;
  682. case TType::SET:
  683. $xfer += $this->_writeList($elem, $espec, $output, true);
  684. break;
  685. }
  686. }
  687. }
  688. if ($set) {
  689. $xfer += $output->writeSetEnd();
  690. } else {
  691. $xfer += $output->writeListEnd();
  692. }
  693. return $xfer;
  694. }
  695. protected function _write($class, $spec, $output)
  696. {
  697. $xfer = 0;
  698. $xfer += $output->writeStructBegin($class);
  699. foreach ($spec as $fid => $fspec) {
  700. $var = $fspec['var'];
  701. if ($this->$var !== null) {
  702. $ftype = $fspec['type'];
  703. $xfer += $output->writeFieldBegin($var, $ftype, $fid);
  704. if (isset(TBase::$tmethod[$ftype])) {
  705. $func = 'write'.TBase::$tmethod[$ftype];
  706. $xfer += $output->$func($this->$var);
  707. } else {
  708. switch ($ftype) {
  709. case TType::STRUCT:
  710. $xfer += $this->$var->write($output);
  711. break;
  712. case TType::MAP:
  713. $xfer += $this->_writeMap($this->$var, $fspec, $output);
  714. break;
  715. case TType::LST:
  716. $xfer += $this->_writeList($this->$var, $fspec, $output, false);
  717. break;
  718. case TType::SET:
  719. $xfer += $this->_writeList($this->$var, $fspec, $output, true);
  720. break;
  721. }
  722. }
  723. $xfer += $output->writeFieldEnd();
  724. }
  725. }
  726. $xfer += $output->writeFieldStop();
  727. $xfer += $output->writeStructEnd();
  728. return $xfer;
  729. }
  730. }
  731. class TApplicationException extends TException
  732. {
  733. static $_TSPEC =
  734. array(1 => array('var' => 'message',
  735. 'type' => TType::STRING),
  736. 2 => array('var' => 'code',
  737. 'type' => TType::I32));
  738. const UNKNOWN = 0;
  739. const UNKNOWN_METHOD = 1;
  740. const INVALID_MESSAGE_TYPE = 2;
  741. const WRONG_METHOD_NAME = 3;
  742. const BAD_SEQUENCE_ID = 4;
  743. const MISSING_RESULT = 5;
  744. const INTERNAL_ERROR = 6;
  745. const PROTOCOL_ERROR = 7;
  746. public function __construct($message=null, $code=0)
  747. {
  748. parent::__construct($message, $code);
  749. }
  750. public function read($output)
  751. {
  752. return $this->_read('TApplicationException', self::$_TSPEC, $output);
  753. }
  754. public function write($output)
  755. {
  756. $xfer = 0;
  757. $xfer += $output->writeStructBegin('TApplicationException');
  758. if ($message = $this->getMessage()) {
  759. $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
  760. $xfer += $output->writeString($message);
  761. $xfer += $output->writeFieldEnd();
  762. }
  763. if ($code = $this->getCode()) {
  764. $xfer += $output->writeFieldBegin('type', TType::I32, 2);
  765. $xfer += $output->writeI32($code);
  766. $xfer += $output->writeFieldEnd();
  767. }
  768. $xfer += $output->writeFieldStop();
  769. $xfer += $output->writeStructEnd();
  770. return $xfer;
  771. }
  772. }
  773. /**
  774. * Set global THRIFT ROOT automatically via inclusion here
  775. */
  776. if (!isset($GLOBALS['THRIFT_ROOT'])) {
  777. $GLOBALS['THRIFT_ROOT'] = dirname(__FILE__);
  778. }
  779. include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TProtocol.php';
  780. include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php';
  781. include_once $GLOBALS['THRIFT_ROOT'].'/TStringUtils.php';