821 lines
22 KiB
PHP
821 lines
22 KiB
PHP
<?php
|
|
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
* @package thrift
|
|
*/
|
|
|
|
/**
|
|
* Data types that can be sent via Thrift
|
|
*/
|
|
class TType
|
|
{
|
|
const STOP = 0;
|
|
const VOID = 1;
|
|
const BOOL = 2;
|
|
const BYTE = 3;
|
|
const I08 = 3;
|
|
const DOUBLE = 4;
|
|
const I16 = 6;
|
|
const I32 = 8;
|
|
const I64 = 10;
|
|
const STRING = 11;
|
|
const UTF7 = 11;
|
|
const STRUCT = 12;
|
|
const MAP = 13;
|
|
const SET = 14;
|
|
const LST = 15; // N.B. cannot use LIST keyword in PHP!
|
|
const UTF8 = 16;
|
|
const UTF16 = 17;
|
|
}
|
|
|
|
/**
|
|
* Message types for RPC
|
|
*/
|
|
class TMessageType
|
|
{
|
|
const CALL = 1;
|
|
const REPLY = 2;
|
|
const EXCEPTION = 3;
|
|
const ONEWAY = 4;
|
|
}
|
|
|
|
/**
|
|
* NOTE(mcslee): This currently contains a ton of duplicated code from TBase
|
|
* because we need to save CPU cycles and this is not yet in an extension.
|
|
* Ideally we'd multiply-inherit TException from both Exception and Base, but
|
|
* that's not possible in PHP and there are no modules either, so for now we
|
|
* apologetically take a trip to HackTown.
|
|
*
|
|
* Can be called with standard Exception constructor (message, code) or with
|
|
* Thrift Base object constructor (spec, vals).
|
|
*
|
|
* @param mixed $p1 Message (string) or type-spec (array)
|
|
* @param mixed $p2 Code (integer) or values (array)
|
|
*/
|
|
class TException extends Exception
|
|
{
|
|
public function __construct($p1=null, $p2=0)
|
|
{
|
|
if (is_array($p1) && is_array($p2)) {
|
|
$spec = $p1;
|
|
$vals = $p2;
|
|
foreach ($spec as $fid => $fspec) {
|
|
$var = $fspec['var'];
|
|
if (isset($vals[$var])) {
|
|
$this->$var = $vals[$var];
|
|
}
|
|
}
|
|
} else {
|
|
parent::__construct($p1, $p2);
|
|
}
|
|
}
|
|
|
|
static $tmethod = array(TType::BOOL => 'Bool',
|
|
TType::BYTE => 'Byte',
|
|
TType::I16 => 'I16',
|
|
TType::I32 => 'I32',
|
|
TType::I64 => 'I64',
|
|
TType::DOUBLE => 'Double',
|
|
TType::STRING => 'String');
|
|
|
|
private function _readMap(&$var, $spec, $input)
|
|
{
|
|
$xfer = 0;
|
|
$ktype = $spec['ktype'];
|
|
$vtype = $spec['vtype'];
|
|
$kread = $vread = null;
|
|
if (isset(TBase::$tmethod[$ktype])) {
|
|
$kread = 'read'.TBase::$tmethod[$ktype];
|
|
} else {
|
|
$kspec = $spec['key'];
|
|
}
|
|
if (isset(TBase::$tmethod[$vtype])) {
|
|
$vread = 'read'.TBase::$tmethod[$vtype];
|
|
} else {
|
|
$vspec = $spec['val'];
|
|
}
|
|
$var = array();
|
|
$_ktype = $_vtype = $size = 0;
|
|
$xfer += $input->readMapBegin($_ktype, $_vtype, $size);
|
|
for ($i = 0; $i < $size; ++$i) {
|
|
$key = $val = null;
|
|
if ($kread !== null) {
|
|
$xfer += $input->$kread($key);
|
|
} else {
|
|
switch ($ktype) {
|
|
case TType::STRUCT:
|
|
$class = $kspec['class'];
|
|
$key = new $class();
|
|
$xfer += $key->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($key, $kspec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($key, $kspec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($key, $kspec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
if ($vread !== null) {
|
|
$xfer += $input->$vread($val);
|
|
} else {
|
|
switch ($vtype) {
|
|
case TType::STRUCT:
|
|
$class = $vspec['class'];
|
|
$val = new $class();
|
|
$xfer += $val->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($val, $vspec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($val, $vspec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($val, $vspec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
$var[$key] = $val;
|
|
}
|
|
$xfer += $input->readMapEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
private function _readList(&$var, $spec, $input, $set=false)
|
|
{
|
|
$xfer = 0;
|
|
$etype = $spec['etype'];
|
|
$eread = $vread = null;
|
|
if (isset(TBase::$tmethod[$etype])) {
|
|
$eread = 'read'.TBase::$tmethod[$etype];
|
|
} else {
|
|
$espec = $spec['elem'];
|
|
}
|
|
$var = array();
|
|
$_etype = $size = 0;
|
|
if ($set) {
|
|
$xfer += $input->readSetBegin($_etype, $size);
|
|
} else {
|
|
$xfer += $input->readListBegin($_etype, $size);
|
|
}
|
|
for ($i = 0; $i < $size; ++$i) {
|
|
$elem = null;
|
|
if ($eread !== null) {
|
|
$xfer += $input->$eread($elem);
|
|
} else {
|
|
$espec = $spec['elem'];
|
|
switch ($etype) {
|
|
case TType::STRUCT:
|
|
$class = $espec['class'];
|
|
$elem = new $class();
|
|
$xfer += $elem->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($elem, $espec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($elem, $espec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($elem, $espec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
if ($set) {
|
|
$var[$elem] = true;
|
|
} else {
|
|
$var []= $elem;
|
|
}
|
|
}
|
|
if ($set) {
|
|
$xfer += $input->readSetEnd();
|
|
} else {
|
|
$xfer += $input->readListEnd();
|
|
}
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
protected function _read($class, $spec, $input)
|
|
{
|
|
$xfer = 0;
|
|
$fname = null;
|
|
$ftype = 0;
|
|
$fid = 0;
|
|
$xfer += $input->readStructBegin($fname);
|
|
while (true) {
|
|
$xfer += $input->readFieldBegin($fname, $ftype, $fid);
|
|
if ($ftype == TType::STOP) {
|
|
break;
|
|
}
|
|
if (isset($spec[$fid])) {
|
|
$fspec = $spec[$fid];
|
|
$var = $fspec['var'];
|
|
if ($ftype == $fspec['type']) {
|
|
$xfer = 0;
|
|
if (isset(TBase::$tmethod[$ftype])) {
|
|
$func = 'read'.TBase::$tmethod[$ftype];
|
|
$xfer += $input->$func($this->$var);
|
|
} else {
|
|
switch ($ftype) {
|
|
case TType::STRUCT:
|
|
$class = $fspec['class'];
|
|
$this->$var = new $class();
|
|
$xfer += $this->$var->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($this->$var, $fspec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($this->$var, $fspec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($this->$var, $fspec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
$xfer += $input->skip($ftype);
|
|
}
|
|
} else {
|
|
$xfer += $input->skip($ftype);
|
|
}
|
|
$xfer += $input->readFieldEnd();
|
|
}
|
|
$xfer += $input->readStructEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
private function _writeMap($var, $spec, $output)
|
|
{
|
|
$xfer = 0;
|
|
$ktype = $spec['ktype'];
|
|
$vtype = $spec['vtype'];
|
|
$kwrite = $vwrite = null;
|
|
if (isset(TBase::$tmethod[$ktype])) {
|
|
$kwrite = 'write'.TBase::$tmethod[$ktype];
|
|
} else {
|
|
$kspec = $spec['key'];
|
|
}
|
|
if (isset(TBase::$tmethod[$vtype])) {
|
|
$vwrite = 'write'.TBase::$tmethod[$vtype];
|
|
} else {
|
|
$vspec = $spec['val'];
|
|
}
|
|
$xfer += $output->writeMapBegin($ktype, $vtype, count($var));
|
|
foreach ($var as $key => $val) {
|
|
if (isset($kwrite)) {
|
|
$xfer += $output->$kwrite($key);
|
|
} else {
|
|
switch ($ktype) {
|
|
case TType::STRUCT:
|
|
$xfer += $key->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($key, $kspec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($key, $kspec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($key, $kspec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
if (isset($vwrite)) {
|
|
$xfer += $output->$vwrite($val);
|
|
} else {
|
|
switch ($vtype) {
|
|
case TType::STRUCT:
|
|
$xfer += $val->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($val, $vspec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($val, $vspec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($val, $vspec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
$xfer += $output->writeMapEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
private function _writeList($var, $spec, $output, $set=false)
|
|
{
|
|
$xfer = 0;
|
|
$etype = $spec['etype'];
|
|
$ewrite = null;
|
|
if (isset(TBase::$tmethod[$etype])) {
|
|
$ewrite = 'write'.TBase::$tmethod[$etype];
|
|
} else {
|
|
$espec = $spec['elem'];
|
|
}
|
|
if ($set) {
|
|
$xfer += $output->writeSetBegin($etype, count($var));
|
|
} else {
|
|
$xfer += $output->writeListBegin($etype, count($var));
|
|
}
|
|
foreach ($var as $key => $val) {
|
|
$elem = $set ? $key : $val;
|
|
if (isset($ewrite)) {
|
|
$xfer += $output->$ewrite($elem);
|
|
} else {
|
|
switch ($etype) {
|
|
case TType::STRUCT:
|
|
$xfer += $elem->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($elem, $espec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($elem, $espec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($elem, $espec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ($set) {
|
|
$xfer += $output->writeSetEnd();
|
|
} else {
|
|
$xfer += $output->writeListEnd();
|
|
}
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
protected function _write($class, $spec, $output)
|
|
{
|
|
$xfer = 0;
|
|
$xfer += $output->writeStructBegin($class);
|
|
foreach ($spec as $fid => $fspec) {
|
|
$var = $fspec['var'];
|
|
if ($this->$var !== null) {
|
|
$ftype = $fspec['type'];
|
|
$xfer += $output->writeFieldBegin($var, $ftype, $fid);
|
|
if (isset(TBase::$tmethod[$ftype])) {
|
|
$func = 'write'.TBase::$tmethod[$ftype];
|
|
$xfer += $output->$func($this->$var);
|
|
} else {
|
|
switch ($ftype) {
|
|
case TType::STRUCT:
|
|
$xfer += $this->$var->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($this->$var, $fspec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($this->$var, $fspec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($this->$var, $fspec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
$xfer += $output->writeFieldEnd();
|
|
}
|
|
}
|
|
$xfer += $output->writeFieldStop();
|
|
$xfer += $output->writeStructEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Base class from which other Thrift structs extend. This is so that we can
|
|
* cut back on the size of the generated code which is turning out to have a
|
|
* nontrivial cost just to load thanks to the wondrously abysmal implementation
|
|
* of PHP. Note that code is intentionally duplicated in here to avoid making
|
|
* function calls for every field or member of a container..
|
|
*/
|
|
abstract class TBase
|
|
{
|
|
static $tmethod = array(TType::BOOL => 'Bool',
|
|
TType::BYTE => 'Byte',
|
|
TType::I16 => 'I16',
|
|
TType::I32 => 'I32',
|
|
TType::I64 => 'I64',
|
|
TType::DOUBLE => 'Double',
|
|
TType::STRING => 'String');
|
|
|
|
abstract public function read($input);
|
|
|
|
abstract public function write($output);
|
|
|
|
public function __construct($spec=null, $vals=null)
|
|
{
|
|
if (is_array($spec) && is_array($vals)) {
|
|
foreach ($spec as $fid => $fspec) {
|
|
$var = $fspec['var'];
|
|
if (isset($vals[$var])) {
|
|
$this->$var = $vals[$var];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private function _readMap(&$var, $spec, $input)
|
|
{
|
|
$xfer = 0;
|
|
$ktype = $spec['ktype'];
|
|
$vtype = $spec['vtype'];
|
|
$kread = $vread = null;
|
|
if (isset(TBase::$tmethod[$ktype])) {
|
|
$kread = 'read'.TBase::$tmethod[$ktype];
|
|
} else {
|
|
$kspec = $spec['key'];
|
|
}
|
|
if (isset(TBase::$tmethod[$vtype])) {
|
|
$vread = 'read'.TBase::$tmethod[$vtype];
|
|
} else {
|
|
$vspec = $spec['val'];
|
|
}
|
|
$var = array();
|
|
$_ktype = $_vtype = $size = 0;
|
|
$xfer += $input->readMapBegin($_ktype, $_vtype, $size);
|
|
for ($i = 0; $i < $size; ++$i) {
|
|
$key = $val = null;
|
|
if ($kread !== null) {
|
|
$xfer += $input->$kread($key);
|
|
} else {
|
|
switch ($ktype) {
|
|
case TType::STRUCT:
|
|
$class = $kspec['class'];
|
|
$key = new $class();
|
|
$xfer += $key->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($key, $kspec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($key, $kspec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($key, $kspec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
if ($vread !== null) {
|
|
$xfer += $input->$vread($val);
|
|
} else {
|
|
switch ($vtype) {
|
|
case TType::STRUCT:
|
|
$class = $vspec['class'];
|
|
$val = new $class();
|
|
$xfer += $val->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($val, $vspec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($val, $vspec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($val, $vspec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
$var[$key] = $val;
|
|
}
|
|
$xfer += $input->readMapEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
private function _readList(&$var, $spec, $input, $set=false)
|
|
{
|
|
$xfer = 0;
|
|
$etype = $spec['etype'];
|
|
$eread = $vread = null;
|
|
if (isset(TBase::$tmethod[$etype])) {
|
|
$eread = 'read'.TBase::$tmethod[$etype];
|
|
} else {
|
|
$espec = $spec['elem'];
|
|
}
|
|
$var = array();
|
|
$_etype = $size = 0;
|
|
if ($set) {
|
|
$xfer += $input->readSetBegin($_etype, $size);
|
|
} else {
|
|
$xfer += $input->readListBegin($_etype, $size);
|
|
}
|
|
for ($i = 0; $i < $size; ++$i) {
|
|
$elem = null;
|
|
if ($eread !== null) {
|
|
$xfer += $input->$eread($elem);
|
|
} else {
|
|
$espec = $spec['elem'];
|
|
switch ($etype) {
|
|
case TType::STRUCT:
|
|
$class = $espec['class'];
|
|
$elem = new $class();
|
|
$xfer += $elem->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($elem, $espec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($elem, $espec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($elem, $espec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
if ($set) {
|
|
$var[$elem] = true;
|
|
} else {
|
|
$var []= $elem;
|
|
}
|
|
}
|
|
if ($set) {
|
|
$xfer += $input->readSetEnd();
|
|
} else {
|
|
$xfer += $input->readListEnd();
|
|
}
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
protected function _read($class, $spec, $input)
|
|
{
|
|
$xfer = 0;
|
|
$fname = null;
|
|
$ftype = 0;
|
|
$fid = 0;
|
|
$xfer += $input->readStructBegin($fname);
|
|
while (true) {
|
|
$xfer += $input->readFieldBegin($fname, $ftype, $fid);
|
|
if ($ftype == TType::STOP) {
|
|
break;
|
|
}
|
|
if (isset($spec[$fid])) {
|
|
$fspec = $spec[$fid];
|
|
$var = $fspec['var'];
|
|
if ($ftype == $fspec['type']) {
|
|
$xfer = 0;
|
|
if (isset(TBase::$tmethod[$ftype])) {
|
|
$func = 'read'.TBase::$tmethod[$ftype];
|
|
$xfer += $input->$func($this->$var);
|
|
} else {
|
|
switch ($ftype) {
|
|
case TType::STRUCT:
|
|
$class = $fspec['class'];
|
|
$this->$var = new $class();
|
|
$xfer += $this->$var->read($input);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_readMap($this->$var, $fspec, $input);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_readList($this->$var, $fspec, $input, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_readList($this->$var, $fspec, $input, true);
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
$xfer += $input->skip($ftype);
|
|
}
|
|
} else {
|
|
$xfer += $input->skip($ftype);
|
|
}
|
|
$xfer += $input->readFieldEnd();
|
|
}
|
|
$xfer += $input->readStructEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
private function _writeMap($var, $spec, $output)
|
|
{
|
|
$xfer = 0;
|
|
$ktype = $spec['ktype'];
|
|
$vtype = $spec['vtype'];
|
|
$kwrite = $vwrite = null;
|
|
if (isset(TBase::$tmethod[$ktype])) {
|
|
$kwrite = 'write'.TBase::$tmethod[$ktype];
|
|
} else {
|
|
$kspec = $spec['key'];
|
|
}
|
|
if (isset(TBase::$tmethod[$vtype])) {
|
|
$vwrite = 'write'.TBase::$tmethod[$vtype];
|
|
} else {
|
|
$vspec = $spec['val'];
|
|
}
|
|
$xfer += $output->writeMapBegin($ktype, $vtype, count($var));
|
|
foreach ($var as $key => $val) {
|
|
if (isset($kwrite)) {
|
|
$xfer += $output->$kwrite($key);
|
|
} else {
|
|
switch ($ktype) {
|
|
case TType::STRUCT:
|
|
$xfer += $key->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($key, $kspec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($key, $kspec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($key, $kspec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
if (isset($vwrite)) {
|
|
$xfer += $output->$vwrite($val);
|
|
} else {
|
|
switch ($vtype) {
|
|
case TType::STRUCT:
|
|
$xfer += $val->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($val, $vspec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($val, $vspec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($val, $vspec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
$xfer += $output->writeMapEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
private function _writeList($var, $spec, $output, $set=false)
|
|
{
|
|
$xfer = 0;
|
|
$etype = $spec['etype'];
|
|
$ewrite = null;
|
|
if (isset(TBase::$tmethod[$etype])) {
|
|
$ewrite = 'write'.TBase::$tmethod[$etype];
|
|
} else {
|
|
$espec = $spec['elem'];
|
|
}
|
|
if ($set) {
|
|
$xfer += $output->writeSetBegin($etype, count($var));
|
|
} else {
|
|
$xfer += $output->writeListBegin($etype, count($var));
|
|
}
|
|
foreach ($var as $key => $val) {
|
|
$elem = $set ? $key : $val;
|
|
if (isset($ewrite)) {
|
|
$xfer += $output->$ewrite($elem);
|
|
} else {
|
|
switch ($etype) {
|
|
case TType::STRUCT:
|
|
$xfer += $elem->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($elem, $espec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($elem, $espec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($elem, $espec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ($set) {
|
|
$xfer += $output->writeSetEnd();
|
|
} else {
|
|
$xfer += $output->writeListEnd();
|
|
}
|
|
|
|
return $xfer;
|
|
}
|
|
|
|
protected function _write($class, $spec, $output)
|
|
{
|
|
$xfer = 0;
|
|
$xfer += $output->writeStructBegin($class);
|
|
foreach ($spec as $fid => $fspec) {
|
|
$var = $fspec['var'];
|
|
if ($this->$var !== null) {
|
|
$ftype = $fspec['type'];
|
|
$xfer += $output->writeFieldBegin($var, $ftype, $fid);
|
|
if (isset(TBase::$tmethod[$ftype])) {
|
|
$func = 'write'.TBase::$tmethod[$ftype];
|
|
$xfer += $output->$func($this->$var);
|
|
} else {
|
|
switch ($ftype) {
|
|
case TType::STRUCT:
|
|
$xfer += $this->$var->write($output);
|
|
break;
|
|
case TType::MAP:
|
|
$xfer += $this->_writeMap($this->$var, $fspec, $output);
|
|
break;
|
|
case TType::LST:
|
|
$xfer += $this->_writeList($this->$var, $fspec, $output, false);
|
|
break;
|
|
case TType::SET:
|
|
$xfer += $this->_writeList($this->$var, $fspec, $output, true);
|
|
break;
|
|
}
|
|
}
|
|
$xfer += $output->writeFieldEnd();
|
|
}
|
|
}
|
|
$xfer += $output->writeFieldStop();
|
|
$xfer += $output->writeStructEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
}
|
|
|
|
class TApplicationException extends TException
|
|
{
|
|
static $_TSPEC =
|
|
array(1 => array('var' => 'message',
|
|
'type' => TType::STRING),
|
|
2 => array('var' => 'code',
|
|
'type' => TType::I32));
|
|
|
|
const UNKNOWN = 0;
|
|
const UNKNOWN_METHOD = 1;
|
|
const INVALID_MESSAGE_TYPE = 2;
|
|
const WRONG_METHOD_NAME = 3;
|
|
const BAD_SEQUENCE_ID = 4;
|
|
const MISSING_RESULT = 5;
|
|
const INTERNAL_ERROR = 6;
|
|
const PROTOCOL_ERROR = 7;
|
|
|
|
public function __construct($message=null, $code=0)
|
|
{
|
|
parent::__construct($message, $code);
|
|
}
|
|
|
|
public function read($output)
|
|
{
|
|
return $this->_read('TApplicationException', self::$_TSPEC, $output);
|
|
}
|
|
|
|
public function write($output)
|
|
{
|
|
$xfer = 0;
|
|
$xfer += $output->writeStructBegin('TApplicationException');
|
|
if ($message = $this->getMessage()) {
|
|
$xfer += $output->writeFieldBegin('message', TType::STRING, 1);
|
|
$xfer += $output->writeString($message);
|
|
$xfer += $output->writeFieldEnd();
|
|
}
|
|
if ($code = $this->getCode()) {
|
|
$xfer += $output->writeFieldBegin('type', TType::I32, 2);
|
|
$xfer += $output->writeI32($code);
|
|
$xfer += $output->writeFieldEnd();
|
|
}
|
|
$xfer += $output->writeFieldStop();
|
|
$xfer += $output->writeStructEnd();
|
|
|
|
return $xfer;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set global THRIFT ROOT automatically via inclusion here
|
|
*/
|
|
if (!isset($GLOBALS['THRIFT_ROOT'])) {
|
|
$GLOBALS['THRIFT_ROOT'] = dirname(__FILE__);
|
|
}
|
|
include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TProtocol.php';
|
|
include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php';
|
|
include_once $GLOBALS['THRIFT_ROOT'].'/TStringUtils.php';
|