blob: 0364c90812f699d49c7edd85321fdbfa09df80c3 [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 */
Roger Thomas6fb59232014-11-04 10:09:23 +000071class TException extends Exception
72{
73 public function __construct($p1=null, $p2=0)
74 {
Mark Slee5b743072007-11-13 04:00:29 +000075 if (is_array($p1) && is_array($p2)) {
76 $spec = $p1;
77 $vals = $p2;
78 foreach ($spec as $fid => $fspec) {
79 $var = $fspec['var'];
80 if (isset($vals[$var])) {
81 $this->$var = $vals[$var];
82 }
83 }
84 } else {
vladimir.panivko3abf7ec2023-07-06 08:55:46 +020085 parent::__construct((string)$p1, $p2);
Mark Slee5b743072007-11-13 04:00:29 +000086 }
87 }
88
89 static $tmethod = array(TType::BOOL => 'Bool',
90 TType::BYTE => 'Byte',
91 TType::I16 => 'I16',
92 TType::I32 => 'I32',
93 TType::I64 => 'I64',
94 TType::DOUBLE => 'Double',
95 TType::STRING => 'String');
96
Roger Thomas6fb59232014-11-04 10:09:23 +000097 private function _readMap(&$var, $spec, $input)
98 {
Mark Slee5b743072007-11-13 04:00:29 +000099 $xfer = 0;
100 $ktype = $spec['ktype'];
101 $vtype = $spec['vtype'];
102 $kread = $vread = null;
103 if (isset(TBase::$tmethod[$ktype])) {
104 $kread = 'read'.TBase::$tmethod[$ktype];
105 } else {
106 $kspec = $spec['key'];
107 }
108 if (isset(TBase::$tmethod[$vtype])) {
109 $vread = 'read'.TBase::$tmethod[$vtype];
110 } else {
111 $vspec = $spec['val'];
112 }
113 $var = array();
114 $_ktype = $_vtype = $size = 0;
115 $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
116 for ($i = 0; $i < $size; ++$i) {
117 $key = $val = null;
118 if ($kread !== null) {
119 $xfer += $input->$kread($key);
120 } else {
121 switch ($ktype) {
122 case TType::STRUCT:
123 $class = $kspec['class'];
124 $key = new $class();
125 $xfer += $key->read($input);
126 break;
127 case TType::MAP:
128 $xfer += $this->_readMap($key, $kspec, $input);
129 break;
130 case TType::LST:
131 $xfer += $this->_readList($key, $kspec, $input, false);
132 break;
133 case TType::SET:
134 $xfer += $this->_readList($key, $kspec, $input, true);
135 break;
136 }
137 }
138 if ($vread !== null) {
139 $xfer += $input->$vread($val);
140 } else {
141 switch ($vtype) {
142 case TType::STRUCT:
143 $class = $vspec['class'];
144 $val = new $class();
145 $xfer += $val->read($input);
146 break;
147 case TType::MAP:
148 $xfer += $this->_readMap($val, $vspec, $input);
149 break;
150 case TType::LST:
151 $xfer += $this->_readList($val, $vspec, $input, false);
152 break;
153 case TType::SET:
154 $xfer += $this->_readList($val, $vspec, $input, true);
155 break;
156 }
157 }
158 $var[$key] = $val;
159 }
160 $xfer += $input->readMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000161
Mark Slee5b743072007-11-13 04:00:29 +0000162 return $xfer;
163 }
164
Roger Thomas6fb59232014-11-04 10:09:23 +0000165 private function _readList(&$var, $spec, $input, $set=false)
166 {
Mark Slee5b743072007-11-13 04:00:29 +0000167 $xfer = 0;
168 $etype = $spec['etype'];
169 $eread = $vread = null;
170 if (isset(TBase::$tmethod[$etype])) {
171 $eread = 'read'.TBase::$tmethod[$etype];
172 } else {
173 $espec = $spec['elem'];
174 }
175 $var = array();
176 $_etype = $size = 0;
177 if ($set) {
178 $xfer += $input->readSetBegin($_etype, $size);
179 } else {
180 $xfer += $input->readListBegin($_etype, $size);
181 }
182 for ($i = 0; $i < $size; ++$i) {
183 $elem = null;
184 if ($eread !== null) {
185 $xfer += $input->$eread($elem);
186 } else {
187 $espec = $spec['elem'];
188 switch ($etype) {
189 case TType::STRUCT:
190 $class = $espec['class'];
191 $elem = new $class();
192 $xfer += $elem->read($input);
193 break;
194 case TType::MAP:
David Reiss465ccc02007-11-13 21:41:29 +0000195 $xfer += $this->_readMap($elem, $espec, $input);
Mark Slee5b743072007-11-13 04:00:29 +0000196 break;
197 case TType::LST:
David Reiss465ccc02007-11-13 21:41:29 +0000198 $xfer += $this->_readList($elem, $espec, $input, false);
Mark Slee5b743072007-11-13 04:00:29 +0000199 break;
200 case TType::SET:
David Reiss465ccc02007-11-13 21:41:29 +0000201 $xfer += $this->_readList($elem, $espec, $input, true);
Mark Slee5b743072007-11-13 04:00:29 +0000202 break;
203 }
204 }
205 if ($set) {
206 $var[$elem] = true;
207 } else {
208 $var []= $elem;
209 }
210 }
211 if ($set) {
212 $xfer += $input->readSetEnd();
213 } else {
214 $xfer += $input->readListEnd();
215 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000216
Mark Slee5b743072007-11-13 04:00:29 +0000217 return $xfer;
218 }
219
Roger Thomas6fb59232014-11-04 10:09:23 +0000220 protected function _read($class, $spec, $input)
221 {
Mark Slee5b743072007-11-13 04:00:29 +0000222 $xfer = 0;
223 $fname = null;
224 $ftype = 0;
225 $fid = 0;
226 $xfer += $input->readStructBegin($fname);
Mark Slee5b743072007-11-13 04:00:29 +0000227 while (true) {
228 $xfer += $input->readFieldBegin($fname, $ftype, $fid);
229 if ($ftype == TType::STOP) {
230 break;
231 }
232 if (isset($spec[$fid])) {
233 $fspec = $spec[$fid];
234 $var = $fspec['var'];
235 if ($ftype == $fspec['type']) {
236 $xfer = 0;
Mark Slee645ecea2007-11-28 02:46:24 +0000237 if (isset(TBase::$tmethod[$ftype])) {
238 $func = 'read'.TBase::$tmethod[$ftype];
239 $xfer += $input->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000240 } else {
Mark Slee645ecea2007-11-28 02:46:24 +0000241 switch ($ftype) {
242 case TType::STRUCT:
243 $class = $fspec['class'];
244 $this->$var = new $class();
245 $xfer += $this->$var->read($input);
246 break;
247 case TType::MAP:
248 $xfer += $this->_readMap($this->$var, $fspec, $input);
249 break;
250 case TType::LST:
251 $xfer += $this->_readList($this->$var, $fspec, $input, false);
252 break;
253 case TType::SET:
254 $xfer += $this->_readList($this->$var, $fspec, $input, true);
255 break;
Mark Slee5b743072007-11-13 04:00:29 +0000256 }
257 }
258 } else {
259 $xfer += $input->skip($ftype);
260 }
261 } else {
262 $xfer += $input->skip($ftype);
263 }
264 $xfer += $input->readFieldEnd();
265 }
266 $xfer += $input->readStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000267
Mark Slee5b743072007-11-13 04:00:29 +0000268 return $xfer;
269 }
270
Roger Thomas6fb59232014-11-04 10:09:23 +0000271 private function _writeMap($var, $spec, $output)
272 {
Mark Slee5b743072007-11-13 04:00:29 +0000273 $xfer = 0;
274 $ktype = $spec['ktype'];
275 $vtype = $spec['vtype'];
276 $kwrite = $vwrite = null;
277 if (isset(TBase::$tmethod[$ktype])) {
278 $kwrite = 'write'.TBase::$tmethod[$ktype];
279 } else {
280 $kspec = $spec['key'];
281 }
282 if (isset(TBase::$tmethod[$vtype])) {
283 $vwrite = 'write'.TBase::$tmethod[$vtype];
284 } else {
285 $vspec = $spec['val'];
286 }
287 $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
288 foreach ($var as $key => $val) {
289 if (isset($kwrite)) {
290 $xfer += $output->$kwrite($key);
291 } else {
292 switch ($ktype) {
293 case TType::STRUCT:
294 $xfer += $key->write($output);
295 break;
296 case TType::MAP:
297 $xfer += $this->_writeMap($key, $kspec, $output);
298 break;
299 case TType::LST:
300 $xfer += $this->_writeList($key, $kspec, $output, false);
301 break;
302 case TType::SET:
303 $xfer += $this->_writeList($key, $kspec, $output, true);
304 break;
305 }
306 }
307 if (isset($vwrite)) {
308 $xfer += $output->$vwrite($val);
309 } else {
310 switch ($vtype) {
311 case TType::STRUCT:
312 $xfer += $val->write($output);
313 break;
314 case TType::MAP:
315 $xfer += $this->_writeMap($val, $vspec, $output);
316 break;
317 case TType::LST:
318 $xfer += $this->_writeList($val, $vspec, $output, false);
319 break;
320 case TType::SET:
321 $xfer += $this->_writeList($val, $vspec, $output, true);
322 break;
323 }
324 }
325 }
326 $xfer += $output->writeMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000327
Mark Slee5b743072007-11-13 04:00:29 +0000328 return $xfer;
329 }
330
Roger Thomas6fb59232014-11-04 10:09:23 +0000331 private function _writeList($var, $spec, $output, $set=false)
332 {
Mark Slee5b743072007-11-13 04:00:29 +0000333 $xfer = 0;
334 $etype = $spec['etype'];
335 $ewrite = null;
336 if (isset(TBase::$tmethod[$etype])) {
337 $ewrite = 'write'.TBase::$tmethod[$etype];
338 } else {
339 $espec = $spec['elem'];
340 }
341 if ($set) {
342 $xfer += $output->writeSetBegin($etype, count($var));
343 } else {
344 $xfer += $output->writeListBegin($etype, count($var));
345 }
346 foreach ($var as $key => $val) {
347 $elem = $set ? $key : $val;
348 if (isset($ewrite)) {
349 $xfer += $output->$ewrite($elem);
350 } else {
351 switch ($etype) {
352 case TType::STRUCT:
353 $xfer += $elem->write($output);
354 break;
355 case TType::MAP:
356 $xfer += $this->_writeMap($elem, $espec, $output);
357 break;
358 case TType::LST:
359 $xfer += $this->_writeList($elem, $espec, $output, false);
360 break;
361 case TType::SET:
362 $xfer += $this->_writeList($elem, $espec, $output, true);
363 break;
364 }
365 }
366 }
367 if ($set) {
368 $xfer += $output->writeSetEnd();
369 } else {
370 $xfer += $output->writeListEnd();
371 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000372
Mark Slee5b743072007-11-13 04:00:29 +0000373 return $xfer;
374 }
375
Roger Thomas6fb59232014-11-04 10:09:23 +0000376 protected function _write($class, $spec, $output)
377 {
Mark Slee5b743072007-11-13 04:00:29 +0000378 $xfer = 0;
379 $xfer += $output->writeStructBegin($class);
380 foreach ($spec as $fid => $fspec) {
381 $var = $fspec['var'];
382 if ($this->$var !== null) {
383 $ftype = $fspec['type'];
384 $xfer += $output->writeFieldBegin($var, $ftype, $fid);
385 if (isset(TBase::$tmethod[$ftype])) {
386 $func = 'write'.TBase::$tmethod[$ftype];
Mark Slee2b786222007-11-13 05:35:34 +0000387 $xfer += $output->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000388 } else {
389 switch ($ftype) {
390 case TType::STRUCT:
391 $xfer += $this->$var->write($output);
392 break;
393 case TType::MAP:
394 $xfer += $this->_writeMap($this->$var, $fspec, $output);
395 break;
396 case TType::LST:
397 $xfer += $this->_writeList($this->$var, $fspec, $output, false);
398 break;
399 case TType::SET:
400 $xfer += $this->_writeList($this->$var, $fspec, $output, true);
401 break;
402 }
403 }
404 $xfer += $output->writeFieldEnd();
405 }
406 }
407 $xfer += $output->writeFieldStop();
408 $xfer += $output->writeStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000409
Mark Slee5b743072007-11-13 04:00:29 +0000410 return $xfer;
411 }
412
413}
414
415/**
416 * Base class from which other Thrift structs extend. This is so that we can
417 * cut back on the size of the generated code which is turning out to have a
418 * nontrivial cost just to load thanks to the wondrously abysmal implementation
419 * of PHP. Note that code is intentionally duplicated in here to avoid making
420 * function calls for every field or member of a container..
421 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000422abstract class TBase
423{
Mark Slee5b743072007-11-13 04:00:29 +0000424 static $tmethod = array(TType::BOOL => 'Bool',
425 TType::BYTE => 'Byte',
426 TType::I16 => 'I16',
427 TType::I32 => 'I32',
428 TType::I64 => 'I64',
429 TType::DOUBLE => 'Double',
430 TType::STRING => 'String');
431
Roger Thomas6fb59232014-11-04 10:09:23 +0000432 abstract public function read($input);
Mark Slee5b743072007-11-13 04:00:29 +0000433
Roger Thomas6fb59232014-11-04 10:09:23 +0000434 abstract public function write($output);
Mark Slee5b743072007-11-13 04:00:29 +0000435
Roger Thomas6fb59232014-11-04 10:09:23 +0000436 public function __construct($spec=null, $vals=null)
437 {
Mark Slee5b743072007-11-13 04:00:29 +0000438 if (is_array($spec) && is_array($vals)) {
439 foreach ($spec as $fid => $fspec) {
440 $var = $fspec['var'];
441 if (isset($vals[$var])) {
442 $this->$var = $vals[$var];
443 }
444 }
445 }
446 }
447
Roger Thomas6fb59232014-11-04 10:09:23 +0000448 private function _readMap(&$var, $spec, $input)
449 {
Mark Slee5b743072007-11-13 04:00:29 +0000450 $xfer = 0;
451 $ktype = $spec['ktype'];
452 $vtype = $spec['vtype'];
453 $kread = $vread = null;
454 if (isset(TBase::$tmethod[$ktype])) {
455 $kread = 'read'.TBase::$tmethod[$ktype];
456 } else {
457 $kspec = $spec['key'];
458 }
459 if (isset(TBase::$tmethod[$vtype])) {
460 $vread = 'read'.TBase::$tmethod[$vtype];
461 } else {
462 $vspec = $spec['val'];
463 }
464 $var = array();
465 $_ktype = $_vtype = $size = 0;
466 $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
467 for ($i = 0; $i < $size; ++$i) {
468 $key = $val = null;
469 if ($kread !== null) {
470 $xfer += $input->$kread($key);
471 } else {
472 switch ($ktype) {
473 case TType::STRUCT:
474 $class = $kspec['class'];
475 $key = new $class();
476 $xfer += $key->read($input);
477 break;
478 case TType::MAP:
David Reissbef54c02007-11-28 20:15:11 +0000479 $xfer += $this->_readMap($key, $kspec, $input);
Mark Slee5b743072007-11-13 04:00:29 +0000480 break;
481 case TType::LST:
David Reissbef54c02007-11-28 20:15:11 +0000482 $xfer += $this->_readList($key, $kspec, $input, false);
Mark Slee5b743072007-11-13 04:00:29 +0000483 break;
484 case TType::SET:
David Reissbef54c02007-11-28 20:15:11 +0000485 $xfer += $this->_readList($key, $kspec, $input, true);
Mark Slee5b743072007-11-13 04:00:29 +0000486 break;
487 }
488 }
489 if ($vread !== null) {
490 $xfer += $input->$vread($val);
491 } else {
492 switch ($vtype) {
493 case TType::STRUCT:
494 $class = $vspec['class'];
495 $val = new $class();
496 $xfer += $val->read($input);
497 break;
498 case TType::MAP:
499 $xfer += $this->_readMap($val, $vspec, $input);
500 break;
501 case TType::LST:
502 $xfer += $this->_readList($val, $vspec, $input, false);
503 break;
504 case TType::SET:
505 $xfer += $this->_readList($val, $vspec, $input, true);
506 break;
507 }
508 }
509 $var[$key] = $val;
510 }
511 $xfer += $input->readMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000512
Mark Slee5b743072007-11-13 04:00:29 +0000513 return $xfer;
514 }
515
Roger Thomas6fb59232014-11-04 10:09:23 +0000516 private function _readList(&$var, $spec, $input, $set=false)
517 {
Mark Slee5b743072007-11-13 04:00:29 +0000518 $xfer = 0;
519 $etype = $spec['etype'];
520 $eread = $vread = null;
521 if (isset(TBase::$tmethod[$etype])) {
522 $eread = 'read'.TBase::$tmethod[$etype];
523 } else {
524 $espec = $spec['elem'];
525 }
526 $var = array();
527 $_etype = $size = 0;
528 if ($set) {
529 $xfer += $input->readSetBegin($_etype, $size);
530 } else {
531 $xfer += $input->readListBegin($_etype, $size);
532 }
533 for ($i = 0; $i < $size; ++$i) {
534 $elem = null;
535 if ($eread !== null) {
536 $xfer += $input->$eread($elem);
537 } else {
538 $espec = $spec['elem'];
539 switch ($etype) {
540 case TType::STRUCT:
541 $class = $espec['class'];
542 $elem = new $class();
543 $xfer += $elem->read($input);
544 break;
545 case TType::MAP:
David Reissbef54c02007-11-28 20:15:11 +0000546 $xfer += $this->_readMap($elem, $espec, $input);
Mark Slee5b743072007-11-13 04:00:29 +0000547 break;
548 case TType::LST:
David Reissbef54c02007-11-28 20:15:11 +0000549 $xfer += $this->_readList($elem, $espec, $input, false);
Mark Slee5b743072007-11-13 04:00:29 +0000550 break;
551 case TType::SET:
David Reissbef54c02007-11-28 20:15:11 +0000552 $xfer += $this->_readList($elem, $espec, $input, true);
Mark Slee5b743072007-11-13 04:00:29 +0000553 break;
554 }
555 }
556 if ($set) {
557 $var[$elem] = true;
558 } else {
559 $var []= $elem;
560 }
561 }
562 if ($set) {
563 $xfer += $input->readSetEnd();
564 } else {
565 $xfer += $input->readListEnd();
566 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000567
Mark Slee5b743072007-11-13 04:00:29 +0000568 return $xfer;
569 }
570
Roger Thomas6fb59232014-11-04 10:09:23 +0000571 protected function _read($class, $spec, $input)
572 {
Mark Slee5b743072007-11-13 04:00:29 +0000573 $xfer = 0;
574 $fname = null;
575 $ftype = 0;
576 $fid = 0;
577 $xfer += $input->readStructBegin($fname);
Mark Slee5b743072007-11-13 04:00:29 +0000578 while (true) {
579 $xfer += $input->readFieldBegin($fname, $ftype, $fid);
580 if ($ftype == TType::STOP) {
581 break;
582 }
583 if (isset($spec[$fid])) {
584 $fspec = $spec[$fid];
585 $var = $fspec['var'];
586 if ($ftype == $fspec['type']) {
587 $xfer = 0;
Mark Slee645ecea2007-11-28 02:46:24 +0000588 if (isset(TBase::$tmethod[$ftype])) {
589 $func = 'read'.TBase::$tmethod[$ftype];
590 $xfer += $input->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000591 } else {
Mark Slee645ecea2007-11-28 02:46:24 +0000592 switch ($ftype) {
593 case TType::STRUCT:
594 $class = $fspec['class'];
595 $this->$var = new $class();
596 $xfer += $this->$var->read($input);
597 break;
598 case TType::MAP:
599 $xfer += $this->_readMap($this->$var, $fspec, $input);
600 break;
601 case TType::LST:
602 $xfer += $this->_readList($this->$var, $fspec, $input, false);
603 break;
604 case TType::SET:
605 $xfer += $this->_readList($this->$var, $fspec, $input, true);
606 break;
Mark Slee5b743072007-11-13 04:00:29 +0000607 }
608 }
609 } else {
610 $xfer += $input->skip($ftype);
611 }
612 } else {
613 $xfer += $input->skip($ftype);
614 }
615 $xfer += $input->readFieldEnd();
616 }
617 $xfer += $input->readStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000618
Mark Slee5b743072007-11-13 04:00:29 +0000619 return $xfer;
620 }
621
Roger Thomas6fb59232014-11-04 10:09:23 +0000622 private function _writeMap($var, $spec, $output)
623 {
Mark Slee5b743072007-11-13 04:00:29 +0000624 $xfer = 0;
625 $ktype = $spec['ktype'];
626 $vtype = $spec['vtype'];
627 $kwrite = $vwrite = null;
628 if (isset(TBase::$tmethod[$ktype])) {
629 $kwrite = 'write'.TBase::$tmethod[$ktype];
630 } else {
631 $kspec = $spec['key'];
632 }
633 if (isset(TBase::$tmethod[$vtype])) {
634 $vwrite = 'write'.TBase::$tmethod[$vtype];
635 } else {
636 $vspec = $spec['val'];
637 }
638 $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
639 foreach ($var as $key => $val) {
640 if (isset($kwrite)) {
641 $xfer += $output->$kwrite($key);
642 } else {
643 switch ($ktype) {
644 case TType::STRUCT:
645 $xfer += $key->write($output);
646 break;
647 case TType::MAP:
648 $xfer += $this->_writeMap($key, $kspec, $output);
649 break;
650 case TType::LST:
651 $xfer += $this->_writeList($key, $kspec, $output, false);
652 break;
653 case TType::SET:
654 $xfer += $this->_writeList($key, $kspec, $output, true);
655 break;
656 }
657 }
658 if (isset($vwrite)) {
659 $xfer += $output->$vwrite($val);
660 } else {
661 switch ($vtype) {
662 case TType::STRUCT:
663 $xfer += $val->write($output);
664 break;
665 case TType::MAP:
666 $xfer += $this->_writeMap($val, $vspec, $output);
667 break;
668 case TType::LST:
669 $xfer += $this->_writeList($val, $vspec, $output, false);
670 break;
671 case TType::SET:
672 $xfer += $this->_writeList($val, $vspec, $output, true);
673 break;
674 }
675 }
676 }
677 $xfer += $output->writeMapEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000678
Mark Slee5b743072007-11-13 04:00:29 +0000679 return $xfer;
680 }
681
Roger Thomas6fb59232014-11-04 10:09:23 +0000682 private function _writeList($var, $spec, $output, $set=false)
683 {
Mark Slee5b743072007-11-13 04:00:29 +0000684 $xfer = 0;
685 $etype = $spec['etype'];
686 $ewrite = null;
687 if (isset(TBase::$tmethod[$etype])) {
688 $ewrite = 'write'.TBase::$tmethod[$etype];
689 } else {
690 $espec = $spec['elem'];
691 }
692 if ($set) {
693 $xfer += $output->writeSetBegin($etype, count($var));
694 } else {
695 $xfer += $output->writeListBegin($etype, count($var));
696 }
697 foreach ($var as $key => $val) {
698 $elem = $set ? $key : $val;
699 if (isset($ewrite)) {
700 $xfer += $output->$ewrite($elem);
701 } else {
702 switch ($etype) {
703 case TType::STRUCT:
704 $xfer += $elem->write($output);
705 break;
706 case TType::MAP:
707 $xfer += $this->_writeMap($elem, $espec, $output);
708 break;
709 case TType::LST:
710 $xfer += $this->_writeList($elem, $espec, $output, false);
711 break;
712 case TType::SET:
713 $xfer += $this->_writeList($elem, $espec, $output, true);
714 break;
715 }
716 }
717 }
718 if ($set) {
719 $xfer += $output->writeSetEnd();
720 } else {
721 $xfer += $output->writeListEnd();
722 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000723
Mark Slee5b743072007-11-13 04:00:29 +0000724 return $xfer;
725 }
726
Roger Thomas6fb59232014-11-04 10:09:23 +0000727 protected function _write($class, $spec, $output)
728 {
Mark Slee5b743072007-11-13 04:00:29 +0000729 $xfer = 0;
730 $xfer += $output->writeStructBegin($class);
731 foreach ($spec as $fid => $fspec) {
732 $var = $fspec['var'];
733 if ($this->$var !== null) {
734 $ftype = $fspec['type'];
735 $xfer += $output->writeFieldBegin($var, $ftype, $fid);
736 if (isset(TBase::$tmethod[$ftype])) {
737 $func = 'write'.TBase::$tmethod[$ftype];
Mark Slee2b786222007-11-13 05:35:34 +0000738 $xfer += $output->$func($this->$var);
Mark Slee5b743072007-11-13 04:00:29 +0000739 } else {
740 switch ($ftype) {
741 case TType::STRUCT:
742 $xfer += $this->$var->write($output);
743 break;
744 case TType::MAP:
745 $xfer += $this->_writeMap($this->$var, $fspec, $output);
746 break;
747 case TType::LST:
748 $xfer += $this->_writeList($this->$var, $fspec, $output, false);
749 break;
750 case TType::SET:
751 $xfer += $this->_writeList($this->$var, $fspec, $output, true);
752 break;
753 }
754 }
755 $xfer += $output->writeFieldEnd();
756 }
757 }
758 $xfer += $output->writeFieldStop();
759 $xfer += $output->writeStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000760
Mark Slee5b743072007-11-13 04:00:29 +0000761 return $xfer;
Mark Sleedac78562007-02-21 07:35:03 +0000762 }
763}
764
Roger Thomas6fb59232014-11-04 10:09:23 +0000765class TApplicationException extends TException
766{
Mark Slee5b743072007-11-13 04:00:29 +0000767 static $_TSPEC =
768 array(1 => array('var' => 'message',
769 'type' => TType::STRING),
770 2 => array('var' => 'code',
771 'type' => TType::I32));
772
Mark Sleedac78562007-02-21 07:35:03 +0000773 const UNKNOWN = 0;
774 const UNKNOWN_METHOD = 1;
775 const INVALID_MESSAGE_TYPE = 2;
776 const WRONG_METHOD_NAME = 3;
777 const BAD_SEQUENCE_ID = 4;
778 const MISSING_RESULT = 5;
Bryan Duxburyd26cb9b2011-04-11 17:59:27 +0000779 const INTERNAL_ERROR = 6;
780 const PROTOCOL_ERROR = 7;
Mark Sleedac78562007-02-21 07:35:03 +0000781
Roger Thomas6fb59232014-11-04 10:09:23 +0000782 public function __construct($message=null, $code=0)
783 {
Mark Sleedac78562007-02-21 07:35:03 +0000784 parent::__construct($message, $code);
785 }
786
Roger Thomas6fb59232014-11-04 10:09:23 +0000787 public function read($output)
788 {
Mark Slee5b743072007-11-13 04:00:29 +0000789 return $this->_read('TApplicationException', self::$_TSPEC, $output);
Mark Sleedac78562007-02-21 07:35:03 +0000790 }
791
Roger Thomas6fb59232014-11-04 10:09:23 +0000792 public function write($output)
793 {
Mark Sleedac78562007-02-21 07:35:03 +0000794 $xfer = 0;
795 $xfer += $output->writeStructBegin('TApplicationException');
Mark Slee5b743072007-11-13 04:00:29 +0000796 if ($message = $this->getMessage()) {
Mark Sleedac78562007-02-21 07:35:03 +0000797 $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
Mark Slee5b743072007-11-13 04:00:29 +0000798 $xfer += $output->writeString($message);
Mark Sleedac78562007-02-21 07:35:03 +0000799 $xfer += $output->writeFieldEnd();
800 }
Mark Slee5b743072007-11-13 04:00:29 +0000801 if ($code = $this->getCode()) {
Mark Sleedac78562007-02-21 07:35:03 +0000802 $xfer += $output->writeFieldBegin('type', TType::I32, 2);
Mark Slee5b743072007-11-13 04:00:29 +0000803 $xfer += $output->writeI32($code);
Mark Sleedac78562007-02-21 07:35:03 +0000804 $xfer += $output->writeFieldEnd();
805 }
806 $xfer += $output->writeFieldStop();
807 $xfer += $output->writeStructEnd();
Roger Thomas6fb59232014-11-04 10:09:23 +0000808
Mark Sleedac78562007-02-21 07:35:03 +0000809 return $xfer;
810 }
811}
812
Mark Slee1ecb1b02007-02-22 01:01:10 +0000813/**
814 * Set global THRIFT ROOT automatically via inclusion here
815 */
816if (!isset($GLOBALS['THRIFT_ROOT'])) {
817 $GLOBALS['THRIFT_ROOT'] = dirname(__FILE__);
818}
819include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TProtocol.php';
820include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php';
Jake Farrellb03a59c2011-11-29 16:45:51 +0000821include_once $GLOBALS['THRIFT_ROOT'].'/TStringUtils.php';