blob: 1dbf64b00491e8ef4a73ea756e490a3eaad65c8a [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
Mark Slee4902c052007-03-01 00:31:30 +000021 */
22
23/**
Mark Slee1ecb1b02007-02-22 01:01:10 +000024 * Data types that can be sent via Thrift
Mark Slee99e2b262006-10-10 01:42:29 +000025 */
Roger Thomas6fb59232014-11-04 10:09:23 +000026class TType
27{
Mark Slee1ecb1b02007-02-22 01:01:10 +000028 const STOP = 0;
29 const VOID = 1;
30 const BOOL = 2;
31 const BYTE = 3;
32 const I08 = 3;
33 const DOUBLE = 4;
34 const I16 = 6;
35 const I32 = 8;
36 const I64 = 10;
37 const STRING = 11;
38 const UTF7 = 11;
39 const STRUCT = 12;
40 const MAP = 13;
41 const SET = 14;
42 const LST = 15; // N.B. cannot use LIST keyword in PHP!
43 const UTF8 = 16;
44 const UTF16 = 17;
Mark Sleecfc01932006-09-01 22:18:16 +000045}
Mark Slee1ecb1b02007-02-22 01:01:10 +000046
47/**
48 * Message types for RPC
49 */
Roger Thomas6fb59232014-11-04 10:09:23 +000050class TMessageType
51{
Mark Slee1ecb1b02007-02-22 01:01:10 +000052 const CALL = 1;
53 const REPLY = 2;
Mark Sleed395d572007-02-27 01:16:55 +000054 const EXCEPTION = 3;
David Reissdeda1412009-04-02 19:22:31 +000055 const ONEWAY = 4;
Mark Slee1ecb1b02007-02-22 01:01:10 +000056}
Mark Slee6e536442006-06-30 18:28:50 +000057
Mark Slee5b743072007-11-13 04:00:29 +000058/**
59 * NOTE(mcslee): This currently contains a ton of duplicated code from TBase
60 * because we need to save CPU cycles and this is not yet in an extension.
61 * Ideally we'd multiply-inherit TException from both Exception and Base, but
62 * that's not possible in PHP and there are no modules either, so for now we
63 * apologetically take a trip to HackTown.
64 *
65 * Can be called with standard Exception constructor (message, code) or with
66 * Thrift Base object constructor (spec, vals).
67 *
68 * @param mixed $p1 Message (string) or type-spec (array)
69 * @param mixed $p2 Code (integer) or values (array)
70 */
Volodymyr Panivkoac52d8d2024-02-22 22:09:00 +010071#[\AllowDynamicProperties]
Roger Thomas6fb59232014-11-04 10:09:23 +000072class TException extends Exception
73{
74 public function __construct($p1=null, $p2=0)
75 {
Mark Slee5b743072007-11-13 04:00:29 +000076 if (is_array($p1) && is_array($p2)) {
77 $spec = $p1;
78 $vals = $p2;
79 foreach ($spec as $fid => $fspec) {
80 $var = $fspec['var'];
81 if (isset($vals[$var])) {
82 $this->$var = $vals[$var];
83 }
84 }
85 } else {
vladimir.panivko3abf7ec2023-07-06 08:55:46 +020086 parent::__construct((string)$p1, $p2);
Mark Slee5b743072007-11-13 04:00:29 +000087 }
88 }
89
90 static $tmethod = array(TType::BOOL => 'Bool',
91 TType::BYTE => 'Byte',
92 TType::I16 => 'I16',
93 TType::I32 => 'I32',
94 TType::I64 => 'I64',
95 TType::DOUBLE => 'Double',
96 TType::STRING => 'String');
97
Roger Thomas6fb59232014-11-04 10:09:23 +000098 private function _readMap(&$var, $spec, $input)
99 {
Mark Slee5b743072007-11-13 04:00:29 +0000100 $xfer = 0;
101 $ktype = $spec['ktype'];
102 $vtype = $spec['vtype'];
103 $kread = $vread = null;
104 if (isset(TBase::$tmethod[$ktype])) {
105 $kread = 'read'.TBase::$tmethod[$ktype];
106 } else {
107 $kspec = $spec['key'];
108 }
109 if (isset(TBase::$tmethod[$vtype])) {
110 $vread = 'read'.TBase::$tmethod[$vtype];
111 } else {
112 $vspec = $spec['val'];
113 }
114 $var = array();
115 $_ktype = $_vtype = $size = 0;
116 $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
117 for ($i = 0; $i < $size; ++$i) {
118 $key = $val = null;
119 if ($kread !== null) {
120 $xfer += $input->$kread($key);
121 } else {
122 switch ($ktype) {
123 case TType::STRUCT:
124 $class = $kspec['class'];
125 $key = new $class();
126 $xfer += $key->read($input);
127 break;
128 case TType::MAP:
129 $xfer += $this->_readMap($key, $kspec, $input);
130 break;
131 case TType::LST:
132 $xfer += $this->_readList($key, $kspec, $input, false);
133 break;
134 case TType::SET:
135 $xfer += $this->_readList($key, $kspec, $input, true);
136 break;
137 }
138 }
139 if ($vread !== null) {
140 $xfer += $input->$vread($val);
141 } else {
142 switch ($vtype) {
143 case TType::STRUCT:
144 $class = $vspec['class'];
145 $val = new $class();
146 $xfer += $val->read($input);
147 break;
148 case TType::MAP:
149 $xfer += $this->_readMap($val, $vspec, $input);
150 break;
151 case TType::LST:
152 $xfer += $this->_readList($val, $vspec, $input, false);
153 break;
154 case TType::SET:
155 $xfer += $this->_readList($val, $vspec, $input, true);
156 break;
157 }
158 }
159 $var[$key] = $val;
160 }
161 $xfer += $input->readMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000162
Mark Slee5b743072007-11-13 04:00:29 +0000163 return $xfer;
164 }
165
Roger Thomas6fb59232014-11-04 10:09:23 +0000166 private function _readList(&$var, $spec, $input, $set=false)
167 {
Mark Slee5b743072007-11-13 04:00:29 +0000168 $xfer = 0;
169 $etype = $spec['etype'];
170 $eread = $vread = null;
171 if (isset(TBase::$tmethod[$etype])) {
172 $eread = 'read'.TBase::$tmethod[$etype];
173 } else {
174 $espec = $spec['elem'];
175 }
176 $var = array();
177 $_etype = $size = 0;
178 if ($set) {
179 $xfer += $input->readSetBegin($_etype, $size);
180 } else {
181 $xfer += $input->readListBegin($_etype, $size);
182 }
183 for ($i = 0; $i < $size; ++$i) {
184 $elem = null;
185 if ($eread !== null) {
186 $xfer += $input->$eread($elem);
187 } else {
188 $espec = $spec['elem'];
189 switch ($etype) {
190 case TType::STRUCT:
191 $class = $espec['class'];
192 $elem = new $class();
193 $xfer += $elem->read($input);
194 break;
195 case TType::MAP:
David Reiss465ccc02007-11-13 21:41:29 +0000196 $xfer += $this->_readMap($elem, $espec, $input);
Mark Slee5b743072007-11-13 04:00:29 +0000197 break;
198 case TType::LST:
David Reiss465ccc02007-11-13 21:41:29 +0000199 $xfer += $this->_readList($elem, $espec, $input, false);
Mark Slee5b743072007-11-13 04:00:29 +0000200 break;
201 case TType::SET:
David Reiss465ccc02007-11-13 21:41:29 +0000202 $xfer += $this->_readList($elem, $espec, $input, true);
Mark Slee5b743072007-11-13 04:00:29 +0000203 break;
204 }
205 }
206 if ($set) {
207 $var[$elem] = true;
208 } else {
209 $var []= $elem;
210 }
211 }
212 if ($set) {
213 $xfer += $input->readSetEnd();
214 } else {
215 $xfer += $input->readListEnd();
216 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000217
Mark Slee5b743072007-11-13 04:00:29 +0000218 return $xfer;
219 }
220
Roger Thomas6fb59232014-11-04 10:09:23 +0000221 protected function _read($class, $spec, $input)
222 {
Mark Slee5b743072007-11-13 04:00:29 +0000223 $xfer = 0;
224 $fname = null;
225 $ftype = 0;
226 $fid = 0;
227 $xfer += $input->readStructBegin($fname);
Mark Slee5b743072007-11-13 04:00:29 +0000228 while (true) {
229 $xfer += $input->readFieldBegin($fname, $ftype, $fid);
230 if ($ftype == TType::STOP) {
231 break;
232 }
233 if (isset($spec[$fid])) {
234 $fspec = $spec[$fid];
235 $var = $fspec['var'];
236 if ($ftype == $fspec['type']) {
237 $xfer = 0;
Mark Slee645ecea2007-11-28 02:46:24 +0000238 if (isset(TBase::$tmethod[$ftype])) {
239 $func = 'read'.TBase::$tmethod[$ftype];
240 $xfer += $input->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000241 } else {
Mark Slee645ecea2007-11-28 02:46:24 +0000242 switch ($ftype) {
243 case TType::STRUCT:
244 $class = $fspec['class'];
245 $this->$var = new $class();
246 $xfer += $this->$var->read($input);
247 break;
248 case TType::MAP:
249 $xfer += $this->_readMap($this->$var, $fspec, $input);
250 break;
251 case TType::LST:
252 $xfer += $this->_readList($this->$var, $fspec, $input, false);
253 break;
254 case TType::SET:
255 $xfer += $this->_readList($this->$var, $fspec, $input, true);
256 break;
Mark Slee5b743072007-11-13 04:00:29 +0000257 }
258 }
259 } else {
260 $xfer += $input->skip($ftype);
261 }
262 } else {
263 $xfer += $input->skip($ftype);
264 }
265 $xfer += $input->readFieldEnd();
266 }
267 $xfer += $input->readStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000268
Mark Slee5b743072007-11-13 04:00:29 +0000269 return $xfer;
270 }
271
Roger Thomas6fb59232014-11-04 10:09:23 +0000272 private function _writeMap($var, $spec, $output)
273 {
Mark Slee5b743072007-11-13 04:00:29 +0000274 $xfer = 0;
275 $ktype = $spec['ktype'];
276 $vtype = $spec['vtype'];
277 $kwrite = $vwrite = null;
278 if (isset(TBase::$tmethod[$ktype])) {
279 $kwrite = 'write'.TBase::$tmethod[$ktype];
280 } else {
281 $kspec = $spec['key'];
282 }
283 if (isset(TBase::$tmethod[$vtype])) {
284 $vwrite = 'write'.TBase::$tmethod[$vtype];
285 } else {
286 $vspec = $spec['val'];
287 }
288 $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
289 foreach ($var as $key => $val) {
290 if (isset($kwrite)) {
291 $xfer += $output->$kwrite($key);
292 } else {
293 switch ($ktype) {
294 case TType::STRUCT:
295 $xfer += $key->write($output);
296 break;
297 case TType::MAP:
298 $xfer += $this->_writeMap($key, $kspec, $output);
299 break;
300 case TType::LST:
301 $xfer += $this->_writeList($key, $kspec, $output, false);
302 break;
303 case TType::SET:
304 $xfer += $this->_writeList($key, $kspec, $output, true);
305 break;
306 }
307 }
308 if (isset($vwrite)) {
309 $xfer += $output->$vwrite($val);
310 } else {
311 switch ($vtype) {
312 case TType::STRUCT:
313 $xfer += $val->write($output);
314 break;
315 case TType::MAP:
316 $xfer += $this->_writeMap($val, $vspec, $output);
317 break;
318 case TType::LST:
319 $xfer += $this->_writeList($val, $vspec, $output, false);
320 break;
321 case TType::SET:
322 $xfer += $this->_writeList($val, $vspec, $output, true);
323 break;
324 }
325 }
326 }
327 $xfer += $output->writeMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000328
Mark Slee5b743072007-11-13 04:00:29 +0000329 return $xfer;
330 }
331
Roger Thomas6fb59232014-11-04 10:09:23 +0000332 private function _writeList($var, $spec, $output, $set=false)
333 {
Mark Slee5b743072007-11-13 04:00:29 +0000334 $xfer = 0;
335 $etype = $spec['etype'];
336 $ewrite = null;
337 if (isset(TBase::$tmethod[$etype])) {
338 $ewrite = 'write'.TBase::$tmethod[$etype];
339 } else {
340 $espec = $spec['elem'];
341 }
342 if ($set) {
343 $xfer += $output->writeSetBegin($etype, count($var));
344 } else {
345 $xfer += $output->writeListBegin($etype, count($var));
346 }
347 foreach ($var as $key => $val) {
348 $elem = $set ? $key : $val;
349 if (isset($ewrite)) {
350 $xfer += $output->$ewrite($elem);
351 } else {
352 switch ($etype) {
353 case TType::STRUCT:
354 $xfer += $elem->write($output);
355 break;
356 case TType::MAP:
357 $xfer += $this->_writeMap($elem, $espec, $output);
358 break;
359 case TType::LST:
360 $xfer += $this->_writeList($elem, $espec, $output, false);
361 break;
362 case TType::SET:
363 $xfer += $this->_writeList($elem, $espec, $output, true);
364 break;
365 }
366 }
367 }
368 if ($set) {
369 $xfer += $output->writeSetEnd();
370 } else {
371 $xfer += $output->writeListEnd();
372 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000373
Mark Slee5b743072007-11-13 04:00:29 +0000374 return $xfer;
375 }
376
Roger Thomas6fb59232014-11-04 10:09:23 +0000377 protected function _write($class, $spec, $output)
378 {
Mark Slee5b743072007-11-13 04:00:29 +0000379 $xfer = 0;
380 $xfer += $output->writeStructBegin($class);
381 foreach ($spec as $fid => $fspec) {
382 $var = $fspec['var'];
383 if ($this->$var !== null) {
384 $ftype = $fspec['type'];
385 $xfer += $output->writeFieldBegin($var, $ftype, $fid);
386 if (isset(TBase::$tmethod[$ftype])) {
387 $func = 'write'.TBase::$tmethod[$ftype];
Mark Slee2b786222007-11-13 05:35:34 +0000388 $xfer += $output->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000389 } else {
390 switch ($ftype) {
391 case TType::STRUCT:
392 $xfer += $this->$var->write($output);
393 break;
394 case TType::MAP:
395 $xfer += $this->_writeMap($this->$var, $fspec, $output);
396 break;
397 case TType::LST:
398 $xfer += $this->_writeList($this->$var, $fspec, $output, false);
399 break;
400 case TType::SET:
401 $xfer += $this->_writeList($this->$var, $fspec, $output, true);
402 break;
403 }
404 }
405 $xfer += $output->writeFieldEnd();
406 }
407 }
408 $xfer += $output->writeFieldStop();
409 $xfer += $output->writeStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000410
Mark Slee5b743072007-11-13 04:00:29 +0000411 return $xfer;
412 }
413
414}
415
416/**
417 * Base class from which other Thrift structs extend. This is so that we can
418 * cut back on the size of the generated code which is turning out to have a
419 * nontrivial cost just to load thanks to the wondrously abysmal implementation
420 * of PHP. Note that code is intentionally duplicated in here to avoid making
421 * function calls for every field or member of a container..
422 */
Volodymyr Panivkoac52d8d2024-02-22 22:09:00 +0100423#[\AllowDynamicProperties]
Roger Thomas6fb59232014-11-04 10:09:23 +0000424abstract class TBase
425{
Mark Slee5b743072007-11-13 04:00:29 +0000426 static $tmethod = array(TType::BOOL => 'Bool',
427 TType::BYTE => 'Byte',
428 TType::I16 => 'I16',
429 TType::I32 => 'I32',
430 TType::I64 => 'I64',
431 TType::DOUBLE => 'Double',
432 TType::STRING => 'String');
433
Roger Thomas6fb59232014-11-04 10:09:23 +0000434 abstract public function read($input);
Mark Slee5b743072007-11-13 04:00:29 +0000435
Roger Thomas6fb59232014-11-04 10:09:23 +0000436 abstract public function write($output);
Mark Slee5b743072007-11-13 04:00:29 +0000437
Roger Thomas6fb59232014-11-04 10:09:23 +0000438 public function __construct($spec=null, $vals=null)
439 {
Mark Slee5b743072007-11-13 04:00:29 +0000440 if (is_array($spec) && is_array($vals)) {
441 foreach ($spec as $fid => $fspec) {
442 $var = $fspec['var'];
443 if (isset($vals[$var])) {
444 $this->$var = $vals[$var];
445 }
446 }
447 }
448 }
449
Roger Thomas6fb59232014-11-04 10:09:23 +0000450 private function _readMap(&$var, $spec, $input)
451 {
Mark Slee5b743072007-11-13 04:00:29 +0000452 $xfer = 0;
453 $ktype = $spec['ktype'];
454 $vtype = $spec['vtype'];
455 $kread = $vread = null;
456 if (isset(TBase::$tmethod[$ktype])) {
457 $kread = 'read'.TBase::$tmethod[$ktype];
458 } else {
459 $kspec = $spec['key'];
460 }
461 if (isset(TBase::$tmethod[$vtype])) {
462 $vread = 'read'.TBase::$tmethod[$vtype];
463 } else {
464 $vspec = $spec['val'];
465 }
466 $var = array();
467 $_ktype = $_vtype = $size = 0;
468 $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
469 for ($i = 0; $i < $size; ++$i) {
470 $key = $val = null;
471 if ($kread !== null) {
472 $xfer += $input->$kread($key);
473 } else {
474 switch ($ktype) {
475 case TType::STRUCT:
476 $class = $kspec['class'];
477 $key = new $class();
478 $xfer += $key->read($input);
479 break;
480 case TType::MAP:
David Reissbef54c02007-11-28 20:15:11 +0000481 $xfer += $this->_readMap($key, $kspec, $input);
Mark Slee5b743072007-11-13 04:00:29 +0000482 break;
483 case TType::LST:
David Reissbef54c02007-11-28 20:15:11 +0000484 $xfer += $this->_readList($key, $kspec, $input, false);
Mark Slee5b743072007-11-13 04:00:29 +0000485 break;
486 case TType::SET:
David Reissbef54c02007-11-28 20:15:11 +0000487 $xfer += $this->_readList($key, $kspec, $input, true);
Mark Slee5b743072007-11-13 04:00:29 +0000488 break;
489 }
490 }
491 if ($vread !== null) {
492 $xfer += $input->$vread($val);
493 } else {
494 switch ($vtype) {
495 case TType::STRUCT:
496 $class = $vspec['class'];
497 $val = new $class();
498 $xfer += $val->read($input);
499 break;
500 case TType::MAP:
501 $xfer += $this->_readMap($val, $vspec, $input);
502 break;
503 case TType::LST:
504 $xfer += $this->_readList($val, $vspec, $input, false);
505 break;
506 case TType::SET:
507 $xfer += $this->_readList($val, $vspec, $input, true);
508 break;
509 }
510 }
511 $var[$key] = $val;
512 }
513 $xfer += $input->readMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000514
Mark Slee5b743072007-11-13 04:00:29 +0000515 return $xfer;
516 }
517
Roger Thomas6fb59232014-11-04 10:09:23 +0000518 private function _readList(&$var, $spec, $input, $set=false)
519 {
Mark Slee5b743072007-11-13 04:00:29 +0000520 $xfer = 0;
521 $etype = $spec['etype'];
522 $eread = $vread = null;
523 if (isset(TBase::$tmethod[$etype])) {
524 $eread = 'read'.TBase::$tmethod[$etype];
525 } else {
526 $espec = $spec['elem'];
527 }
528 $var = array();
529 $_etype = $size = 0;
530 if ($set) {
531 $xfer += $input->readSetBegin($_etype, $size);
532 } else {
533 $xfer += $input->readListBegin($_etype, $size);
534 }
535 for ($i = 0; $i < $size; ++$i) {
536 $elem = null;
537 if ($eread !== null) {
538 $xfer += $input->$eread($elem);
539 } else {
540 $espec = $spec['elem'];
541 switch ($etype) {
542 case TType::STRUCT:
543 $class = $espec['class'];
544 $elem = new $class();
545 $xfer += $elem->read($input);
546 break;
547 case TType::MAP:
David Reissbef54c02007-11-28 20:15:11 +0000548 $xfer += $this->_readMap($elem, $espec, $input);
Mark Slee5b743072007-11-13 04:00:29 +0000549 break;
550 case TType::LST:
David Reissbef54c02007-11-28 20:15:11 +0000551 $xfer += $this->_readList($elem, $espec, $input, false);
Mark Slee5b743072007-11-13 04:00:29 +0000552 break;
553 case TType::SET:
David Reissbef54c02007-11-28 20:15:11 +0000554 $xfer += $this->_readList($elem, $espec, $input, true);
Mark Slee5b743072007-11-13 04:00:29 +0000555 break;
556 }
557 }
558 if ($set) {
559 $var[$elem] = true;
560 } else {
561 $var []= $elem;
562 }
563 }
564 if ($set) {
565 $xfer += $input->readSetEnd();
566 } else {
567 $xfer += $input->readListEnd();
568 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000569
Mark Slee5b743072007-11-13 04:00:29 +0000570 return $xfer;
571 }
572
Roger Thomas6fb59232014-11-04 10:09:23 +0000573 protected function _read($class, $spec, $input)
574 {
Mark Slee5b743072007-11-13 04:00:29 +0000575 $xfer = 0;
576 $fname = null;
577 $ftype = 0;
578 $fid = 0;
579 $xfer += $input->readStructBegin($fname);
Mark Slee5b743072007-11-13 04:00:29 +0000580 while (true) {
581 $xfer += $input->readFieldBegin($fname, $ftype, $fid);
582 if ($ftype == TType::STOP) {
583 break;
584 }
585 if (isset($spec[$fid])) {
586 $fspec = $spec[$fid];
587 $var = $fspec['var'];
588 if ($ftype == $fspec['type']) {
589 $xfer = 0;
Mark Slee645ecea2007-11-28 02:46:24 +0000590 if (isset(TBase::$tmethod[$ftype])) {
591 $func = 'read'.TBase::$tmethod[$ftype];
592 $xfer += $input->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000593 } else {
Mark Slee645ecea2007-11-28 02:46:24 +0000594 switch ($ftype) {
595 case TType::STRUCT:
596 $class = $fspec['class'];
597 $this->$var = new $class();
598 $xfer += $this->$var->read($input);
599 break;
600 case TType::MAP:
601 $xfer += $this->_readMap($this->$var, $fspec, $input);
602 break;
603 case TType::LST:
604 $xfer += $this->_readList($this->$var, $fspec, $input, false);
605 break;
606 case TType::SET:
607 $xfer += $this->_readList($this->$var, $fspec, $input, true);
608 break;
Mark Slee5b743072007-11-13 04:00:29 +0000609 }
610 }
611 } else {
612 $xfer += $input->skip($ftype);
613 }
614 } else {
615 $xfer += $input->skip($ftype);
616 }
617 $xfer += $input->readFieldEnd();
618 }
619 $xfer += $input->readStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000620
Mark Slee5b743072007-11-13 04:00:29 +0000621 return $xfer;
622 }
623
Roger Thomas6fb59232014-11-04 10:09:23 +0000624 private function _writeMap($var, $spec, $output)
625 {
Mark Slee5b743072007-11-13 04:00:29 +0000626 $xfer = 0;
627 $ktype = $spec['ktype'];
628 $vtype = $spec['vtype'];
629 $kwrite = $vwrite = null;
630 if (isset(TBase::$tmethod[$ktype])) {
631 $kwrite = 'write'.TBase::$tmethod[$ktype];
632 } else {
633 $kspec = $spec['key'];
634 }
635 if (isset(TBase::$tmethod[$vtype])) {
636 $vwrite = 'write'.TBase::$tmethod[$vtype];
637 } else {
638 $vspec = $spec['val'];
639 }
640 $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
641 foreach ($var as $key => $val) {
642 if (isset($kwrite)) {
643 $xfer += $output->$kwrite($key);
644 } else {
645 switch ($ktype) {
646 case TType::STRUCT:
647 $xfer += $key->write($output);
648 break;
649 case TType::MAP:
650 $xfer += $this->_writeMap($key, $kspec, $output);
651 break;
652 case TType::LST:
653 $xfer += $this->_writeList($key, $kspec, $output, false);
654 break;
655 case TType::SET:
656 $xfer += $this->_writeList($key, $kspec, $output, true);
657 break;
658 }
659 }
660 if (isset($vwrite)) {
661 $xfer += $output->$vwrite($val);
662 } else {
663 switch ($vtype) {
664 case TType::STRUCT:
665 $xfer += $val->write($output);
666 break;
667 case TType::MAP:
668 $xfer += $this->_writeMap($val, $vspec, $output);
669 break;
670 case TType::LST:
671 $xfer += $this->_writeList($val, $vspec, $output, false);
672 break;
673 case TType::SET:
674 $xfer += $this->_writeList($val, $vspec, $output, true);
675 break;
676 }
677 }
678 }
679 $xfer += $output->writeMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000680
Mark Slee5b743072007-11-13 04:00:29 +0000681 return $xfer;
682 }
683
Roger Thomas6fb59232014-11-04 10:09:23 +0000684 private function _writeList($var, $spec, $output, $set=false)
685 {
Mark Slee5b743072007-11-13 04:00:29 +0000686 $xfer = 0;
687 $etype = $spec['etype'];
688 $ewrite = null;
689 if (isset(TBase::$tmethod[$etype])) {
690 $ewrite = 'write'.TBase::$tmethod[$etype];
691 } else {
692 $espec = $spec['elem'];
693 }
694 if ($set) {
695 $xfer += $output->writeSetBegin($etype, count($var));
696 } else {
697 $xfer += $output->writeListBegin($etype, count($var));
698 }
699 foreach ($var as $key => $val) {
700 $elem = $set ? $key : $val;
701 if (isset($ewrite)) {
702 $xfer += $output->$ewrite($elem);
703 } else {
704 switch ($etype) {
705 case TType::STRUCT:
706 $xfer += $elem->write($output);
707 break;
708 case TType::MAP:
709 $xfer += $this->_writeMap($elem, $espec, $output);
710 break;
711 case TType::LST:
712 $xfer += $this->_writeList($elem, $espec, $output, false);
713 break;
714 case TType::SET:
715 $xfer += $this->_writeList($elem, $espec, $output, true);
716 break;
717 }
718 }
719 }
720 if ($set) {
721 $xfer += $output->writeSetEnd();
722 } else {
723 $xfer += $output->writeListEnd();
724 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000725
Mark Slee5b743072007-11-13 04:00:29 +0000726 return $xfer;
727 }
728
Roger Thomas6fb59232014-11-04 10:09:23 +0000729 protected function _write($class, $spec, $output)
730 {
Mark Slee5b743072007-11-13 04:00:29 +0000731 $xfer = 0;
732 $xfer += $output->writeStructBegin($class);
733 foreach ($spec as $fid => $fspec) {
734 $var = $fspec['var'];
735 if ($this->$var !== null) {
736 $ftype = $fspec['type'];
737 $xfer += $output->writeFieldBegin($var, $ftype, $fid);
738 if (isset(TBase::$tmethod[$ftype])) {
739 $func = 'write'.TBase::$tmethod[$ftype];
Mark Slee2b786222007-11-13 05:35:34 +0000740 $xfer += $output->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000741 } else {
742 switch ($ftype) {
743 case TType::STRUCT:
744 $xfer += $this->$var->write($output);
745 break;
746 case TType::MAP:
747 $xfer += $this->_writeMap($this->$var, $fspec, $output);
748 break;
749 case TType::LST:
750 $xfer += $this->_writeList($this->$var, $fspec, $output, false);
751 break;
752 case TType::SET:
753 $xfer += $this->_writeList($this->$var, $fspec, $output, true);
754 break;
755 }
756 }
757 $xfer += $output->writeFieldEnd();
758 }
759 }
760 $xfer += $output->writeFieldStop();
761 $xfer += $output->writeStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000762
Mark Slee5b743072007-11-13 04:00:29 +0000763 return $xfer;
Mark Sleedac78562007-02-21 07:35:03 +0000764 }
765}
766
Roger Thomas6fb59232014-11-04 10:09:23 +0000767class TApplicationException extends TException
768{
Mark Slee5b743072007-11-13 04:00:29 +0000769 static $_TSPEC =
770 array(1 => array('var' => 'message',
771 'type' => TType::STRING),
772 2 => array('var' => 'code',
773 'type' => TType::I32));
774
Mark Sleedac78562007-02-21 07:35:03 +0000775 const UNKNOWN = 0;
776 const UNKNOWN_METHOD = 1;
777 const INVALID_MESSAGE_TYPE = 2;
778 const WRONG_METHOD_NAME = 3;
779 const BAD_SEQUENCE_ID = 4;
780 const MISSING_RESULT = 5;
Bryan Duxburyd26cb9b2011-04-11 17:59:27 +0000781 const INTERNAL_ERROR = 6;
782 const PROTOCOL_ERROR = 7;
Mark Sleedac78562007-02-21 07:35:03 +0000783
Roger Thomas6fb59232014-11-04 10:09:23 +0000784 public function __construct($message=null, $code=0)
785 {
Mark Sleedac78562007-02-21 07:35:03 +0000786 parent::__construct($message, $code);
787 }
788
Roger Thomas6fb59232014-11-04 10:09:23 +0000789 public function read($output)
790 {
Mark Slee5b743072007-11-13 04:00:29 +0000791 return $this->_read('TApplicationException', self::$_TSPEC, $output);
Mark Sleedac78562007-02-21 07:35:03 +0000792 }
793
Roger Thomas6fb59232014-11-04 10:09:23 +0000794 public function write($output)
795 {
Mark Sleedac78562007-02-21 07:35:03 +0000796 $xfer = 0;
797 $xfer += $output->writeStructBegin('TApplicationException');
Mark Slee5b743072007-11-13 04:00:29 +0000798 if ($message = $this->getMessage()) {
Mark Sleedac78562007-02-21 07:35:03 +0000799 $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
Mark Slee5b743072007-11-13 04:00:29 +0000800 $xfer += $output->writeString($message);
Mark Sleedac78562007-02-21 07:35:03 +0000801 $xfer += $output->writeFieldEnd();
802 }
Mark Slee5b743072007-11-13 04:00:29 +0000803 if ($code = $this->getCode()) {
Mark Sleedac78562007-02-21 07:35:03 +0000804 $xfer += $output->writeFieldBegin('type', TType::I32, 2);
Mark Slee5b743072007-11-13 04:00:29 +0000805 $xfer += $output->writeI32($code);
Mark Sleedac78562007-02-21 07:35:03 +0000806 $xfer += $output->writeFieldEnd();
807 }
808 $xfer += $output->writeFieldStop();
809 $xfer += $output->writeStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000810
Mark Sleedac78562007-02-21 07:35:03 +0000811 return $xfer;
812 }
813}
814
Mark Slee1ecb1b02007-02-22 01:01:10 +0000815/**
816 * Set global THRIFT ROOT automatically via inclusion here
817 */
818if (!isset($GLOBALS['THRIFT_ROOT'])) {
819 $GLOBALS['THRIFT_ROOT'] = dirname(__FILE__);
820}
821include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TProtocol.php';
822include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php';
Jake Farrellb03a59c2011-11-29 16:45:51 +0000823include_once $GLOBALS['THRIFT_ROOT'].'/TStringUtils.php';