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/** 24 * Data types that can be sent via Thrift 25 */ 26class TType 27{ 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; 45} 46 47/** 48 * Message types for RPC 49 */ 50class TMessageType 51{ 52 const CALL = 1; 53 const REPLY = 2; 54 const EXCEPTION = 3; 55 const ONEWAY = 4; 56} 57 58/** 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 */ 71class TException extends Exception 72{ 73 public function __construct($p1=null, $p2=0) 74 { 75 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 { 85 parent::__construct($p1, $p2); 86 } 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 97 private function _readMap(&$var, $spec, $input) 98 { 99 $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(); 161 162 return $xfer; 163 } 164 165 private function _readList(&$var, $spec, $input, $set=false) 166 { 167 $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: 195 $xfer += $this->_readMap($elem, $espec, $input); 196 break; 197 case TType::LST: 198 $xfer += $this->_readList($elem, $espec, $input, false); 199 break; 200 case TType::SET: 201 $xfer += $this->_readList($elem, $espec, $input, true); 202 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 } 216 217 return $xfer; 218 } 219 220 protected function _read($class, $spec, $input) 221 { 222 $xfer = 0; 223 $fname = null; 224 $ftype = 0; 225 $fid = 0; 226 $xfer += $input->readStructBegin($fname); 227 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; 237 if (isset(TBase::$tmethod[$ftype])) { 238 $func = 'read'.TBase::$tmethod[$ftype]; 239 $xfer += $input->$func($this->$var); 240 } else { 241 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; 256 } 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(); 267 268 return $xfer; 269 } 270 271 private function _writeMap($var, $spec, $output) 272 { 273 $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(); 327 328 return $xfer; 329 } 330 331 private function _writeList($var, $spec, $output, $set=false) 332 { 333 $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 } 372 373 return $xfer; 374 } 375 376 protected function _write($class, $spec, $output) 377 { 378 $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]; 387 $xfer += $output->$func($this->$var); 388 } 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(); 409 410 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 */ 422abstract class TBase 423{ 424 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 432 abstract public function read($input); 433 434 abstract public function write($output); 435 436 public function __construct($spec=null, $vals=null) 437 { 438 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 448 private function _readMap(&$var, $spec, $input) 449 { 450 $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: 479 $xfer += $this->_readMap($key, $kspec, $input); 480 break; 481 case TType::LST: 482 $xfer += $this->_readList($key, $kspec, $input, false); 483 break; 484 case TType::SET: 485 $xfer += $this->_readList($key, $kspec, $input, true); 486 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(); 512 513 return $xfer; 514 } 515 516 private function _readList(&$var, $spec, $input, $set=false) 517 { 518 $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: 546 $xfer += $this->_readMap($elem, $espec, $input); 547 break; 548 case TType::LST: 549 $xfer += $this->_readList($elem, $espec, $input, false); 550 break; 551 case TType::SET: 552 $xfer += $this->_readList($elem, $espec, $input, true); 553 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 } 567 568 return $xfer; 569 } 570 571 protected function _read($class, $spec, $input) 572 { 573 $xfer = 0; 574 $fname = null; 575 $ftype = 0; 576 $fid = 0; 577 $xfer += $input->readStructBegin($fname); 578 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; 588 if (isset(TBase::$tmethod[$ftype])) { 589 $func = 'read'.TBase::$tmethod[$ftype]; 590 $xfer += $input->$func($this->$var); 591 } else { 592 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; 607 } 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(); 618 619 return $xfer; 620 } 621 622 private function _writeMap($var, $spec, $output) 623 { 624 $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(); 678 679 return $xfer; 680 } 681 682 private function _writeList($var, $spec, $output, $set=false) 683 { 684 $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 } 723 724 return $xfer; 725 } 726 727 protected function _write($class, $spec, $output) 728 { 729 $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]; 738 $xfer += $output->$func($this->$var); 739 } 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(); 760 761 return $xfer; 762 } 763} 764 765class TApplicationException extends TException 766{ 767 static $_TSPEC = 768 array(1 => array('var' => 'message', 769 'type' => TType::STRING), 770 2 => array('var' => 'code', 771 'type' => TType::I32)); 772 773 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; 779 const INTERNAL_ERROR = 6; 780 const PROTOCOL_ERROR = 7; 781 782 public function __construct($message=null, $code=0) 783 { 784 parent::__construct($message, $code); 785 } 786 787 public function read($output) 788 { 789 return $this->_read('TApplicationException', self::$_TSPEC, $output); 790 } 791 792 public function write($output) 793 { 794 $xfer = 0; 795 $xfer += $output->writeStructBegin('TApplicationException'); 796 if ($message = $this->getMessage()) { 797 $xfer += $output->writeFieldBegin('message', TType::STRING, 1); 798 $xfer += $output->writeString($message); 799 $xfer += $output->writeFieldEnd(); 800 } 801 if ($code = $this->getCode()) { 802 $xfer += $output->writeFieldBegin('type', TType::I32, 2); 803 $xfer += $output->writeI32($code); 804 $xfer += $output->writeFieldEnd(); 805 } 806 $xfer += $output->writeFieldStop(); 807 $xfer += $output->writeStructEnd(); 808 809 return $xfer; 810 } 811} 812 813/** 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'; 821include_once $GLOBALS['THRIFT_ROOT'].'/TStringUtils.php'; 822