// Include other Thrift includes
const vector<t_program*>& includes = program_->get_includes();
for (size_t i = 0; i < includes.size(); ++i) {
+ string package = includes[i]->get_name();
f_types_ <<
- "include_once $GLOBALS['THRIFT_ROOT'].'/packages/" + includes[i]->get_name() << "_types.php';" << endl;
+ "include_once $GLOBALS['THRIFT_ROOT'].'/packages/" << package << "/" << package << "_types.php';" << endl;
}
f_types_ << endl;
generate_php_struct_definition(f_types_, tstruct, is_exception);
}
+void t_php_generator::generate_php_type_spec(ofstream& out,
+ t_type* t) {
+ t = get_true_type(t);
+ indent(out) << "'type' => " << type_to_enum(t) << "," << endl;
+
+ if (t->is_base_type() || t->is_enum()) {
+ // Noop, type is all we need
+ } else if (t->is_struct() || t->is_xception()) {
+ indent(out) << "'class' => '" << t->get_name() <<"'," << endl;
+ } else if (t->is_map()) {
+ t_type* ktype = get_true_type(((t_map*)t)->get_key_type());
+ t_type* vtype = get_true_type(((t_map*)t)->get_val_type());
+ indent(out) << "'ktype' => " << type_to_enum(ktype) << "," << endl;
+ indent(out) << "'vtype' => " << type_to_enum(vtype) << "," << endl;
+ indent(out) << "'key' => array(" << endl;
+ indent_up();
+ generate_php_type_spec(out, ktype);
+ indent_down();
+ indent(out) << ")," << endl;
+ indent(out) << "'val' => array(" << endl;
+ indent_up();
+ generate_php_type_spec(out, vtype);
+ indent(out) << ")," << endl;
+ indent_down();
+ } else if (t->is_list() || t->is_set()) {
+ t_type* etype;
+ if (t->is_list()) {
+ etype = get_true_type(((t_list*)t)->get_elem_type());
+ } else {
+ etype = get_true_type(((t_set*)t)->get_elem_type());
+ }
+ indent(out) << "'etype' => " << type_to_enum(etype) <<"," << endl;
+ indent(out) << "'elem' => array(" << endl;
+ indent_up();
+ generate_php_type_spec(out, etype);
+ indent(out) << ")," << endl;
+ indent_down();
+ } else {
+ throw "compiler error: no type for php struct spec field";
+ }
+
+}
+
+/**
+ * Generates the struct specification structure, which fully qualifies enough
+ * type information to generalize serialization routines.
+ */
+void t_php_generator::generate_php_struct_spec(ofstream& out,
+ t_struct* tstruct) {
+ indent(out) << "static $_TSPEC = array(" << endl;
+ indent_up();
+
+ const vector<t_field*>& members = tstruct->get_members();
+ vector<t_field*>::const_iterator m_iter;
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+ t_type* t = get_true_type((*m_iter)->get_type());
+ indent(out) << (*m_iter)->get_key() << " => array(" << endl;
+ indent_up();
+ out <<
+ indent() << "'var' => '" << (*m_iter)->get_name() << "'," << endl;
+ generate_php_type_spec(out, t);
+ indent(out) << ")," << endl;
+ indent_down();
+ }
+
+ indent_down();
+ indent(out) << " );" << endl;
+}
+
+
/**
* Generates a struct definition for a thrift data type. This is nothing in PHP
* where the objects are all just associative arrays (unless of course we
out <<
"class " << php_namespace(tstruct->get_program()) << tstruct->get_name();
if (is_exception) {
- out << " extends Exception";
+ out << " extends TException";
+ } else {
+ out << " extends TBase";
}
out <<
" {" << endl;
indent_up();
+ generate_php_struct_spec(out, tstruct);
+
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
string dval = "null";
t_type* t = get_true_type((*m_iter)->get_type());
}
out <<
- indent() << "if (is_array($vals)) {" << endl;
- indent_up();
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- out <<
- indent() << "if (isset($vals['" << (*m_iter)->get_name() << "'])) {" << endl <<
- indent() << " $this->" << (*m_iter)->get_name() << " = $vals['" << (*m_iter)->get_name() << "'];" << endl <<
- indent() << "}" << endl;
- }
- indent_down();
- out <<
+ indent() << "if (is_array($vals)) {" << endl <<
+ indent() << " parent::construct(self::$_TSPEC, $vals);" << endl <<
indent() << "}" << endl;
- indent_down();
- out <<
- indent() << "}" << endl <<
- endl;
+ scope_down(out);
+
+ out << endl;
}
out <<
vector<t_field*>::const_iterator f_iter;
indent(out) <<
- "public function read($input) " << endl;
+ "public function read($input)" << endl;
scope_up(out);
+ // TODO(mcslee): Testing this new jonx!
+ indent(out) << "return $this->_read('" << tstruct->get_name() << "', self::$_TSPEC, $input);" << endl;
+ scope_down(out);
+ return;
+
out <<
indent() << "$xfer = 0;" << endl <<
indent() << "$fname = null;" << endl <<
}
indent_up();
+ // TODO(mcslee): Testing this new j0nx
+ indent(out) << "return $this->_write('" << tstruct->get_name() << "', self::$_TSPEC, $output);" << endl;
+ scope_down(out);
+ return;
+
indent(out) <<
"$xfer = 0;" << endl;
}
generate_service_client(tservice);
generate_service_helpers(tservice);
- generate_service_processor(tservice);
+ if (phps_) {
+ generate_service_processor(tservice);
+ }
// Close service file
f_service_ << "?>" << endl;
t_type* atype = get_true_type((*a_iter)->get_type());
string cast = type_to_cast(atype);
string req = "$request['" + (*a_iter)->get_name() + "']";
- f_service_ <<
- indent() << "$" << (*a_iter)->get_name() << " = isset(" << req << ") ? " << cast << req << " : null;" << endl;
+ if (atype->is_bool()) {
+ f_service_ <<
+ indent() << "$" << (*a_iter)->get_name() << " = " << cast << "(!empty(" << req << ") && (" << req << " !== 'false'));" << endl;
+ } else {
+ f_service_ <<
+ indent() << "$" << (*a_iter)->get_name() << " = isset(" << req << ") ? " << cast << req << " : null;" << endl;
+ }
if (atype->is_string() &&
((t_base_type*)atype)->is_string_list()) {
f_service_ <<
const EXCEPTION = 3;
}
+/**
+ * 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 {
- function __construct($message=null, $code=0) {
- parent::__construct($message, $code);
+ 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);
+ }
}
-}
-class TApplicationException extends TException {
-
- 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;
+ static $tmethod = array(TType::BOOL => 'Bool',
+ TType::BYTE => 'Byte',
+ TType::I16 => 'I16',
+ TType::I32 => 'I32',
+ TType::I64 => 'I64',
+ TType::DOUBLE => 'Double',
+ TType::STRING => 'String');
- function __construct($message=null, $code=0) {
- parent::__construct($message, $code);
+ 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;
}
- public function read($input) {
+ 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($key, $espec, $input);
+ break;
+ case TType::LST:
+ $xfer += $this->_readList($key, $espec, $input, false);
+ break;
+ case TType::SET:
+ $xfer += $this->_readList($key, $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)
- {
+ $fast_binary = (bool)
+ is_a($input, 'TBinaryProtocolAccelerated') &&
+ function_exists('thrift_protocol_binary_deserialize');
+
+ while (true) {
$xfer += $input->readFieldBegin($fname, $ftype, $fid);
if ($ftype == TType::STOP) {
break;
}
- switch ($fid)
- {
- case 1:
- if ($ftype == TType::STRING) {
- $xfer += $input->readString($this->message);
+ if (isset($spec[$fid])) {
+ $fspec = $spec[$fid];
+ $var = $fspec['var'];
+ if ($ftype == $fspec['type']) {
+ $xfer = 0;
+ if ($fast_binary) {
+ $class = isset($fspec['class']) ? $fspec['class'] : null;
+ $this->$var = thrift_protocol_binary_deserialize($ftype, $input, $class);
} else {
- $xfer += $input->skip($ftype);
+ if (isset(TBase::$tmethod[$ftype])) {
+ $func = 'read'.TBase::$tmethod[$ftype];
+ $xter += $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 2:
- if ($ftype == TType::I32) {
- $xfer += $input->readI32($this->code);
- } else {
- $xfer += $input->skip($ftype);
+ 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];
+ $xter += $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 function read($input);
+
+ abstract 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;
- default:
- $xfer += $input->skip($ftype);
+ 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($key, $espec, $input);
+ break;
+ case TType::LST:
+ $xfer += $this->_readList($key, $espec, $input, false);
+ break;
+ case TType::SET:
+ $xfer += $this->_readList($key, $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);
+ $fast_binary = (bool)
+ is_a($input, 'TBinaryProtocolAccelerated') &&
+ function_exists('thrift_protocol_binary_deserialize');
+
+ 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 ($fast_binary) {
+ $class = isset($fspec['class']) ? $fspec['class'] : null;
+ $this->$var = thrift_protocol_binary_deserialize($ftype, $input, $class);
+ } else {
+ if (isset(TBase::$tmethod[$ftype])) {
+ $func = 'read'.TBase::$tmethod[$ftype];
+ $xter += $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();
}
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];
+ $xter += $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;
+
+ 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 ($this->getMessage()) {
+ if ($message = $this->getMessage()) {
$xfer += $output->writeFieldBegin('message', TType::STRING, 1);
- $xfer += $output->writeString($this->getMessage());
+ $xfer += $output->writeString($message);
$xfer += $output->writeFieldEnd();
}
- if ($this->getCode()) {
+ if ($code = $this->getCode()) {
$xfer += $output->writeFieldBegin('type', TType::I32, 2);
- $xfer += $output->writeI32($this->getCode());
+ $xfer += $output->writeI32($code);
$xfer += $output->writeFieldEnd();
}
$xfer += $output->writeFieldStop();