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