diff options
Diffstat (limited to 'vendor/packaged')
59 files changed, 8246 insertions, 0 deletions
diff --git a/vendor/packaged/thrift/.gitignore b/vendor/packaged/thrift/.gitignore new file mode 100644 index 000000000..ff72e2d08 --- /dev/null +++ b/vendor/packaged/thrift/.gitignore @@ -0,0 +1,2 @@ +/composer.lock +/vendor diff --git a/vendor/packaged/thrift/README.md b/vendor/packaged/thrift/README.md new file mode 100644 index 000000000..c35ca057e --- /dev/null +++ b/vendor/packaged/thrift/README.md @@ -0,0 +1,44 @@ +Apache Thrift +===== + +The code provided by this library is from: +https://github.com/apache/thrift/tree/master/lib/php/lib + +This repo has been created to provide the thrift protocol via composer + + +Thrift PHP Software Library + +License +======= + +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. + +Dependencies +============ + +PHP_INT_SIZE + + This built-in signals whether your architecture is 32 or 64 bit and is + used by the TBinaryProtocol to properly use pack() and unpack() to + serialize data. + +apc_fetch(), apc_store() + + APC cache is used by the TSocketPool class. If you do not have APC installed, + Thrift will fill in null stub function definitions. diff --git a/vendor/packaged/thrift/composer.json b/vendor/packaged/thrift/composer.json new file mode 100644 index 000000000..8a8227dd3 --- /dev/null +++ b/vendor/packaged/thrift/composer.json @@ -0,0 +1,16 @@ +{ + "name": "packaged/thrift", + "description": "Apache Thrift", + "keywords": ["thrift", "apache"], + "homepage": "http://thrift.apache.org/", + "minimum-stability": "stable", + "license": "Apache-2.0", + "require": { + "php": "^5.5 || ^7.0 || ^8.0" + }, + "autoload": { + "psr-4": { + "Thrift\\": "src/" + } + } +} diff --git a/vendor/packaged/thrift/src/Base/TBase.php b/vendor/packaged/thrift/src/Base/TBase.php new file mode 100644 index 000000000..c61b631af --- /dev/null +++ b/vendor/packaged/thrift/src/Base/TBase.php @@ -0,0 +1,382 @@ +<?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 + */ + +namespace Thrift\Base; + +use Thrift\Type\TType; + +/** + * 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 +{ + public 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]; + } + } + } + } + + public function __wakeup() + { + $this->__construct(get_object_vars($this)); + } + + 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; + } +} diff --git a/vendor/packaged/thrift/src/ClassLoader/ThriftClassLoader.php b/vendor/packaged/thrift/src/ClassLoader/ThriftClassLoader.php new file mode 100644 index 000000000..4361bd84e --- /dev/null +++ b/vendor/packaged/thrift/src/ClassLoader/ThriftClassLoader.php @@ -0,0 +1,206 @@ +<?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. + * + * ClassLoader to load Thrift library and definitions + * Inspired from UniversalClassLoader from Symfony 2 + * + * @package thrift.classloader + */ + +namespace Thrift\ClassLoader; + +class ThriftClassLoader +{ + /** + * Namespaces path + * @var array + */ + protected $namespaces = array(); + + /** + * Thrift definition paths + * @var type + */ + protected $definitions = array(); + + /** + * Do we use APC cache ? + * @var boolean + */ + protected $apc = false; + + /** + * APC Cache prefix + * @var string + */ + protected $apc_prefix; + + /** + * Set autoloader to use APC cache + * @param boolean $apc + * @param string $apc_prefix + */ + public function __construct($apc = false, $apc_prefix = null) + { + $this->apc = $apc; + $this->apc_prefix = $apc_prefix; + } + + /** + * Registers a namespace. + * + * @param string $namespace The namespace + * @param array|string $paths The location(s) of the namespace + */ + public function registerNamespace($namespace, $paths) + { + $this->namespaces[$namespace] = (array)$paths; + } + + /** + * Registers a Thrift definition namespace. + * + * @param string $namespace The definition namespace + * @param array|string $paths The location(s) of the definition namespace + */ + public function registerDefinition($namespace, $paths) + { + $this->definitions[$namespace] = (array)$paths; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Loads the given class, definition or interface. + * + * @param string $class The name of the class + */ + public function loadClass($class) + { + if ((true === $this->apc && ($file = $this->findFileInApc($class))) or + ($file = $this->findFile($class)) + ) { + require_once $file; + } + } + + /** + * Loads the given class or interface in APC. + * @param string $class The name of the class + * @return string + */ + protected function findFileInApc($class) + { + if (false === $file = apc_fetch($this->apc_prefix . $class)) { + apc_store($this->apc_prefix . $class, $file = $this->findFile($class)); + } + + return $file; + } + + /** + * Find class in namespaces or definitions directories + * @param string $class + * @return string + */ + public function findFile($class) + { + // Remove first backslash + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + if (false !== $pos = strrpos($class, '\\')) { + // Namespaced class name + $namespace = substr($class, 0, $pos); + + // Iterate in normal namespaces + foreach ($this->namespaces as $ns => $dirs) { + //Don't interfere with other autoloaders + if (0 !== strpos($namespace, $ns)) { + continue; + } + + foreach ($dirs as $dir) { + $className = substr($class, $pos + 1); + + $file = $dir . DIRECTORY_SEPARATOR . + str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . + DIRECTORY_SEPARATOR . + $className . '.php'; + + if (file_exists($file)) { + return $file; + } + } + } + + // Iterate in Thrift namespaces + + // Remove first part of namespace + $m = explode('\\', $class); + + // Ignore wrong call + if (count($m) <= 1) { + return; + } + + $class = array_pop($m); + $namespace = implode('\\', $m); + + foreach ($this->definitions as $ns => $dirs) { + //Don't interfere with other autoloaders + if (0 !== strpos($namespace, $ns)) { + continue; + } + + foreach ($dirs as $dir) { + /** + * Available in service: Interface, Client, Processor, Rest + * And every service methods (_.+) + */ + if (0 === preg_match('#(.+)(if|client|processor|rest)$#i', $class, $n) and + 0 === preg_match('#(.+)_[a-z0-9]+_(args|result)$#i', $class, $n) + ) { + $className = 'Types'; + } else { + $className = $n[1]; + } + + $file = $dir . DIRECTORY_SEPARATOR . + str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . + DIRECTORY_SEPARATOR . + $className . '.php'; + + if (file_exists($file)) { + return $file; + } + } + } + } + } +} diff --git a/vendor/packaged/thrift/src/Exception/TApplicationException.php b/vendor/packaged/thrift/src/Exception/TApplicationException.php new file mode 100644 index 000000000..ebb6a6a89 --- /dev/null +++ b/vendor/packaged/thrift/src/Exception/TApplicationException.php @@ -0,0 +1,76 @@ +<?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 + */ + +namespace Thrift\Exception; + +use Thrift\Type\TType; + +class TApplicationException extends TException +{ + public 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; + const INVALID_TRANSFORM = 8; + const INVALID_PROTOCOL = 9; + const UNSUPPORTED_CLIENT_TYPE = 10; + + 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; + } +} diff --git a/vendor/packaged/thrift/src/Exception/TException.php b/vendor/packaged/thrift/src/Exception/TException.php new file mode 100644 index 000000000..7dbf83293 --- /dev/null +++ b/vendor/packaged/thrift/src/Exception/TException.php @@ -0,0 +1,384 @@ +<?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 + */ + +namespace Thrift\Exception; + +use Thrift\Type\TType; +use Thrift\Base\TBase; + +/** + * 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); + } + } + + public 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; + } +} diff --git a/vendor/packaged/thrift/src/Exception/TProtocolException.php b/vendor/packaged/thrift/src/Exception/TProtocolException.php new file mode 100644 index 000000000..3a55d45ff --- /dev/null +++ b/vendor/packaged/thrift/src/Exception/TProtocolException.php @@ -0,0 +1,50 @@ +<?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.protocol + * @author: rmarin ([email protected]) + */ + +namespace Thrift\Exception; + +/** + * Protocol module. Contains all the types and definitions needed to implement + * a protocol encoder/decoder. + * + * @package thrift.protocol + */ + +/** + * Protocol exceptions + */ +class TProtocolException extends TException +{ + const UNKNOWN = 0; + const INVALID_DATA = 1; + const NEGATIVE_SIZE = 2; + const SIZE_LIMIT = 3; + const BAD_VERSION = 4; + const NOT_IMPLEMENTED = 5; + const DEPTH_LIMIT = 6; + + public function __construct($message = null, $code = 0) + { + parent::__construct($message, $code); + } +} diff --git a/vendor/packaged/thrift/src/Exception/TTransportException.php b/vendor/packaged/thrift/src/Exception/TTransportException.php new file mode 100644 index 000000000..7d8d56743 --- /dev/null +++ b/vendor/packaged/thrift/src/Exception/TTransportException.php @@ -0,0 +1,40 @@ +<?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.transport + */ + +namespace Thrift\Exception; + +/** + * Transport exceptions + */ +class TTransportException extends TException +{ + const UNKNOWN = 0; + const NOT_OPEN = 1; + const ALREADY_OPEN = 2; + const TIMED_OUT = 3; + const END_OF_FILE = 4; + + public function __construct($message = null, $code = 0) + { + parent::__construct($message, $code); + } +} diff --git a/vendor/packaged/thrift/src/Factory/TBinaryProtocolFactory.php b/vendor/packaged/thrift/src/Factory/TBinaryProtocolFactory.php new file mode 100644 index 000000000..2519183df --- /dev/null +++ b/vendor/packaged/thrift/src/Factory/TBinaryProtocolFactory.php @@ -0,0 +1,45 @@ +<?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.protocol + */ + +namespace Thrift\Factory; + +use Thrift\Protocol\TBinaryProtocol; + +/** + * Binary Protocol Factory + */ +class TBinaryProtocolFactory implements TProtocolFactory +{ + private $strictRead_ = false; + private $strictWrite_ = false; + + public function __construct($strictRead = false, $strictWrite = false) + { + $this->strictRead_ = $strictRead; + $this->strictWrite_ = $strictWrite; + } + + public function getProtocol($trans) + { + return new TBinaryProtocol($trans, $this->strictRead_, $this->strictWrite_); + } +} diff --git a/vendor/packaged/thrift/src/Factory/TCompactProtocolFactory.php b/vendor/packaged/thrift/src/Factory/TCompactProtocolFactory.php new file mode 100644 index 000000000..11fb8ff33 --- /dev/null +++ b/vendor/packaged/thrift/src/Factory/TCompactProtocolFactory.php @@ -0,0 +1,40 @@ +<?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.protocol + */ + +namespace Thrift\Factory; + +use Thrift\Protocol\TCompactProtocol; + +/** + * Compact Protocol Factory + */ +class TCompactProtocolFactory implements TProtocolFactory +{ + public function __construct() + { + } + + public function getProtocol($trans) + { + return new TCompactProtocol($trans); + } +} diff --git a/vendor/packaged/thrift/src/Factory/TJSONProtocolFactory.php b/vendor/packaged/thrift/src/Factory/TJSONProtocolFactory.php new file mode 100644 index 000000000..fbfb1d731 --- /dev/null +++ b/vendor/packaged/thrift/src/Factory/TJSONProtocolFactory.php @@ -0,0 +1,40 @@ +<?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.protocol + */ + +namespace Thrift\Factory; + +use Thrift\Protocol\TJSONProtocol; + +/** + * JSON Protocol Factory + */ +class TJSONProtocolFactory implements TProtocolFactory +{ + public function __construct() + { + } + + public function getProtocol($trans) + { + return new TJSONProtocol($trans); + } +} diff --git a/vendor/packaged/thrift/src/Factory/TProtocolFactory.php b/vendor/packaged/thrift/src/Factory/TProtocolFactory.php new file mode 100644 index 000000000..d3066c8ec --- /dev/null +++ b/vendor/packaged/thrift/src/Factory/TProtocolFactory.php @@ -0,0 +1,36 @@ +<?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.protocol + */ + +namespace Thrift\Factory; + +/** + * Protocol factory creates protocol objects from transports + */ +interface TProtocolFactory +{ + /** + * Build a protocol from the base transport + * + * @return Thrift\Protocol\TProtocol protocol + */ + public function getProtocol($trans); +} diff --git a/vendor/packaged/thrift/src/Factory/TStringFuncFactory.php b/vendor/packaged/thrift/src/Factory/TStringFuncFactory.php new file mode 100644 index 000000000..30de4d780 --- /dev/null +++ b/vendor/packaged/thrift/src/Factory/TStringFuncFactory.php @@ -0,0 +1,66 @@ +<?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. + * + */ + +namespace Thrift\Factory; + +use Thrift\StringFunc\Core; +use Thrift\StringFunc\Mbstring; +use Thrift\StringFunc\TStringFunc; + +class TStringFuncFactory +{ + private static $_instance; + + /** + * Get the Singleton instance of TStringFunc implementation that is + * compatible with the current system's mbstring.func_overload settings. + * + * @return TStringFunc + */ + public static function create() + { + if (!self::$_instance) { + self::_setInstance(); + } + + return self::$_instance; + } + + private static function _setInstance() + { + /** + * Cannot use str* functions for byte counting because multibyte + * characters will be read a single bytes. + * + * See: http://php.net/manual/en/mbstring.overload.php + */ + if (ini_get('mbstring.func_overload') & 2) { + self::$_instance = new Mbstring(); + } else { + /** + * mbstring is not installed or does not have function overloading + * of the str* functions enabled so use PHP core str* functions for + * byte counting. + */ + self::$_instance = new Core(); + } + } +} diff --git a/vendor/packaged/thrift/src/Factory/TTransportFactory.php b/vendor/packaged/thrift/src/Factory/TTransportFactory.php new file mode 100644 index 000000000..43f2eecde --- /dev/null +++ b/vendor/packaged/thrift/src/Factory/TTransportFactory.php @@ -0,0 +1,18 @@ +<?php + +namespace Thrift\Factory; + +use Thrift\Transport\TTransport; + +class TTransportFactory +{ + /** + * @static + * @param TTransport $transport + * @return TTransport + */ + public static function getTransport(TTransport $transport) + { + return $transport; + } +} diff --git a/vendor/packaged/thrift/src/Protocol/JSON/BaseContext.php b/vendor/packaged/thrift/src/Protocol/JSON/BaseContext.php new file mode 100644 index 000000000..31bcb48e4 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/JSON/BaseContext.php @@ -0,0 +1,39 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\JSON; + +class BaseContext +{ + public function escapeNum() + { + return false; + } + + public function write() + { + } + + public function read() + { + } +} diff --git a/vendor/packaged/thrift/src/Protocol/JSON/ListContext.php b/vendor/packaged/thrift/src/Protocol/JSON/ListContext.php new file mode 100644 index 000000000..eef659442 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/JSON/ListContext.php @@ -0,0 +1,54 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\JSON; + +use Thrift\Protocol\TJSONProtocol; + +class ListContext extends BaseContext +{ + private $first_ = true; + private $p_; + + public function __construct($p) + { + $this->p_ = $p; + } + + public function write() + { + if ($this->first_) { + $this->first_ = false; + } else { + $this->p_->getTransport()->write(TJSONProtocol::COMMA); + } + } + + public function read() + { + if ($this->first_) { + $this->first_ = false; + } else { + $this->p_->readJSONSyntaxChar(TJSONProtocol::COMMA); + } + } +} diff --git a/vendor/packaged/thrift/src/Protocol/JSON/LookaheadReader.php b/vendor/packaged/thrift/src/Protocol/JSON/LookaheadReader.php new file mode 100644 index 000000000..0b18c40d0 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/JSON/LookaheadReader.php @@ -0,0 +1,57 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\JSON; + +class LookaheadReader +{ + private $hasData_ = false; + private $data_ = array(); + private $p_; + + public function __construct($p) + { + $this->p_ = $p; + } + + public function read() + { + if ($this->hasData_) { + $this->hasData_ = false; + } else { + $this->data_ = $this->p_->getTransport()->readAll(1); + } + + return substr($this->data_, 0, 1); + } + + public function peek() + { + if (!$this->hasData_) { + $this->data_ = $this->p_->getTransport()->readAll(1); + } + + $this->hasData_ = true; + + return substr($this->data_, 0, 1); + } +} diff --git a/vendor/packaged/thrift/src/Protocol/JSON/PairContext.php b/vendor/packaged/thrift/src/Protocol/JSON/PairContext.php new file mode 100644 index 000000000..7b353c4ad --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/JSON/PairContext.php @@ -0,0 +1,64 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\JSON; + +use Thrift\Protocol\TJSONProtocol; + +class PairContext extends BaseContext +{ + private $first_ = true; + private $colon_ = true; + private $p_ = null; + + public function __construct($p) + { + $this->p_ = $p; + } + + public function write() + { + if ($this->first_) { + $this->first_ = false; + $this->colon_ = true; + } else { + $this->p_->getTransport()->write($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA); + $this->colon_ = !$this->colon_; + } + } + + public function read() + { + if ($this->first_) { + $this->first_ = false; + $this->colon_ = true; + } else { + $this->p_->readJSONSyntaxChar($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA); + $this->colon_ = !$this->colon_; + } + } + + public function escapeNum() + { + return $this->colon_; + } +} diff --git a/vendor/packaged/thrift/src/Protocol/SimpleJSON/CollectionMapKeyException.php b/vendor/packaged/thrift/src/Protocol/SimpleJSON/CollectionMapKeyException.php new file mode 100644 index 000000000..522b85a5b --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/SimpleJSON/CollectionMapKeyException.php @@ -0,0 +1,33 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\SimpleJSON; + +use Thrift\Exception\TException; + +class CollectionMapKeyException extends TException +{ + public function __construct($message) + { + parent::__construct($message); + } +} diff --git a/vendor/packaged/thrift/src/Protocol/SimpleJSON/Context.php b/vendor/packaged/thrift/src/Protocol/SimpleJSON/Context.php new file mode 100644 index 000000000..dbd16faa2 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/SimpleJSON/Context.php @@ -0,0 +1,35 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\SimpleJSON; + +class Context +{ + public function write() + { + } + + public function isMapKey() + { + return false; + } +} diff --git a/vendor/packaged/thrift/src/Protocol/SimpleJSON/ListContext.php b/vendor/packaged/thrift/src/Protocol/SimpleJSON/ListContext.php new file mode 100644 index 000000000..6f346d8f8 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/SimpleJSON/ListContext.php @@ -0,0 +1,45 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\SimpleJSON; + +use Thrift\Protocol\TSimpleJSONProtocol; + +class ListContext extends Context +{ + protected $first_ = true; + private $p_; + + public function __construct($p) + { + $this->p_ = $p; + } + + public function write() + { + if ($this->first_) { + $this->first_ = false; + } else { + $this->p_->getTransport()->write(TSimpleJSONProtocol::COMMA); + } + } +} diff --git a/vendor/packaged/thrift/src/Protocol/SimpleJSON/MapContext.php b/vendor/packaged/thrift/src/Protocol/SimpleJSON/MapContext.php new file mode 100644 index 000000000..61c060d09 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/SimpleJSON/MapContext.php @@ -0,0 +1,47 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\SimpleJSON; + +class MapContext extends StructContext +{ + protected $isKey = true; + private $p_; + + public function __construct($p) + { + parent::__construct($p); + } + + public function write() + { + parent::write(); + $this->isKey = !$this->isKey; + } + + public function isMapKey() + { + // we want to coerce map keys to json strings regardless + // of their type + return $this->isKey; + } +} diff --git a/vendor/packaged/thrift/src/Protocol/SimpleJSON/StructContext.php b/vendor/packaged/thrift/src/Protocol/SimpleJSON/StructContext.php new file mode 100644 index 000000000..38a62d1a2 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/SimpleJSON/StructContext.php @@ -0,0 +1,52 @@ +<?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.protocol + */ + +namespace Thrift\Protocol\SimpleJSON; + +use Thrift\Protocol\TSimpleJSONProtocol; + +class StructContext extends Context +{ + protected $first_ = true; + protected $colon_ = true; + private $p_; + + public function __construct($p) + { + $this->p_ = $p; + } + + public function write() + { + if ($this->first_) { + $this->first_ = false; + $this->colon_ = true; + } else { + $this->p_->getTransport()->write( + $this->colon_ ? + TSimpleJSONProtocol::COLON : + TSimpleJSONProtocol::COMMA + ); + $this->colon_ = !$this->colon_; + } + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TBinaryProtocol.php b/vendor/packaged/thrift/src/Protocol/TBinaryProtocol.php new file mode 100644 index 000000000..cda5c0d4c --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TBinaryProtocol.php @@ -0,0 +1,453 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Type\TType; +use Thrift\Exception\TProtocolException; +use Thrift\Factory\TStringFuncFactory; + +/** + * Binary implementation of the Thrift protocol. + * + */ +class TBinaryProtocol extends TProtocol +{ + const VERSION_MASK = 0xffff0000; + const VERSION_1 = 0x80010000; + + protected $strictRead_ = false; + protected $strictWrite_ = true; + + public function __construct($trans, $strictRead = false, $strictWrite = true) + { + parent::__construct($trans); + $this->strictRead_ = $strictRead; + $this->strictWrite_ = $strictWrite; + } + + public function writeMessageBegin($name, $type, $seqid) + { + if ($this->strictWrite_) { + $version = self::VERSION_1 | $type; + + return + $this->writeI32($version) + + $this->writeString($name) + + $this->writeI32($seqid); + } else { + return + $this->writeString($name) + + $this->writeByte($type) + + $this->writeI32($seqid); + } + } + + public function writeMessageEnd() + { + return 0; + } + + public function writeStructBegin($name) + { + return 0; + } + + public function writeStructEnd() + { + return 0; + } + + public function writeFieldBegin($fieldName, $fieldType, $fieldId) + { + return + $this->writeByte($fieldType) + + $this->writeI16($fieldId); + } + + public function writeFieldEnd() + { + return 0; + } + + public function writeFieldStop() + { + return + $this->writeByte(TType::STOP); + } + + public function writeMapBegin($keyType, $valType, $size) + { + return + $this->writeByte($keyType) + + $this->writeByte($valType) + + $this->writeI32($size); + } + + public function writeMapEnd() + { + return 0; + } + + public function writeListBegin($elemType, $size) + { + return + $this->writeByte($elemType) + + $this->writeI32($size); + } + + public function writeListEnd() + { + return 0; + } + + public function writeSetBegin($elemType, $size) + { + return + $this->writeByte($elemType) + + $this->writeI32($size); + } + + public function writeSetEnd() + { + return 0; + } + + public function writeBool($value) + { + $data = pack('c', $value ? 1 : 0); + $this->trans_->write($data, 1); + + return 1; + } + + public function writeByte($value) + { + $data = pack('c', $value); + $this->trans_->write($data, 1); + + return 1; + } + + public function writeI16($value) + { + $data = pack('n', $value); + $this->trans_->write($data, 2); + + return 2; + } + + public function writeI32($value) + { + $data = pack('N', $value); + $this->trans_->write($data, 4); + + return 4; + } + + public function writeI64($value) + { + // If we are on a 32bit architecture we have to explicitly deal with + // 64-bit twos-complement arithmetic since PHP wants to treat all ints + // as signed and any int over 2^31 - 1 as a float + if (PHP_INT_SIZE == 4) { + $neg = $value < 0; + + if ($neg) { + $value *= -1; + } + + $hi = (int)($value / 4294967296); + $lo = (int)$value; + + if ($neg) { + $hi = ~$hi; + $lo = ~$lo; + if (($lo & (int)0xffffffff) == (int)0xffffffff) { + $lo = 0; + $hi++; + } else { + $lo++; + } + } + $data = pack('N2', $hi, $lo); + } else { + $hi = $value >> 32; + $lo = $value & 0xFFFFFFFF; + $data = pack('N2', $hi, $lo); + } + + $this->trans_->write($data, 8); + + return 8; + } + + public function writeDouble($value) + { + $data = pack('d', $value); + $this->trans_->write(strrev($data), 8); + + return 8; + } + + public function writeString($value) + { + $len = TStringFuncFactory::create()->strlen($value); + $result = $this->writeI32($len); + if ($len) { + $this->trans_->write($value, $len); + } + + return $result + $len; + } + + public function readMessageBegin(&$name, &$type, &$seqid) + { + $result = $this->readI32($sz); + if ($sz < 0) { + $version = (int)($sz & self::VERSION_MASK); + if ($version != (int)self::VERSION_1) { + throw new TProtocolException('Bad version identifier: ' . $sz, TProtocolException::BAD_VERSION); + } + $type = $sz & 0x000000ff; + $result += + $this->readString($name) + + $this->readI32($seqid); + } else { + if ($this->strictRead_) { + throw new TProtocolException( + 'No version identifier, old protocol client?', + TProtocolException::BAD_VERSION + ); + } else { + // Handle pre-versioned input + $name = $this->trans_->readAll($sz); + $result += + $sz + + $this->readByte($type) + + $this->readI32($seqid); + } + } + + return $result; + } + + public function readMessageEnd() + { + return 0; + } + + public function readStructBegin(&$name) + { + $name = ''; + + return 0; + } + + public function readStructEnd() + { + return 0; + } + + public function readFieldBegin(&$name, &$fieldType, &$fieldId) + { + $result = $this->readByte($fieldType); + if ($fieldType == TType::STOP) { + $fieldId = 0; + + return $result; + } + $result += $this->readI16($fieldId); + + return $result; + } + + public function readFieldEnd() + { + return 0; + } + + public function readMapBegin(&$keyType, &$valType, &$size) + { + return + $this->readByte($keyType) + + $this->readByte($valType) + + $this->readI32($size); + } + + public function readMapEnd() + { + return 0; + } + + public function readListBegin(&$elemType, &$size) + { + return + $this->readByte($elemType) + + $this->readI32($size); + } + + public function readListEnd() + { + return 0; + } + + public function readSetBegin(&$elemType, &$size) + { + return + $this->readByte($elemType) + + $this->readI32($size); + } + + public function readSetEnd() + { + return 0; + } + + public function readBool(&$value) + { + $data = $this->trans_->readAll(1); + $arr = unpack('c', $data); + $value = $arr[1] == 1; + + return 1; + } + + public function readByte(&$value) + { + $data = $this->trans_->readAll(1); + $arr = unpack('c', $data); + $value = $arr[1]; + + return 1; + } + + public function readI16(&$value) + { + $data = $this->trans_->readAll(2); + $arr = unpack('n', $data); + $value = $arr[1]; + if ($value > 0x7fff) { + $value = 0 - (($value - 1) ^ 0xffff); + } + + return 2; + } + + public function readI32(&$value) + { + $data = $this->trans_->readAll(4); + $arr = unpack('N', $data); + $value = $arr[1]; + if ($value > 0x7fffffff) { + $value = 0 - (($value - 1) ^ 0xffffffff); + } + + return 4; + } + + public function readI64(&$value) + { + $data = $this->trans_->readAll(8); + + $arr = unpack('N2', $data); + + // If we are on a 32bit architecture we have to explicitly deal with + // 64-bit twos-complement arithmetic since PHP wants to treat all ints + // as signed and any int over 2^31 - 1 as a float + if (PHP_INT_SIZE == 4) { + $hi = $arr[1]; + $lo = $arr[2]; + $isNeg = $hi < 0; + + // Check for a negative + if ($isNeg) { + $hi = ~$hi & (int)0xffffffff; + $lo = ~$lo & (int)0xffffffff; + + if ($lo == (int)0xffffffff) { + $hi++; + $lo = 0; + } else { + $lo++; + } + } + + // Force 32bit words in excess of 2G to pe positive - we deal wigh sign + // explicitly below + + if ($hi & (int)0x80000000) { + $hi &= (int)0x7fffffff; + $hi += 0x80000000; + } + + if ($lo & (int)0x80000000) { + $lo &= (int)0x7fffffff; + $lo += 0x80000000; + } + + $value = $hi * 4294967296 + $lo; + + if ($isNeg) { + $value = 0 - $value; + } + } else { + // Upcast negatives in LSB bit + if ($arr[2] & 0x80000000) { + $arr[2] = $arr[2] & 0xffffffff; + } + + // Check for a negative + if ($arr[1] & 0x80000000) { + $arr[1] = $arr[1] & 0xffffffff; + $arr[1] = $arr[1] ^ 0xffffffff; + $arr[2] = $arr[2] ^ 0xffffffff; + $value = 0 - $arr[1] * 4294967296 - $arr[2] - 1; + } else { + $value = $arr[1] * 4294967296 + $arr[2]; + } + } + + return 8; + } + + public function readDouble(&$value) + { + $data = strrev($this->trans_->readAll(8)); + $arr = unpack('d', $data); + $value = $arr[1]; + + return 8; + } + + public function readString(&$value) + { + $result = $this->readI32($len); + if ($len) { + $value = $this->trans_->readAll($len); + } else { + $value = ''; + } + + return $result + $len; + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TBinaryProtocolAccelerated.php b/vendor/packaged/thrift/src/Protocol/TBinaryProtocolAccelerated.php new file mode 100644 index 000000000..ff799a6ab --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TBinaryProtocolAccelerated.php @@ -0,0 +1,67 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Transport\TBufferedTransport; + +/** + * Accelerated binary protocol: used in conjunction with the thrift_protocol + * extension for faster deserialization + */ +class TBinaryProtocolAccelerated extends TBinaryProtocol +{ + public function __construct($trans, $strictRead = false, $strictWrite = true) + { + // If the transport doesn't implement putBack, wrap it in a + // TBufferedTransport (which does) + + // NOTE (t.heintz): This is very evil to do, because the TBufferedTransport may swallow bytes, which + // are then never written to the underlying transport. This happens precisely when a number of bytes + // less than the max buffer size (512 by default) is written to the transport and then flush() is NOT + // called. In that case the data stays in the writeBuffer of the transport, from where it can never be + // accessed again (for example through read()). + // + // Since the caller of this method does not know about the wrapping transport, this creates bugs which + // are very difficult to find. Hence the wrapping of a transport in a buffer should be left to the + // calling code. An interface could used to mandate the presence of the putBack() method in the transport. + // + // I am leaving this code in nonetheless, because there may be applications depending on this behavior. + // + // @see THRIFT-1579 + + if (!method_exists($trans, 'putBack')) { + $trans = new TBufferedTransport($trans); + } + parent::__construct($trans, $strictRead, $strictWrite); + } + + public function isStrictRead() + { + return $this->strictRead_; + } + + public function isStrictWrite() + { + return $this->strictWrite_; + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TCompactProtocol.php b/vendor/packaged/thrift/src/Protocol/TCompactProtocol.php new file mode 100644 index 000000000..1af2a274a --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TCompactProtocol.php @@ -0,0 +1,739 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Type\TType; +use Thrift\Exception\TProtocolException; +use Thrift\Factory\TStringFuncFactory; + +/** + * Compact implementation of the Thrift protocol. + * + */ +class TCompactProtocol extends TProtocol +{ + const COMPACT_STOP = 0x00; + const COMPACT_TRUE = 0x01; + const COMPACT_FALSE = 0x02; + const COMPACT_BYTE = 0x03; + const COMPACT_I16 = 0x04; + const COMPACT_I32 = 0x05; + const COMPACT_I64 = 0x06; + const COMPACT_DOUBLE = 0x07; + const COMPACT_BINARY = 0x08; + const COMPACT_LIST = 0x09; + const COMPACT_SET = 0x0A; + const COMPACT_MAP = 0x0B; + const COMPACT_STRUCT = 0x0C; + + const STATE_CLEAR = 0; + const STATE_FIELD_WRITE = 1; + const STATE_VALUE_WRITE = 2; + const STATE_CONTAINER_WRITE = 3; + const STATE_BOOL_WRITE = 4; + const STATE_FIELD_READ = 5; + const STATE_CONTAINER_READ = 6; + const STATE_VALUE_READ = 7; + const STATE_BOOL_READ = 8; + + const VERSION_MASK = 0x1f; + const VERSION = 1; + const PROTOCOL_ID = 0x82; + const TYPE_MASK = 0xe0; + const TYPE_BITS = 0x07; + const TYPE_SHIFT_AMOUNT = 5; + + protected static $ctypes = array( + TType::STOP => TCompactProtocol::COMPACT_STOP, + TType::BOOL => TCompactProtocol::COMPACT_TRUE, // used for collection + TType::BYTE => TCompactProtocol::COMPACT_BYTE, + TType::I16 => TCompactProtocol::COMPACT_I16, + TType::I32 => TCompactProtocol::COMPACT_I32, + TType::I64 => TCompactProtocol::COMPACT_I64, + TType::DOUBLE => TCompactProtocol::COMPACT_DOUBLE, + TType::STRING => TCompactProtocol::COMPACT_BINARY, + TType::STRUCT => TCompactProtocol::COMPACT_STRUCT, + TType::LST => TCompactProtocol::COMPACT_LIST, + TType::SET => TCompactProtocol::COMPACT_SET, + TType::MAP => TCompactProtocol::COMPACT_MAP, + ); + + protected static $ttypes = array( + TCompactProtocol::COMPACT_STOP => TType::STOP, + TCompactProtocol::COMPACT_TRUE => TType::BOOL, // used for collection + TCompactProtocol::COMPACT_FALSE => TType::BOOL, + TCompactProtocol::COMPACT_BYTE => TType::BYTE, + TCompactProtocol::COMPACT_I16 => TType::I16, + TCompactProtocol::COMPACT_I32 => TType::I32, + TCompactProtocol::COMPACT_I64 => TType::I64, + TCompactProtocol::COMPACT_DOUBLE => TType::DOUBLE, + TCompactProtocol::COMPACT_BINARY => TType::STRING, + TCompactProtocol::COMPACT_STRUCT => TType::STRUCT, + TCompactProtocol::COMPACT_LIST => TType::LST, + TCompactProtocol::COMPACT_SET => TType::SET, + TCompactProtocol::COMPACT_MAP => TType::MAP, + ); + + protected $state = TCompactProtocol::STATE_CLEAR; + protected $lastFid = 0; + protected $boolFid = null; + protected $boolValue = null; + protected $structs = array(); + protected $containers = array(); + + // Some varint / zigzag helper methods + public function toZigZag($n, $bits) + { + return ($n << 1) ^ ($n >> ($bits - 1)); + } + + public function fromZigZag($n) + { + return ($n >> 1) ^ -($n & 1); + } + + public function getVarint($data) + { + $out = ""; + while (true) { + if (($data & ~0x7f) === 0) { + $out .= chr($data); + break; + } else { + $out .= chr(($data & 0xff) | 0x80); + $data = $data >> 7; + } + } + + return $out; + } + + public function writeVarint($data) + { + $out = $this->getVarint($data); + $result = TStringFuncFactory::create()->strlen($out); + $this->trans_->write($out, $result); + + return $result; + } + + public function readVarint(&$result) + { + $idx = 0; + $shift = 0; + $result = 0; + while (true) { + $x = $this->trans_->readAll(1); + $arr = unpack('C', $x); + $byte = $arr[1]; + $idx += 1; + $result |= ($byte & 0x7f) << $shift; + if (($byte >> 7) === 0) { + return $idx; + } + $shift += 7; + } + + return $idx; + } + + public function __construct($trans) + { + parent::__construct($trans); + } + + public function writeMessageBegin($name, $type, $seqid) + { + $written = + $this->writeUByte(TCompactProtocol::PROTOCOL_ID) + + $this->writeUByte(TCompactProtocol::VERSION | + ($type << TCompactProtocol::TYPE_SHIFT_AMOUNT)) + + $this->writeVarint($seqid) + + $this->writeString($name); + $this->state = TCompactProtocol::STATE_VALUE_WRITE; + + return $written; + } + + public function writeMessageEnd() + { + $this->state = TCompactProtocol::STATE_CLEAR; + + return 0; + } + + public function writeStructBegin($name) + { + $this->structs[] = array($this->state, $this->lastFid); + $this->state = TCompactProtocol::STATE_FIELD_WRITE; + $this->lastFid = 0; + + return 0; + } + + public function writeStructEnd() + { + $old_values = array_pop($this->structs); + $this->state = $old_values[0]; + $this->lastFid = $old_values[1]; + + return 0; + } + + public function writeFieldStop() + { + return $this->writeByte(0); + } + + public function writeFieldHeader($type, $fid) + { + $written = 0; + $delta = $fid - $this->lastFid; + if (0 < $delta && $delta <= 15) { + $written = $this->writeUByte(($delta << 4) | $type); + } else { + $written = $this->writeByte($type) + + $this->writeI16($fid); + } + $this->lastFid = $fid; + + return $written; + } + + public function writeFieldBegin($field_name, $field_type, $field_id) + { + if ($field_type == TTYPE::BOOL) { + $this->state = TCompactProtocol::STATE_BOOL_WRITE; + $this->boolFid = $field_id; + + return 0; + } else { + $this->state = TCompactProtocol::STATE_VALUE_WRITE; + + return $this->writeFieldHeader(self::$ctypes[$field_type], $field_id); + } + } + + public function writeFieldEnd() + { + $this->state = TCompactProtocol::STATE_FIELD_WRITE; + + return 0; + } + + public function writeCollectionBegin($etype, $size) + { + $written = 0; + if ($size <= 14) { + $written = $this->writeUByte($size << 4 | + self::$ctypes[$etype]); + } else { + $written = $this->writeUByte(0xf0 | + self::$ctypes[$etype]) + + $this->writeVarint($size); + } + $this->containers[] = $this->state; + $this->state = TCompactProtocol::STATE_CONTAINER_WRITE; + + return $written; + } + + public function writeMapBegin($key_type, $val_type, $size) + { + $written = 0; + if ($size == 0) { + $written = $this->writeByte(0); + } else { + $written = $this->writeVarint($size) + + $this->writeUByte(self::$ctypes[$key_type] << 4 | + self::$ctypes[$val_type]); + } + $this->containers[] = $this->state; + + return $written; + } + + public function writeCollectionEnd() + { + $this->state = array_pop($this->containers); + + return 0; + } + + public function writeMapEnd() + { + return $this->writeCollectionEnd(); + } + + public function writeListBegin($elem_type, $size) + { + return $this->writeCollectionBegin($elem_type, $size); + } + + public function writeListEnd() + { + return $this->writeCollectionEnd(); + } + + public function writeSetBegin($elem_type, $size) + { + return $this->writeCollectionBegin($elem_type, $size); + } + + public function writeSetEnd() + { + return $this->writeCollectionEnd(); + } + + public function writeBool($value) + { + if ($this->state == TCompactProtocol::STATE_BOOL_WRITE) { + $ctype = TCompactProtocol::COMPACT_FALSE; + if ($value) { + $ctype = TCompactProtocol::COMPACT_TRUE; + } + + return $this->writeFieldHeader($ctype, $this->boolFid); + } elseif ($this->state == TCompactProtocol::STATE_CONTAINER_WRITE) { + return $this->writeByte($value ? 1 : 0); + } else { + throw new TProtocolException('Invalid state in compact protocol'); + } + } + + public function writeByte($value) + { + $data = pack('c', $value); + $this->trans_->write($data, 1); + + return 1; + } + + public function writeUByte($byte) + { + $this->trans_->write(pack('C', $byte), 1); + + return 1; + } + + public function writeI16($value) + { + $thing = $this->toZigZag($value, 16); + + return $this->writeVarint($thing); + } + + public function writeI32($value) + { + $thing = $this->toZigZag($value, 32); + + return $this->writeVarint($thing); + } + + public function writeDouble($value) + { + $data = pack('d', $value); + $this->trans_->write($data, 8); + + return 8; + } + + public function writeString($value) + { + $len = TStringFuncFactory::create()->strlen($value); + $result = $this->writeVarint($len); + if ($len) { + $this->trans_->write($value, $len); + } + + return $result + $len; + } + + public function readFieldBegin(&$name, &$field_type, &$field_id) + { + $result = $this->readUByte($compact_type_and_delta); + + $compact_type = $compact_type_and_delta & 0x0f; + + if ($compact_type == TType::STOP) { + $field_type = $compact_type; + $field_id = 0; + + return $result; + } + $delta = $compact_type_and_delta >> 4; + if ($delta == 0) { + $result += $this->readI16($field_id); + } else { + $field_id = $this->lastFid + $delta; + } + $this->lastFid = $field_id; + $field_type = $this->getTType($compact_type); + + if ($compact_type == TCompactProtocol::COMPACT_TRUE) { + $this->state = TCompactProtocol::STATE_BOOL_READ; + $this->boolValue = true; + } elseif ($compact_type == TCompactProtocol::COMPACT_FALSE) { + $this->state = TCompactProtocol::STATE_BOOL_READ; + $this->boolValue = false; + } else { + $this->state = TCompactProtocol::STATE_VALUE_READ; + } + + return $result; + } + + public function readFieldEnd() + { + $this->state = TCompactProtocol::STATE_FIELD_READ; + + return 0; + } + + public function readUByte(&$value) + { + $data = $this->trans_->readAll(1); + $arr = unpack('C', $data); + $value = $arr[1]; + + return 1; + } + + public function readByte(&$value) + { + $data = $this->trans_->readAll(1); + $arr = unpack('c', $data); + $value = $arr[1]; + + return 1; + } + + public function readZigZag(&$value) + { + $result = $this->readVarint($value); + $value = $this->fromZigZag($value); + + return $result; + } + + public function readMessageBegin(&$name, &$type, &$seqid) + { + $protoId = 0; + $result = $this->readUByte($protoId); + if ($protoId != TCompactProtocol::PROTOCOL_ID) { + throw new TProtocolException('Bad protocol id in TCompact message'); + } + $verType = 0; + $result += $this->readUByte($verType); + $type = ($verType >> TCompactProtocol::TYPE_SHIFT_AMOUNT) & TCompactProtocol::TYPE_BITS; + $version = $verType & TCompactProtocol::VERSION_MASK; + if ($version != TCompactProtocol::VERSION) { + throw new TProtocolException('Bad version in TCompact message'); + } + $result += $this->readVarint($seqid); + $result += $this->readString($name); + + return $result; + } + + public function readMessageEnd() + { + return 0; + } + + public function readStructBegin(&$name) + { + $name = ''; // unused + $this->structs[] = array($this->state, $this->lastFid); + $this->state = TCompactProtocol::STATE_FIELD_READ; + $this->lastFid = 0; + + return 0; + } + + public function readStructEnd() + { + $last = array_pop($this->structs); + $this->state = $last[0]; + $this->lastFid = $last[1]; + + return 0; + } + + public function readCollectionBegin(&$type, &$size) + { + $sizeType = 0; + $result = $this->readUByte($sizeType); + $size = $sizeType >> 4; + $type = $this->getTType($sizeType); + if ($size == 15) { + $result += $this->readVarint($size); + } + $this->containers[] = $this->state; + $this->state = TCompactProtocol::STATE_CONTAINER_READ; + + return $result; + } + + public function readMapBegin(&$key_type, &$val_type, &$size) + { + $result = $this->readVarint($size); + $types = 0; + if ($size > 0) { + $result += $this->readUByte($types); + } + $val_type = $this->getTType($types); + $key_type = $this->getTType($types >> 4); + $this->containers[] = $this->state; + $this->state = TCompactProtocol::STATE_CONTAINER_READ; + + return $result; + } + + public function readCollectionEnd() + { + $this->state = array_pop($this->containers); + + return 0; + } + + public function readMapEnd() + { + return $this->readCollectionEnd(); + } + + public function readListBegin(&$elem_type, &$size) + { + return $this->readCollectionBegin($elem_type, $size); + } + + public function readListEnd() + { + return $this->readCollectionEnd(); + } + + public function readSetBegin(&$elem_type, &$size) + { + return $this->readCollectionBegin($elem_type, $size); + } + + public function readSetEnd() + { + return $this->readCollectionEnd(); + } + + public function readBool(&$value) + { + if ($this->state == TCompactProtocol::STATE_BOOL_READ) { + $value = $this->boolValue; + + return 0; + } elseif ($this->state == TCompactProtocol::STATE_CONTAINER_READ) { + return $this->readByte($value); + } else { + throw new TProtocolException('Invalid state in compact protocol'); + } + } + + public function readI16(&$value) + { + return $this->readZigZag($value); + } + + public function readI32(&$value) + { + return $this->readZigZag($value); + } + + public function readDouble(&$value) + { + $data = $this->trans_->readAll(8); + $arr = unpack('d', $data); + $value = $arr[1]; + + return 8; + } + + public function readString(&$value) + { + $result = $this->readVarint($len); + if ($len) { + $value = $this->trans_->readAll($len); + } else { + $value = ''; + } + + return $result + $len; + } + + public function getTType($byte) + { + return self::$ttypes[$byte & 0x0f]; + } + + // If we are on a 32bit architecture we have to explicitly deal with + // 64-bit twos-complement arithmetic since PHP wants to treat all ints + // as signed and any int over 2^31 - 1 as a float + + // Read and write I64 as two 32 bit numbers $hi and $lo + + public function readI64(&$value) + { + // Read varint from wire + $hi = 0; + $lo = 0; + + $idx = 0; + $shift = 0; + + while (true) { + $x = $this->trans_->readAll(1); + $arr = unpack('C', $x); + $byte = $arr[1]; + $idx += 1; + // Shift hi and lo together. + if ($shift < 28) { + $lo |= (($byte & 0x7f) << $shift); + } elseif ($shift == 28) { + $lo |= (($byte & 0x0f) << 28); + $hi |= (($byte & 0x70) >> 4); + } else { + $hi |= (($byte & 0x7f) << ($shift - 32)); + } + if (($byte >> 7) === 0) { + break; + } + $shift += 7; + } + + // Now, unzig it. + $xorer = 0; + if ($lo & 1) { + $xorer = 0xffffffff; + } + $lo = ($lo >> 1) & 0x7fffffff; + $lo = $lo | (($hi & 1) << 31); + $hi = ($hi >> 1) ^ $xorer; + $lo = $lo ^ $xorer; + + // Now put $hi and $lo back together + $isNeg = $hi < 0 || $hi & 0x80000000; + + // Check for a negative + if ($isNeg) { + $hi = ~$hi & (int)0xffffffff; + $lo = ~$lo & (int)0xffffffff; + + if ($lo == (int)0xffffffff) { + $hi++; + $lo = 0; + } else { + $lo++; + } + } + + // Force 32bit words in excess of 2G to be positive - we deal with sign + // explicitly below + + if ($hi & (int)0x80000000) { + $hi &= (int)0x7fffffff; + $hi += 0x80000000; + } + + if ($lo & (int)0x80000000) { + $lo &= (int)0x7fffffff; + $lo += 0x80000000; + } + + // Create as negative value first, since we can store -2^63 but not 2^63 + $value = -$hi * 4294967296 - $lo; + + if (!$isNeg) { + $value = -$value; + } + + return $idx; + } + + public function writeI64($value) + { + // If we are in an I32 range, use the easy method below. + if (($value > 4294967296) || ($value < -4294967296)) { + // Convert $value to $hi and $lo + $neg = $value < 0; + + if ($neg) { + $value *= -1; + } + + $hi = (int)$value >> 32; + $lo = (int)$value & 0xffffffff; + + if ($neg) { + $hi = ~$hi; + $lo = ~$lo; + if (($lo & (int)0xffffffff) == (int)0xffffffff) { + $lo = 0; + $hi++; + } else { + $lo++; + } + } + + // Now do the zigging and zagging. + $xorer = 0; + if ($neg) { + $xorer = 0xffffffff; + } + $lowbit = ($lo >> 31) & 1; + $hi = ($hi << 1) | $lowbit; + $lo = ($lo << 1); + $lo = ($lo ^ $xorer) & 0xffffffff; + $hi = ($hi ^ $xorer) & 0xffffffff; + + // now write out the varint, ensuring we shift both hi and lo + $out = ""; + while (true) { + if (($lo & ~0x7f) === 0 && + $hi === 0) { + $out .= chr($lo); + break; + } else { + $out .= chr(($lo & 0xff) | 0x80); + $lo = $lo >> 7; + $lo = $lo | ($hi << 25); + $hi = $hi >> 7; + // Right shift carries sign, but we don't want it to. + $hi = $hi & (127 << 25); + } + } + + $ret = TStringFuncFactory::create()->strlen($out); + $this->trans_->write($out, $ret); + + return $ret; + } else { + return $this->writeVarint($this->toZigZag($value, 64)); + } + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TJSONProtocol.php b/vendor/packaged/thrift/src/Protocol/TJSONProtocol.php new file mode 100644 index 000000000..914488421 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TJSONProtocol.php @@ -0,0 +1,815 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Type\TType; +use Thrift\Exception\TProtocolException; +use Thrift\Protocol\JSON\BaseContext; +use Thrift\Protocol\JSON\LookaheadReader; +use Thrift\Protocol\JSON\PairContext; +use Thrift\Protocol\JSON\ListContext; + +/** + * JSON implementation of thrift protocol, ported from Java. + */ +class TJSONProtocol extends TProtocol +{ + const COMMA = ','; + const COLON = ':'; + const LBRACE = '{'; + const RBRACE = '}'; + const LBRACKET = '['; + const RBRACKET = ']'; + const QUOTE = '"'; + const BACKSLASH = '\\'; + const ZERO = '0'; + const ESCSEQ = '\\'; + const DOUBLEESC = '__DOUBLE_ESCAPE_SEQUENCE__'; + + const VERSION = 1; + + public static $JSON_CHAR_TABLE = array( + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, // 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 + 1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + ); + + public static $ESCAPE_CHARS = array('"', '\\', '/', "b", "f", "n", "r", "t"); + + public static $ESCAPE_CHAR_VALS = array( + '"', '\\', '/', "\x08", "\f", "\n", "\r", "\t", + ); + + const NAME_BOOL = "tf"; + const NAME_BYTE = "i8"; + const NAME_I16 = "i16"; + const NAME_I32 = "i32"; + const NAME_I64 = "i64"; + const NAME_DOUBLE = "dbl"; + const NAME_STRUCT = "rec"; + const NAME_STRING = "str"; + const NAME_MAP = "map"; + const NAME_LIST = "lst"; + const NAME_SET = "set"; + + private function getTypeNameForTypeID($typeID) + { + switch ($typeID) { + case TType::BOOL: + return self::NAME_BOOL; + case TType::BYTE: + return self::NAME_BYTE; + case TType::I16: + return self::NAME_I16; + case TType::I32: + return self::NAME_I32; + case TType::I64: + return self::NAME_I64; + case TType::DOUBLE: + return self::NAME_DOUBLE; + case TType::STRING: + return self::NAME_STRING; + case TType::STRUCT: + return self::NAME_STRUCT; + case TType::MAP: + return self::NAME_MAP; + case TType::SET: + return self::NAME_SET; + case TType::LST: + return self::NAME_LIST; + default: + throw new TProtocolException("Unrecognized type", TProtocolException::UNKNOWN); + } + } + + private function getTypeIDForTypeName($name) + { + $result = TType::STOP; + + if (strlen($name) > 1) { + switch (substr($name, 0, 1)) { + case 'd': + $result = TType::DOUBLE; + break; + case 'i': + switch (substr($name, 1, 1)) { + case '8': + $result = TType::BYTE; + break; + case '1': + $result = TType::I16; + break; + case '3': + $result = TType::I32; + break; + case '6': + $result = TType::I64; + break; + } + break; + case 'l': + $result = TType::LST; + break; + case 'm': + $result = TType::MAP; + break; + case 'r': + $result = TType::STRUCT; + break; + case 's': + if (substr($name, 1, 1) == 't') { + $result = TType::STRING; + } elseif (substr($name, 1, 1) == 'e') { + $result = TType::SET; + } + break; + case 't': + $result = TType::BOOL; + break; + } + } + if ($result == TType::STOP) { + throw new TProtocolException("Unrecognized type", TProtocolException::INVALID_DATA); + } + + return $result; + } + + public $contextStack_ = array(); + public $context_; + public $reader_; + + private function pushContext($c) + { + array_push($this->contextStack_, $this->context_); + $this->context_ = $c; + } + + private function popContext() + { + $this->context_ = array_pop($this->contextStack_); + } + + public function __construct($trans) + { + parent::__construct($trans); + $this->context_ = new BaseContext(); + $this->reader_ = new LookaheadReader($this); + } + + public function reset() + { + $this->contextStack_ = array(); + $this->context_ = new BaseContext(); + $this->reader_ = new LookaheadReader($this); + } + + private $tmpbuf_ = array(4); + + public function readJSONSyntaxChar($b) + { + $ch = $this->reader_->read(); + + if (substr($ch, 0, 1) != $b) { + throw new TProtocolException("Unexpected character: " . $ch, TProtocolException::INVALID_DATA); + } + } + + private function hexVal($s) + { + for ($i = 0; $i < strlen($s); $i++) { + $ch = substr($s, $i, 1); + + if (!($ch >= "a" && $ch <= "f") && !($ch >= "0" && $ch <= "9")) { + throw new TProtocolException("Expected hex character " . $ch, TProtocolException::INVALID_DATA); + } + } + + return hexdec($s); + } + + private function hexChar($val) + { + return dechex($val); + } + + private function hasJSONUnescapedUnicode() + { + if (PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4)) { + return true; + } + + return false; + } + + private function unescapedUnicode($str) + { + if ($this->hasJSONUnescapedUnicode()) { + return json_encode($str, JSON_UNESCAPED_UNICODE); + } + + $json = json_encode($str); + + /* + * Unescaped character outside the Basic Multilingual Plane + * High surrogate: 0xD800 - 0xDBFF + * Low surrogate: 0xDC00 - 0xDFFF + */ + $json = preg_replace_callback( + '/\\\\u(d[89ab][0-9a-f]{2})\\\\u(d[cdef][0-9a-f]{2})/i', + function ($matches) { + return mb_convert_encoding(pack('H*', $matches[1] . $matches[2]), 'UTF-8', 'UTF-16BE'); + }, + $json + ); + + /* + * Unescaped characters within the Basic Multilingual Plane + */ + $json = preg_replace_callback( + '/\\\\u([0-9a-f]{4})/i', + function ($matches) { + return mb_convert_encoding(pack('H*', $matches[1]), 'UTF-8', 'UTF-16BE'); + }, + $json + ); + + return $json; + } + + private function writeJSONString($b) + { + $this->context_->write(); + + if (is_numeric($b) && $this->context_->escapeNum()) { + $this->trans_->write(self::QUOTE); + } + + $this->trans_->write($this->unescapedUnicode($b)); + + if (is_numeric($b) && $this->context_->escapeNum()) { + $this->trans_->write(self::QUOTE); + } + } + + private function writeJSONInteger($num) + { + $this->context_->write(); + + if ($this->context_->escapeNum()) { + $this->trans_->write(self::QUOTE); + } + + $this->trans_->write($num); + + if ($this->context_->escapeNum()) { + $this->trans_->write(self::QUOTE); + } + } + + private function writeJSONDouble($num) + { + $this->context_->write(); + + if ($this->context_->escapeNum()) { + $this->trans_->write(self::QUOTE); + } + + $this->trans_->write(json_encode($num)); + + if ($this->context_->escapeNum()) { + $this->trans_->write(self::QUOTE); + } + } + + private function writeJSONBase64($data) + { + $this->context_->write(); + $this->trans_->write(self::QUOTE); + $this->trans_->write(json_encode(base64_encode($data))); + $this->trans_->write(self::QUOTE); + } + + private function writeJSONObjectStart() + { + $this->context_->write(); + $this->trans_->write(self::LBRACE); + $this->pushContext(new PairContext($this)); + } + + private function writeJSONObjectEnd() + { + $this->popContext(); + $this->trans_->write(self::RBRACE); + } + + private function writeJSONArrayStart() + { + $this->context_->write(); + $this->trans_->write(self::LBRACKET); + $this->pushContext(new ListContext($this)); + } + + private function writeJSONArrayEnd() + { + $this->popContext(); + $this->trans_->write(self::RBRACKET); + } + + private function readJSONString($skipContext) + { + if (!$skipContext) { + $this->context_->read(); + } + + $jsonString = ''; + $lastChar = null; + while (true) { + $ch = $this->reader_->read(); + $jsonString .= $ch; + if ($ch == self::QUOTE && + $lastChar !== null && + $lastChar !== self::ESCSEQ) { + break; + } + if ($ch == self::ESCSEQ && $lastChar == self::ESCSEQ) { + $lastChar = self::DOUBLEESC; + } else { + $lastChar = $ch; + } + } + + return json_decode($jsonString); + } + + private function isJSONNumeric($b) + { + switch ($b) { + case '+': + case '-': + case '.': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'E': + case 'e': + return true; + } + + return false; + } + + private function readJSONNumericChars() + { + $strbld = array(); + + while (true) { + $ch = $this->reader_->peek(); + + if (!$this->isJSONNumeric($ch)) { + break; + } + + $strbld[] = $this->reader_->read(); + } + + return implode("", $strbld); + } + + private function readJSONInteger() + { + $this->context_->read(); + + if ($this->context_->escapeNum()) { + $this->readJSONSyntaxChar(self::QUOTE); + } + + $str = $this->readJSONNumericChars(); + + if ($this->context_->escapeNum()) { + $this->readJSONSyntaxChar(self::QUOTE); + } + + if (!is_numeric($str)) { + throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA); + } + + return intval($str); + } + + /** + * Identical to readJSONInteger but without the final cast. + * Needed for proper handling of i64 on 32 bit machines. Why a + * separate function? So we don't have to force the rest of the + * use cases through the extra conditional. + */ + private function readJSONIntegerAsString() + { + $this->context_->read(); + + if ($this->context_->escapeNum()) { + $this->readJSONSyntaxChar(self::QUOTE); + } + + $str = $this->readJSONNumericChars(); + + if ($this->context_->escapeNum()) { + $this->readJSONSyntaxChar(self::QUOTE); + } + + if (!is_numeric($str)) { + throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA); + } + + return $str; + } + + private function readJSONDouble() + { + $this->context_->read(); + + if (substr($this->reader_->peek(), 0, 1) == self::QUOTE) { + $arr = $this->readJSONString(true); + + if ($arr == "NaN") { + return NAN; + } elseif ($arr == "Infinity") { + return INF; + } elseif (!$this->context_->escapeNum()) { + throw new TProtocolException( + "Numeric data unexpectedly quoted " . $arr, + TProtocolException::INVALID_DATA + ); + } + + return floatval($arr); + } else { + if ($this->context_->escapeNum()) { + $this->readJSONSyntaxChar(self::QUOTE); + } + + return floatval($this->readJSONNumericChars()); + } + } + + private function readJSONBase64() + { + $arr = $this->readJSONString(false); + $data = base64_decode($arr, true); + + if ($data === false) { + throw new TProtocolException("Invalid base64 data " . $arr, TProtocolException::INVALID_DATA); + } + + return $data; + } + + private function readJSONObjectStart() + { + $this->context_->read(); + $this->readJSONSyntaxChar(self::LBRACE); + $this->pushContext(new PairContext($this)); + } + + private function readJSONObjectEnd() + { + $this->readJSONSyntaxChar(self::RBRACE); + $this->popContext(); + } + + private function readJSONArrayStart() + { + $this->context_->read(); + $this->readJSONSyntaxChar(self::LBRACKET); + $this->pushContext(new ListContext($this)); + } + + private function readJSONArrayEnd() + { + $this->readJSONSyntaxChar(self::RBRACKET); + $this->popContext(); + } + + /** + * Writes the message header + * + * @param string $name Function name + * @param int $type message type TMessageType::CALL or TMessageType::REPLY + * @param int $seqid The sequence id of this message + */ + public function writeMessageBegin($name, $type, $seqid) + { + $this->writeJSONArrayStart(); + $this->writeJSONInteger(self::VERSION); + $this->writeJSONString($name); + $this->writeJSONInteger($type); + $this->writeJSONInteger($seqid); + } + + /** + * Close the message + */ + public function writeMessageEnd() + { + $this->writeJSONArrayEnd(); + } + + /** + * Writes a struct header. + * + * @param string $name Struct name + * @throws TException on write error + * @return int How many bytes written + */ + public function writeStructBegin($name) + { + $this->writeJSONObjectStart(); + } + + /** + * Close a struct. + * + * @throws TException on write error + * @return int How many bytes written + */ + public function writeStructEnd() + { + $this->writeJSONObjectEnd(); + } + + public function writeFieldBegin($fieldName, $fieldType, $fieldId) + { + $this->writeJSONInteger($fieldId); + $this->writeJSONObjectStart(); + $this->writeJSONString($this->getTypeNameForTypeID($fieldType)); + } + + public function writeFieldEnd() + { + $this->writeJsonObjectEnd(); + } + + public function writeFieldStop() + { + } + + public function writeMapBegin($keyType, $valType, $size) + { + $this->writeJSONArrayStart(); + $this->writeJSONString($this->getTypeNameForTypeID($keyType)); + $this->writeJSONString($this->getTypeNameForTypeID($valType)); + $this->writeJSONInteger($size); + $this->writeJSONObjectStart(); + } + + public function writeMapEnd() + { + $this->writeJSONObjectEnd(); + $this->writeJSONArrayEnd(); + } + + public function writeListBegin($elemType, $size) + { + $this->writeJSONArrayStart(); + $this->writeJSONString($this->getTypeNameForTypeID($elemType)); + $this->writeJSONInteger($size); + } + + public function writeListEnd() + { + $this->writeJSONArrayEnd(); + } + + public function writeSetBegin($elemType, $size) + { + $this->writeJSONArrayStart(); + $this->writeJSONString($this->getTypeNameForTypeID($elemType)); + $this->writeJSONInteger($size); + } + + public function writeSetEnd() + { + $this->writeJSONArrayEnd(); + } + + public function writeBool($bool) + { + $this->writeJSONInteger($bool ? 1 : 0); + } + + public function writeByte($byte) + { + $this->writeJSONInteger($byte); + } + + public function writeI16($i16) + { + $this->writeJSONInteger($i16); + } + + public function writeI32($i32) + { + $this->writeJSONInteger($i32); + } + + public function writeI64($i64) + { + $this->writeJSONInteger($i64); + } + + public function writeDouble($dub) + { + $this->writeJSONDouble($dub); + } + + public function writeString($str) + { + $this->writeJSONString($str); + } + + /** + * Reads the message header + * + * @param string $name Function name + * @param int $type message type TMessageType::CALL or TMessageType::REPLY + * @parem int $seqid The sequence id of this message + */ + public function readMessageBegin(&$name, &$type, &$seqid) + { + $this->readJSONArrayStart(); + + if ($this->readJSONInteger() != self::VERSION) { + throw new TProtocolException("Message contained bad version", TProtocolException::BAD_VERSION); + } + + $name = $this->readJSONString(false); + $type = $this->readJSONInteger(); + $seqid = $this->readJSONInteger(); + + return true; + } + + /** + * Read the close of message + */ + public function readMessageEnd() + { + $this->readJSONArrayEnd(); + } + + public function readStructBegin(&$name) + { + $this->readJSONObjectStart(); + + return 0; + } + + public function readStructEnd() + { + $this->readJSONObjectEnd(); + } + + public function readFieldBegin(&$name, &$fieldType, &$fieldId) + { + $ch = $this->reader_->peek(); + $name = ""; + + if (substr($ch, 0, 1) == self::RBRACE) { + $fieldType = TType::STOP; + } else { + $fieldId = $this->readJSONInteger(); + $this->readJSONObjectStart(); + $fieldType = $this->getTypeIDForTypeName($this->readJSONString(false)); + } + } + + public function readFieldEnd() + { + $this->readJSONObjectEnd(); + } + + public function readMapBegin(&$keyType, &$valType, &$size) + { + $this->readJSONArrayStart(); + $keyType = $this->getTypeIDForTypeName($this->readJSONString(false)); + $valType = $this->getTypeIDForTypeName($this->readJSONString(false)); + $size = $this->readJSONInteger(); + $this->readJSONObjectStart(); + } + + public function readMapEnd() + { + $this->readJSONObjectEnd(); + $this->readJSONArrayEnd(); + } + + public function readListBegin(&$elemType, &$size) + { + $this->readJSONArrayStart(); + $elemType = $this->getTypeIDForTypeName($this->readJSONString(false)); + $size = $this->readJSONInteger(); + + return true; + } + + public function readListEnd() + { + $this->readJSONArrayEnd(); + } + + public function readSetBegin(&$elemType, &$size) + { + $this->readJSONArrayStart(); + $elemType = $this->getTypeIDForTypeName($this->readJSONString(false)); + $size = $this->readJSONInteger(); + + return true; + } + + public function readSetEnd() + { + $this->readJSONArrayEnd(); + } + + public function readBool(&$bool) + { + $bool = $this->readJSONInteger() == 0 ? false : true; + + return true; + } + + public function readByte(&$byte) + { + $byte = $this->readJSONInteger(); + + return true; + } + + public function readI16(&$i16) + { + $i16 = $this->readJSONInteger(); + + return true; + } + + public function readI32(&$i32) + { + $i32 = $this->readJSONInteger(); + + return true; + } + + public function readI64(&$i64) + { + if (PHP_INT_SIZE === 4) { + $i64 = $this->readJSONIntegerAsString(); + } else { + $i64 = $this->readJSONInteger(); + } + + return true; + } + + public function readDouble(&$dub) + { + $dub = $this->readJSONDouble(); + + return true; + } + + public function readString(&$str) + { + $str = $this->readJSONString(false); + + return true; + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TMultiplexedProtocol.php b/vendor/packaged/thrift/src/Protocol/TMultiplexedProtocol.php new file mode 100644 index 000000000..d579c099d --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TMultiplexedProtocol.php @@ -0,0 +1,85 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Type\TMessageType; + +/** + * <code>TMultiplexedProtocol</code> is a protocol-independent concrete decorator + * that allows a Thrift client to communicate with a multiplexing Thrift server, + * by prepending the service name to the function name during function calls. + * + * @package Thrift\Protocol + */ +class TMultiplexedProtocol extends TProtocolDecorator +{ + /** + * Separator between service name and function name. + * Should be the same as used at multiplexed Thrift server. + * + * @var string + */ + const SEPARATOR = ":"; + + /** + * The name of service. + * + * @var string + */ + private $serviceName_; + + /** + * Constructor of <code>TMultiplexedProtocol</code> class. + * + * Wrap the specified protocol, allowing it to be used to communicate with a + * multiplexing server. The <code>$serviceName</code> is required as it is + * prepended to the message header so that the multiplexing server can broker + * the function call to the proper service. + * + * @param TProtocol $protocol + * @param string $serviceName The name of service. + */ + public function __construct(TProtocol $protocol, $serviceName) + { + parent::__construct($protocol); + $this->serviceName_ = $serviceName; + } + + /** + * Writes the message header. + * Prepends the service name to the function name, separated by <code>TMultiplexedProtocol::SEPARATOR</code>. + * + * @param string $name Function name. + * @param int $type Message type. + * @param int $seqid The sequence id of this message. + */ + public function writeMessageBegin($name, $type, $seqid) + { + if ($type == TMessageType::CALL || $type == TMessageType::ONEWAY) { + $nameWithService = $this->serviceName_ . self::SEPARATOR . $name; + parent::writeMessageBegin($nameWithService, $type, $seqid); + } else { + parent::writeMessageBegin($name, $type, $seqid); + } + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TProtocol.php b/vendor/packaged/thrift/src/Protocol/TProtocol.php new file mode 100644 index 000000000..f7b581f7b --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TProtocol.php @@ -0,0 +1,352 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Exception\TException; +use Thrift\Transport\TTransport; +use Thrift\Type\TType; +use Thrift\Exception\TProtocolException; + +/** + * Protocol base class module. + */ +abstract class TProtocol +{ + /** + * Underlying transport + * + * @var TTransport + */ + protected $trans_; + + /** + * @param TTransport $trans + */ + protected function __construct($trans) + { + $this->trans_ = $trans; + } + + /** + * Accessor for transport + * + * @return TTransport + */ + public function getTransport() + { + return $this->trans_; + } + + /** + * Writes the message header + * + * @param string $name Function name + * @param int $type message type TMessageType::CALL or TMessageType::REPLY + * @param int $seqid The sequence id of this message + */ + abstract public function writeMessageBegin($name, $type, $seqid); + + /** + * Close the message + */ + abstract public function writeMessageEnd(); + + /** + * Writes a struct header. + * + * @param string $name Struct name + * @throws TException on write error + * @return int How many bytes written + */ + abstract public function writeStructBegin($name); + + /** + * Close a struct. + * + * @throws TException on write error + * @return int How many bytes written + */ + abstract public function writeStructEnd(); + + /* + * Starts a field. + * + * @param string $name Field name + * @param int $type Field type + * @param int $fid Field id + * @throws TException on write error + * @return int How many bytes written + */ + abstract public function writeFieldBegin($fieldName, $fieldType, $fieldId); + + abstract public function writeFieldEnd(); + + abstract public function writeFieldStop(); + + abstract public function writeMapBegin($keyType, $valType, $size); + + abstract public function writeMapEnd(); + + abstract public function writeListBegin($elemType, $size); + + abstract public function writeListEnd(); + + abstract public function writeSetBegin($elemType, $size); + + abstract public function writeSetEnd(); + + abstract public function writeBool($bool); + + abstract public function writeByte($byte); + + abstract public function writeI16($i16); + + abstract public function writeI32($i32); + + abstract public function writeI64($i64); + + abstract public function writeDouble($dub); + + abstract public function writeString($str); + + /** + * Reads the message header + * + * @param string $name Function name + * @param int $type message type TMessageType::CALL or TMessageType::REPLY + * @parem int $seqid The sequence id of this message + */ + abstract public function readMessageBegin(&$name, &$type, &$seqid); + + /** + * Read the close of message + */ + abstract public function readMessageEnd(); + + abstract public function readStructBegin(&$name); + + abstract public function readStructEnd(); + + abstract public function readFieldBegin(&$name, &$fieldType, &$fieldId); + + abstract public function readFieldEnd(); + + abstract public function readMapBegin(&$keyType, &$valType, &$size); + + abstract public function readMapEnd(); + + abstract public function readListBegin(&$elemType, &$size); + + abstract public function readListEnd(); + + abstract public function readSetBegin(&$elemType, &$size); + + abstract public function readSetEnd(); + + abstract public function readBool(&$bool); + + abstract public function readByte(&$byte); + + abstract public function readI16(&$i16); + + abstract public function readI32(&$i32); + + abstract public function readI64(&$i64); + + abstract public function readDouble(&$dub); + + abstract public function readString(&$str); + + /** + * The skip function is a utility to parse over unrecognized date without + * causing corruption. + * + * @param TType $type What type is it + */ + public function skip($type) + { + switch ($type) { + case TType::BOOL: + return $this->readBool($bool); + case TType::BYTE: + return $this->readByte($byte); + case TType::I16: + return $this->readI16($i16); + case TType::I32: + return $this->readI32($i32); + case TType::I64: + return $this->readI64($i64); + case TType::DOUBLE: + return $this->readDouble($dub); + case TType::STRING: + return $this->readString($str); + case TType::STRUCT: + $result = $this->readStructBegin($name); + while (true) { + $result += $this->readFieldBegin($name, $ftype, $fid); + if ($ftype == TType::STOP) { + break; + } + $result += $this->skip($ftype); + $result += $this->readFieldEnd(); + } + $result += $this->readStructEnd(); + + return $result; + + case TType::MAP: + $result = $this->readMapBegin($keyType, $valType, $size); + for ($i = 0; $i < $size; $i++) { + $result += $this->skip($keyType); + $result += $this->skip($valType); + } + $result += $this->readMapEnd(); + + return $result; + + case TType::SET: + $result = $this->readSetBegin($elemType, $size); + for ($i = 0; $i < $size; $i++) { + $result += $this->skip($elemType); + } + $result += $this->readSetEnd(); + + return $result; + + case TType::LST: + $result = $this->readListBegin($elemType, $size); + for ($i = 0; $i < $size; $i++) { + $result += $this->skip($elemType); + } + $result += $this->readListEnd(); + + return $result; + + default: + throw new TProtocolException( + 'Unknown field type: ' . $type, + TProtocolException::INVALID_DATA + ); + } + } + + /** + * Utility for skipping binary data + * + * @param TTransport $itrans TTransport object + * @param int $type Field type + */ + public static function skipBinary($itrans, $type) + { + switch ($type) { + case TType::BOOL: + return $itrans->readAll(1); + case TType::BYTE: + return $itrans->readAll(1); + case TType::I16: + return $itrans->readAll(2); + case TType::I32: + return $itrans->readAll(4); + case TType::I64: + return $itrans->readAll(8); + case TType::DOUBLE: + return $itrans->readAll(8); + case TType::STRING: + $len = unpack('N', $itrans->readAll(4)); + $len = $len[1]; + if ($len > 0x7fffffff) { + $len = 0 - (($len - 1) ^ 0xffffffff); + } + + return 4 + $itrans->readAll($len); + + case TType::STRUCT: + $result = 0; + while (true) { + $ftype = 0; + $fid = 0; + $data = $itrans->readAll(1); + $arr = unpack('c', $data); + $ftype = $arr[1]; + if ($ftype == TType::STOP) { + break; + } + // I16 field id + $result += $itrans->readAll(2); + $result += self::skipBinary($itrans, $ftype); + } + + return $result; + + case TType::MAP: + // Ktype + $data = $itrans->readAll(1); + $arr = unpack('c', $data); + $ktype = $arr[1]; + // Vtype + $data = $itrans->readAll(1); + $arr = unpack('c', $data); + $vtype = $arr[1]; + // Size + $data = $itrans->readAll(4); + $arr = unpack('N', $data); + $size = $arr[1]; + if ($size > 0x7fffffff) { + $size = 0 - (($size - 1) ^ 0xffffffff); + } + $result = 6; + for ($i = 0; $i < $size; $i++) { + $result += self::skipBinary($itrans, $ktype); + $result += self::skipBinary($itrans, $vtype); + } + + return $result; + + case TType::SET: + case TType::LST: + // Vtype + $data = $itrans->readAll(1); + $arr = unpack('c', $data); + $vtype = $arr[1]; + // Size + $data = $itrans->readAll(4); + $arr = unpack('N', $data); + $size = $arr[1]; + if ($size > 0x7fffffff) { + $size = 0 - (($size - 1) ^ 0xffffffff); + } + $result = 5; + for ($i = 0; $i < $size; $i++) { + $result += self::skipBinary($itrans, $vtype); + } + + return $result; + + default: + throw new TProtocolException( + 'Unknown field type: ' . $type, + TProtocolException::INVALID_DATA + ); + } + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TProtocolDecorator.php b/vendor/packaged/thrift/src/Protocol/TProtocolDecorator.php new file mode 100644 index 000000000..a85e0b8e5 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TProtocolDecorator.php @@ -0,0 +1,285 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Exception\TException; + +/** + * <code>TProtocolDecorator</code> forwards all requests to an enclosed + * <code>TProtocol</code> instance, providing a way to author concise + * concrete decorator subclasses. While it has no abstract methods, it + * is marked abstract as a reminder that by itself, it does not modify + * the behaviour of the enclosed <code>TProtocol</code>. + * + * @package Thrift\Protocol + */ +abstract class TProtocolDecorator extends TProtocol +{ + /** + * Instance of protocol, to which all operations will be forwarded. + * + * @var TProtocol + */ + private $concreteProtocol_; + + /** + * Constructor of <code>TProtocolDecorator</code> class. + * Encloses the specified protocol. + * + * @param TProtocol $protocol All operations will be forward to this instance. Must be non-null. + */ + protected function __construct(TProtocol $protocol) + { + parent::__construct($protocol->getTransport()); + $this->concreteProtocol_ = $protocol; + } + + /** + * Writes the message header. + * + * @param string $name Function name + * @param int $type message type TMessageType::CALL or TMessageType::REPLY + * @param int $seqid The sequence id of this message + */ + public function writeMessageBegin($name, $type, $seqid) + { + return $this->concreteProtocol_->writeMessageBegin($name, $type, $seqid); + } + + /** + * Closes the message. + */ + public function writeMessageEnd() + { + return $this->concreteProtocol_->writeMessageEnd(); + } + + /** + * Writes a struct header. + * + * @param string $name Struct name + * + * @throws TException on write error + * @return int How many bytes written + */ + public function writeStructBegin($name) + { + return $this->concreteProtocol_->writeStructBegin($name); + } + + /** + * Close a struct. + * + * @throws TException on write error + * @return int How many bytes written + */ + public function writeStructEnd() + { + return $this->concreteProtocol_->writeStructEnd(); + } + + public function writeFieldBegin($fieldName, $fieldType, $fieldId) + { + return $this->concreteProtocol_->writeFieldBegin($fieldName, $fieldType, $fieldId); + } + + public function writeFieldEnd() + { + return $this->concreteProtocol_->writeFieldEnd(); + } + + public function writeFieldStop() + { + return $this->concreteProtocol_->writeFieldStop(); + } + + public function writeMapBegin($keyType, $valType, $size) + { + return $this->concreteProtocol_->writeMapBegin($keyType, $valType, $size); + } + + public function writeMapEnd() + { + return $this->concreteProtocol_->writeMapEnd(); + } + + public function writeListBegin($elemType, $size) + { + return $this->concreteProtocol_->writeListBegin($elemType, $size); + } + + public function writeListEnd() + { + return $this->concreteProtocol_->writeListEnd(); + } + + public function writeSetBegin($elemType, $size) + { + return $this->concreteProtocol_->writeSetBegin($elemType, $size); + } + + public function writeSetEnd() + { + return $this->concreteProtocol_->writeSetEnd(); + } + + public function writeBool($bool) + { + return $this->concreteProtocol_->writeBool($bool); + } + + public function writeByte($byte) + { + return $this->concreteProtocol_->writeByte($byte); + } + + public function writeI16($i16) + { + return $this->concreteProtocol_->writeI16($i16); + } + + public function writeI32($i32) + { + return $this->concreteProtocol_->writeI32($i32); + } + + public function writeI64($i64) + { + return $this->concreteProtocol_->writeI64($i64); + } + + public function writeDouble($dub) + { + return $this->concreteProtocol_->writeDouble($dub); + } + + public function writeString($str) + { + return $this->concreteProtocol_->writeString($str); + } + + /** + * Reads the message header + * + * @param string $name Function name + * @param int $type message type TMessageType::CALL or TMessageType::REPLY + * @param int $seqid The sequence id of this message + */ + public function readMessageBegin(&$name, &$type, &$seqid) + { + return $this->concreteProtocol_->readMessageBegin($name, $type, $seqid); + } + + /** + * Read the close of message + */ + public function readMessageEnd() + { + return $this->concreteProtocol_->readMessageEnd(); + } + + public function readStructBegin(&$name) + { + return $this->concreteProtocol_->readStructBegin($name); + } + + public function readStructEnd() + { + return $this->concreteProtocol_->readStructEnd(); + } + + public function readFieldBegin(&$name, &$fieldType, &$fieldId) + { + return $this->concreteProtocol_->readFieldBegin($name, $fieldType, $fieldId); + } + + public function readFieldEnd() + { + return $this->concreteProtocol_->readFieldEnd(); + } + + public function readMapBegin(&$keyType, &$valType, &$size) + { + $this->concreteProtocol_->readMapBegin($keyType, $valType, $size); + } + + public function readMapEnd() + { + return $this->concreteProtocol_->readMapEnd(); + } + + public function readListBegin(&$elemType, &$size) + { + $this->concreteProtocol_->readListBegin($elemType, $size); + } + + public function readListEnd() + { + return $this->concreteProtocol_->readListEnd(); + } + + public function readSetBegin(&$elemType, &$size) + { + return $this->concreteProtocol_->readSetBegin($elemType, $size); + } + + public function readSetEnd() + { + return $this->concreteProtocol_->readSetEnd(); + } + + public function readBool(&$bool) + { + return $this->concreteProtocol_->readBool($bool); + } + + public function readByte(&$byte) + { + return $this->concreteProtocol_->readByte($byte); + } + + public function readI16(&$i16) + { + return $this->concreteProtocol_->readI16($i16); + } + + public function readI32(&$i32) + { + return $this->concreteProtocol_->readI32($i32); + } + + public function readI64(&$i64) + { + return $this->concreteProtocol_->readI64($i64); + } + + public function readDouble(&$dub) + { + return $this->concreteProtocol_->readDouble($dub); + } + + public function readString(&$str) + { + return $this->concreteProtocol_->readString($str); + } +} diff --git a/vendor/packaged/thrift/src/Protocol/TSimpleJSONProtocol.php b/vendor/packaged/thrift/src/Protocol/TSimpleJSONProtocol.php new file mode 100644 index 000000000..1cf1f6407 --- /dev/null +++ b/vendor/packaged/thrift/src/Protocol/TSimpleJSONProtocol.php @@ -0,0 +1,374 @@ +<?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.protocol + */ + +namespace Thrift\Protocol; + +use Thrift\Exception\TException; +use Thrift\Exception\TProtocolException; +use Thrift\Protocol\SimpleJSON\Context; +use Thrift\Protocol\SimpleJSON\ListContext; +use Thrift\Protocol\SimpleJSON\StructContext; +use Thrift\Protocol\SimpleJSON\MapContext; +use Thrift\Protocol\SimpleJSON\CollectionMapKeyException; + +/** + * SimpleJSON implementation of thrift protocol, ported from Java. + */ +class TSimpleJSONProtocol extends TProtocol +{ + const COMMA = ','; + const COLON = ':'; + const LBRACE = '{'; + const RBRACE = '}'; + const LBRACKET = '['; + const RBRACKET = ']'; + const QUOTE = '"'; + + const NAME_MAP = "map"; + const NAME_LIST = "lst"; + const NAME_SET = "set"; + + protected $writeContext_ = null; + protected $writeContextStack_ = []; + + /** + * Push a new write context onto the stack. + */ + protected function pushWriteContext(Context $c) + { + $this->writeContextStack_[] = $this->writeContext_; + $this->writeContext_ = $c; + } + + /** + * Pop the last write context off the stack + */ + protected function popWriteContext() + { + $this->writeContext_ = array_pop($this->writeContextStack_); + } + + /** + * Used to make sure that we are not encountering a map whose keys are containers + */ + protected function assertContextIsNotMapKey($invalidKeyType) + { + if ($this->writeContext_->isMapKey()) { + throw new CollectionMapKeyException( + "Cannot serialize a map with keys that are of type " . + $invalidKeyType + ); + } + } + + private function writeJSONString($b) + { + $this->writeContext_->write(); + + $this->trans_->write(json_encode((string)$b)); + } + + private function writeJSONInteger($num) + { + $isMapKey = $this->writeContext_->isMapKey(); + + $this->writeContext_->write(); + + if ($isMapKey) { + $this->trans_->write(self::QUOTE); + } + + $this->trans_->write((int)$num); + + if ($isMapKey) { + $this->trans_->write(self::QUOTE); + } + } + + private function writeJSONDouble($num) + { + $isMapKey = $this->writeContext_->isMapKey(); + + $this->writeContext_->write(); + + if ($isMapKey) { + $this->trans_->write(self::QUOTE); + } + + $this->trans_->write(json_encode((float)$num)); + + if ($isMapKey) { + $this->trans_->write(self::QUOTE); + } + } + + /** + * Constructor + */ + public function __construct($trans) + { + parent::__construct($trans); + $this->writeContext_ = new Context(); + } + + /** + * Writes the message header + * + * @param string $name Function name + * @param int $type message type TMessageType::CALL or TMessageType::REPLY + * @param int $seqid The sequence id of this message + */ + public function writeMessageBegin($name, $type, $seqid) + { + $this->trans_->write(self::LBRACKET); + $this->pushWriteContext(new ListContext($this)); + $this->writeJSONString($name); + $this->writeJSONInteger($type); + $this->writeJSONInteger($seqid); + } + + /** + * Close the message + */ + public function writeMessageEnd() + { + $this->popWriteContext(); + $this->trans_->write(self::RBRACKET); + } + + /** + * Writes a struct header. + * + * @param string $name Struct name + */ + public function writeStructBegin($name) + { + $this->writeContext_->write(); + $this->trans_->write(self::LBRACE); + $this->pushWriteContext(new StructContext($this)); + } + + /** + * Close a struct. + */ + public function writeStructEnd() + { + $this->popWriteContext(); + $this->trans_->write(self::RBRACE); + } + + public function writeFieldBegin($fieldName, $fieldType, $fieldId) + { + $this->writeJSONString($fieldName); + } + + public function writeFieldEnd() + { + } + + public function writeFieldStop() + { + } + + public function writeMapBegin($keyType, $valType, $size) + { + $this->assertContextIsNotMapKey(self::NAME_MAP); + $this->writeContext_->write(); + $this->trans_->write(self::LBRACE); + $this->pushWriteContext(new MapContext($this)); + } + + public function writeMapEnd() + { + $this->popWriteContext(); + $this->trans_->write(self::RBRACE); + } + + public function writeListBegin($elemType, $size) + { + $this->assertContextIsNotMapKey(self::NAME_LIST); + $this->writeContext_->write(); + $this->trans_->write(self::LBRACKET); + $this->pushWriteContext(new ListContext($this)); + // No metadata! + } + + public function writeListEnd() + { + $this->popWriteContext(); + $this->trans_->write(self::RBRACKET); + } + + public function writeSetBegin($elemType, $size) + { + $this->assertContextIsNotMapKey(self::NAME_SET); + $this->writeContext_->write(); + $this->trans_->write(self::LBRACKET); + $this->pushWriteContext(new ListContext($this)); + // No metadata! + } + + public function writeSetEnd() + { + $this->popWriteContext(); + $this->trans_->write(self::RBRACKET); + } + + public function writeBool($bool) + { + $this->writeJSONInteger($bool ? 1 : 0); + } + + public function writeByte($byte) + { + $this->writeJSONInteger($byte); + } + + public function writeI16($i16) + { + $this->writeJSONInteger($i16); + } + + public function writeI32($i32) + { + $this->writeJSONInteger($i32); + } + + public function writeI64($i64) + { + $this->writeJSONInteger($i64); + } + + public function writeDouble($dub) + { + $this->writeJSONDouble($dub); + } + + public function writeString($str) + { + $this->writeJSONString($str); + } + + /** + * Reading methods. + * + * simplejson is not meant to be read back into thrift + * - see http://wiki.apache.org/thrift/ThriftUsageJava + * - use JSON instead + */ + + public function readMessageBegin(&$name, &$type, &$seqid) + { + throw new TException("Not implemented"); + } + + public function readMessageEnd() + { + throw new TException("Not implemented"); + } + + public function readStructBegin(&$name) + { + throw new TException("Not implemented"); + } + + public function readStructEnd() + { + throw new TException("Not implemented"); + } + + public function readFieldBegin(&$name, &$fieldType, &$fieldId) + { + throw new TException("Not implemented"); + } + + public function readFieldEnd() + { + throw new TException("Not implemented"); + } + + public function readMapBegin(&$keyType, &$valType, &$size) + { + throw new TException("Not implemented"); + } + + public function readMapEnd() + { + throw new TException("Not implemented"); + } + + public function readListBegin(&$elemType, &$size) + { + throw new TException("Not implemented"); + } + + public function readListEnd() + { + throw new TException("Not implemented"); + } + + public function readSetBegin(&$elemType, &$size) + { + throw new TException("Not implemented"); + } + + public function readSetEnd() + { + throw new TException("Not implemented"); + } + + public function readBool(&$bool) + { + throw new TException("Not implemented"); + } + + public function readByte(&$byte) + { + throw new TException("Not implemented"); + } + + public function readI16(&$i16) + { + throw new TException("Not implemented"); + } + + public function readI32(&$i32) + { + throw new TException("Not implemented"); + } + + public function readI64(&$i64) + { + throw new TException("Not implemented"); + } + + public function readDouble(&$dub) + { + throw new TException("Not implemented"); + } + + public function readString(&$str) + { + throw new TException("Not implemented"); + } +} diff --git a/vendor/packaged/thrift/src/Serializer/TBinarySerializer.php b/vendor/packaged/thrift/src/Serializer/TBinarySerializer.php new file mode 100644 index 000000000..9d2b14730 --- /dev/null +++ b/vendor/packaged/thrift/src/Serializer/TBinarySerializer.php @@ -0,0 +1,87 @@ +<?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.protocol + * @author: rmarin ([email protected]) + */ + +namespace Thrift\Serializer; + +use Thrift\Transport\TMemoryBuffer; +use Thrift\Protocol\TBinaryProtocolAccelerated; +use Thrift\Type\TMessageType; + +/** + * Utility class for serializing and deserializing + * a thrift object using TBinaryProtocolAccelerated. + */ +class TBinarySerializer +{ + // NOTE(rmarin): Because thrift_protocol_write_binary + // adds a begin message prefix, you cannot specify + // a transport in which to serialize an object. It has to + // be a string. Otherwise we will break the compatibility with + // normal deserialization. + public static function serialize($object) + { + $transport = new TMemoryBuffer(); + $protocol = new TBinaryProtocolAccelerated($transport); + if (function_exists('thrift_protocol_write_binary')) { + thrift_protocol_write_binary( + $protocol, + $object->getName(), + TMessageType::REPLY, + $object, + 0, + $protocol->isStrictWrite() + ); + + $protocol->readMessageBegin($unused_name, $unused_type, $unused_seqid); + } else { + $object->write($protocol); + } + $protocol->getTransport()->flush(); + + return $transport->getBuffer(); + } + + public static function deserialize($string_object, $class_name, $buffer_size = 8192) + { + $transport = new TMemoryBuffer(); + $protocol = new TBinaryProtocolAccelerated($transport); + if (function_exists('thrift_protocol_read_binary')) { + // NOTE (t.heintz) TBinaryProtocolAccelerated internally wraps our TMemoryBuffer in a + // TBufferedTransport, so we have to retrieve it again or risk losing data when writing + // less than 512 bytes to the transport (see the comment there as well). + // @see THRIFT-1579 + $protocol->writeMessageBegin('', TMessageType::REPLY, 0); + $protocolTransport = $protocol->getTransport(); + $protocolTransport->write($string_object); + $protocolTransport->flush(); + + return thrift_protocol_read_binary($protocol, $class_name, $protocol->isStrictRead(), $buffer_size); + } else { + $transport->write($string_object); + $object = new $class_name(); + $object->read($protocol); + + return $object; + } + } +} diff --git a/vendor/packaged/thrift/src/Server/TForkingServer.php b/vendor/packaged/thrift/src/Server/TForkingServer.php new file mode 100644 index 000000000..0bb6e9192 --- /dev/null +++ b/vendor/packaged/thrift/src/Server/TForkingServer.php @@ -0,0 +1,125 @@ +<?php + +namespace Thrift\Server; + +use Thrift\Transport\TTransport; +use Thrift\Exception\TException; +use Thrift\Exception\TTransportException; + +/** + * A forking implementation of a Thrift server. + * + * @package thrift.server + */ +class TForkingServer extends TServer +{ + /** + * Flag for the main serving loop + * + * @var bool + */ + private $stop_ = false; + + /** + * List of children. + * + * @var array + */ + protected $children_ = array(); + + /** + * Listens for new client using the supplied + * transport. We fork when a new connection + * arrives. + * + * @return void + */ + public function serve() + { + $this->transport_->listen(); + + while (!$this->stop_) { + try { + $transport = $this->transport_->accept(); + + if ($transport != null) { + $pid = pcntl_fork(); + + if ($pid > 0) { + $this->handleParent($transport, $pid); + } elseif ($pid === 0) { + $this->handleChild($transport); + } else { + throw new TException('Failed to fork'); + } + } + } catch (TTransportException $e) { + } + + $this->collectChildren(); + } + } + + /** + * Code run by the parent + * + * @param TTransport $transport + * @param int $pid + * @return void + */ + private function handleParent(TTransport $transport, $pid) + { + $this->children_[$pid] = $transport; + } + + /** + * Code run by the child. + * + * @param TTransport $transport + * @return void + */ + private function handleChild(TTransport $transport) + { + try { + $inputTransport = $this->inputTransportFactory_->getTransport($transport); + $outputTransport = $this->outputTransportFactory_->getTransport($transport); + $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport); + $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport); + while ($this->processor_->process($inputProtocol, $outputProtocol)) { + } + @$transport->close(); + } catch (TTransportException $e) { + } + + exit(0); + } + + /** + * Collects any children we may have + * + * @return void + */ + private function collectChildren() + { + foreach ($this->children_ as $pid => $transport) { + if (pcntl_waitpid($pid, $status, WNOHANG) > 0) { + unset($this->children_[$pid]); + if ($transport) { + @$transport->close(); + } + } + } + } + + /** + * Stops the server running. Kills the transport + * and then stops the main serving loop + * + * @return void + */ + public function stop() + { + $this->transport_->close(); + $this->stop_ = true; + } +} diff --git a/vendor/packaged/thrift/src/Server/TSSLServerSocket.php b/vendor/packaged/thrift/src/Server/TSSLServerSocket.php new file mode 100644 index 000000000..ac589b76b --- /dev/null +++ b/vendor/packaged/thrift/src/Server/TSSLServerSocket.php @@ -0,0 +1,97 @@ +<?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. + * + */ + +namespace Thrift\Server; + +use Thrift\Transport\TSSLSocket; + +/** + * Socket implementation of a server agent. + * + * @package thrift.transport + */ +class TSSLServerSocket extends TServerSocket +{ + /** + * Remote port + * + * @var resource + */ + protected $context_ = null; + + /** + * ServerSocket constructor + * + * @param string $host Host to listen on + * @param int $port Port to listen on + * @param resource $context Stream context + * @return void + */ + public function __construct($host = 'localhost', $port = 9090, $context = null) + { + $ssl_host = $this->getSSLHost($host); + parent::__construct($ssl_host, $port); + $this->context_ = $context; + } + + public function getSSLHost($host) + { + $transport_protocol_loc = strpos($host, "://"); + if ($transport_protocol_loc === false) { + $host = 'ssl://' . $host; + } + return $host; + } + + /** + * Opens a new socket server handle + * + * @return void + */ + public function listen() + { + $this->listener_ = @stream_socket_server( + $this->host_ . ':' . $this->port_, + $errno, + $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, + $this->context_ + ); + } + + /** + * Implementation of accept. If not client is accepted in the given time + * + * @return TSocket + */ + protected function acceptImpl() + { + $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0); + if (!$handle) { + return null; + } + + $socket = new TSSLSocket(); + $socket->setHandle($handle); + + return $socket; + } +} diff --git a/vendor/packaged/thrift/src/Server/TServer.php b/vendor/packaged/thrift/src/Server/TServer.php new file mode 100644 index 000000000..268c37820 --- /dev/null +++ b/vendor/packaged/thrift/src/Server/TServer.php @@ -0,0 +1,102 @@ +<?php + +namespace Thrift\Server; + +use Thrift\Factory\TTransportFactory; +use Thrift\Factory\TProtocolFactory; + +/** + * Generic class for a Thrift server. + * + * @package thrift.server + */ +abstract class TServer +{ + /** + * Processor to handle new clients + * + * @var TProcessor + */ + protected $processor_; + + /** + * Server transport to be used for listening + * and accepting new clients + * + * @var TServerTransport + */ + protected $transport_; + + /** + * Input transport factory + * + * @var TTransportFactory + */ + protected $inputTransportFactory_; + + /** + * Output transport factory + * + * @var TTransportFactory + */ + protected $outputTransportFactory_; + + /** + * Input protocol factory + * + * @var TProtocolFactory + */ + protected $inputProtocolFactory_; + + /** + * Output protocol factory + * + * @var TProtocolFactory + */ + protected $outputProtocolFactory_; + + /** + * Sets up all the factories, etc + * + * @param object $processor + * @param TServerTransport $transport + * @param TTransportFactory $inputTransportFactory + * @param TTransportFactory $outputTransportFactory + * @param TProtocolFactory $inputProtocolFactory + * @param TProtocolFactory $outputProtocolFactory + * @return void + */ + public function __construct( + $processor, + TServerTransport $transport, + TTransportFactory $inputTransportFactory, + TTransportFactory $outputTransportFactory, + TProtocolFactory $inputProtocolFactory, + TProtocolFactory $outputProtocolFactory + ) { + $this->processor_ = $processor; + $this->transport_ = $transport; + $this->inputTransportFactory_ = $inputTransportFactory; + $this->outputTransportFactory_ = $outputTransportFactory; + $this->inputProtocolFactory_ = $inputProtocolFactory; + $this->outputProtocolFactory_ = $outputProtocolFactory; + } + + /** + * Serves the server. This should never return + * unless a problem permits it to do so or it + * is interrupted intentionally + * + * @abstract + * @return void + */ + abstract public function serve(); + + /** + * Stops the server serving + * + * @abstract + * @return void + */ + abstract public function stop(); +} diff --git a/vendor/packaged/thrift/src/Server/TServerSocket.php b/vendor/packaged/thrift/src/Server/TServerSocket.php new file mode 100644 index 000000000..8f38fb23f --- /dev/null +++ b/vendor/packaged/thrift/src/Server/TServerSocket.php @@ -0,0 +1,124 @@ +<?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.transport + */ + +namespace Thrift\Server; + +use Thrift\Transport\TSocket; + +/** + * Socket implementation of a server agent. + * + * @package thrift.transport + */ +class TServerSocket extends TServerTransport +{ + /** + * Handle for the listener socket + * + * @var resource + */ + protected $listener_; + + /** + * Port for the listener to listen on + * + * @var int + */ + protected $port_; + + /** + * Timeout when listening for a new client + * + * @var int + */ + protected $acceptTimeout_ = 30000; + + /** + * Host to listen on + * + * @var string + */ + protected $host_; + + /** + * ServerSocket constructor + * + * @param string $host Host to listen on + * @param int $port Port to listen on + * @return void + */ + public function __construct($host = 'localhost', $port = 9090) + { + $this->host_ = $host; + $this->port_ = $port; + } + + /** + * Sets the accept timeout + * + * @param int $acceptTimeout + * @return void + */ + public function setAcceptTimeout($acceptTimeout) + { + $this->acceptTimeout_ = $acceptTimeout; + } + + /** + * Opens a new socket server handle + * + * @return void + */ + public function listen() + { + $this->listener_ = stream_socket_server('tcp://' . $this->host_ . ':' . $this->port_); + } + + /** + * Closes the socket server handle + * + * @return void + */ + public function close() + { + @fclose($this->listener_); + $this->listener_ = null; + } + + /** + * Implementation of accept. If not client is accepted in the given time + * + * @return TSocket + */ + protected function acceptImpl() + { + $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0); + if (!$handle) { + return null; + } + + $socket = new TSocket(); + $socket->setHandle($handle); + + return $socket; + } +} diff --git a/vendor/packaged/thrift/src/Server/TServerTransport.php b/vendor/packaged/thrift/src/Server/TServerTransport.php new file mode 100644 index 000000000..15a27afa8 --- /dev/null +++ b/vendor/packaged/thrift/src/Server/TServerTransport.php @@ -0,0 +1,56 @@ +<?php + +namespace Thrift\Server; + +use Thrift\Exception\TTransportException; + +/** + * Generic class for Server agent. + * + * @package thrift.transport + */ +abstract class TServerTransport +{ + /** + * List for new clients + * + * @abstract + * @return void + */ + abstract public function listen(); + + /** + * Close the server + * + * @abstract + * @return void + */ + abstract public function close(); + + /** + * Subclasses should use this to implement + * accept. + * + * @abstract + * @return TTransport + */ + abstract protected function acceptImpl(); + + /** + * Uses the accept implemtation. If null is returned, an + * exception is thrown. + * + * @throws TTransportException + * @return TTransport + */ + public function accept() + { + $transport = $this->acceptImpl(); + + if ($transport == null) { + throw new TTransportException("accept() may not return NULL"); + } + + return $transport; + } +} diff --git a/vendor/packaged/thrift/src/Server/TSimpleServer.php b/vendor/packaged/thrift/src/Server/TSimpleServer.php new file mode 100644 index 000000000..4c1dda5a5 --- /dev/null +++ b/vendor/packaged/thrift/src/Server/TSimpleServer.php @@ -0,0 +1,60 @@ +<?php + +namespace Thrift\Server; + +use Thrift\Exception\TTransportException; + +/** + * Simple implemtation of a Thrift server. + * + * @package thrift.server + */ +class TSimpleServer extends TServer +{ + /** + * Flag for the main serving loop + * + * @var bool + */ + private $stop_ = false; + + /** + * Listens for new client using the supplied + * transport. It handles TTransportExceptions + * to avoid timeouts etc killing it + * + * @return void + */ + public function serve() + { + $this->transport_->listen(); + + while (!$this->stop_) { + try { + $transport = $this->transport_->accept(); + + if ($transport != null) { + $inputTransport = $this->inputTransportFactory_->getTransport($transport); + $outputTransport = $this->outputTransportFactory_->getTransport($transport); + $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport); + $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport); + while ($this->processor_->process($inputProtocol, $outputProtocol)) { + } + } + } catch (TTransportException $e) { + } + } + } + + /** + * Stops the server running. Kills the transport + * and then stops the main serving loop + * + * @return void + */ + public function stop() + { + $this->transport_->close(); + $this->stop_ = true; + } +} diff --git a/vendor/packaged/thrift/src/StoredMessageProtocol.php b/vendor/packaged/thrift/src/StoredMessageProtocol.php new file mode 100644 index 000000000..c4aaaa9ec --- /dev/null +++ b/vendor/packaged/thrift/src/StoredMessageProtocol.php @@ -0,0 +1,53 @@ +<?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.processor + */ + +namespace Thrift; + +use Thrift\Protocol\TProtocol; +use Thrift\Protocol\TProtocolDecorator; + +/** + * Our goal was to work with any protocol. In order to do that, we needed + * to allow them to call readMessageBegin() and get the Message in exactly + * the standard format, without the service name prepended to the Message name. + */ +class StoredMessageProtocol extends TProtocolDecorator +{ + private $fname_; + private $mtype_; + private $rseqid_; + + public function __construct(TProtocol $protocol, $fname, $mtype, $rseqid) + { + parent::__construct($protocol); + $this->fname_ = $fname; + $this->mtype_ = $mtype; + $this->rseqid_ = $rseqid; + } + + public function readMessageBegin(&$name, &$type, &$seqid) + { + $name = $this->fname_; + $type = $this->mtype_; + $seqid = $this->rseqid_; + } +} diff --git a/vendor/packaged/thrift/src/StringFunc/Core.php b/vendor/packaged/thrift/src/StringFunc/Core.php new file mode 100644 index 000000000..39a75b3a2 --- /dev/null +++ b/vendor/packaged/thrift/src/StringFunc/Core.php @@ -0,0 +1,40 @@ +<?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. + * + */ + +namespace Thrift\StringFunc; + +class Core implements TStringFunc +{ + public function substr($str, $start, $length = null) + { + // specifying a null $length would return an empty string + if ($length === null) { + return substr($str, $start); + } + + return substr($str, $start, $length); + } + + public function strlen($str) + { + return strlen($str); + } +} diff --git a/vendor/packaged/thrift/src/StringFunc/Mbstring.php b/vendor/packaged/thrift/src/StringFunc/Mbstring.php new file mode 100644 index 000000000..968ff18f1 --- /dev/null +++ b/vendor/packaged/thrift/src/StringFunc/Mbstring.php @@ -0,0 +1,46 @@ +<?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. + * + */ + +namespace Thrift\StringFunc; + +class Mbstring implements TStringFunc +{ + public function substr($str, $start, $length = null) + { + /** + * We need to set the charset parameter, which is the second + * optional parameter and the first optional parameter can't + * be null or false as a "magic" value because that would + * cause an empty string to be returned, so we need to + * actually calculate the proper length value. + */ + if ($length === null) { + $length = $this->strlen($str) - $start; + } + + return mb_substr($str, $start, $length, '8bit'); + } + + public function strlen($str) + { + return mb_strlen($str, '8bit'); + } +} diff --git a/vendor/packaged/thrift/src/StringFunc/TStringFunc.php b/vendor/packaged/thrift/src/StringFunc/TStringFunc.php new file mode 100644 index 000000000..dea497f2e --- /dev/null +++ b/vendor/packaged/thrift/src/StringFunc/TStringFunc.php @@ -0,0 +1,28 @@ +<?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. + * + */ + +namespace Thrift\StringFunc; + +interface TStringFunc +{ + public function substr($str, $start, $length = null); + public function strlen($str); +} diff --git a/vendor/packaged/thrift/src/TMultiplexedProcessor.php b/vendor/packaged/thrift/src/TMultiplexedProcessor.php new file mode 100644 index 000000000..a64a9687c --- /dev/null +++ b/vendor/packaged/thrift/src/TMultiplexedProcessor.php @@ -0,0 +1,118 @@ +<?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.processor + */ + +namespace Thrift; + +use Thrift\Exception\TException; +use Thrift\Protocol\TProtocol; +use Thrift\Protocol\TMultiplexedProtocol; +use Thrift\Type\TMessageType; + +/** + * <code>TMultiplexedProcessor</code> is a Processor allowing + * a single <code>TServer</code> to provide multiple services. + * + * <p>To do so, you instantiate the processor and then register additional + * processors with it, as shown in the following example:</p> + * + * <blockquote><code> + * $processor = new TMultiplexedProcessor(); + * + * processor->registerProcessor( + * "Calculator", + * new \tutorial\CalculatorProcessor(new CalculatorHandler())); + * + * processor->registerProcessor( + * "WeatherReport", + * new \tutorial\WeatherReportProcessor(new WeatherReportHandler())); + * + * $processor->process($protocol, $protocol); + * </code></blockquote> + */ + +class TMultiplexedProcessor +{ + private $serviceProcessorMap_; + + /** + * 'Register' a service with this <code>TMultiplexedProcessor</code>. This + * allows us to broker requests to individual services by using the service + * name to select them at request time. + * + * @param serviceName Name of a service, has to be identical to the name + * declared in the Thrift IDL, e.g. "WeatherReport". + * @param processor Implementation of a service, usually referred to + * as "handlers", e.g. WeatherReportHandler implementing WeatherReport.Iface. + */ + public function registerProcessor($serviceName, $processor) + { + $this->serviceProcessorMap_[$serviceName] = $processor; + } + + /** + * This implementation of <code>process</code> performs the following steps: + * + * <ol> + * <li>Read the beginning of the message.</li> + * <li>Extract the service name from the message.</li> + * <li>Using the service name to locate the appropriate processor.</li> + * <li>Dispatch to the processor, with a decorated instance of TProtocol + * that allows readMessageBegin() to return the original Message.</li> + * </ol> + * + * @throws TException If the message type is not CALL or ONEWAY, if + * the service name was not found in the message, or if the service + * name was not found in the service map. + */ + public function process(TProtocol $input, TProtocol $output) + { + /* + Use the actual underlying protocol (e.g. TBinaryProtocol) to read the + message header. This pulls the message "off the wire", which we'll + deal with at the end of this method. + */ + $input->readMessageBegin($fname, $mtype, $rseqid); + + if ($mtype !== TMessageType::CALL && $mtype != TMessageType::ONEWAY) { + throw new TException("This should not have happened!?"); + } + + // Extract the service name and the new Message name. + if (strpos($fname, TMultiplexedProtocol::SEPARATOR) === false) { + throw new TException("Service name not found in message name: {$fname}. Did you " . + "forget to use a TMultiplexProtocol in your client?"); + } + list($serviceName, $messageName) = explode(':', $fname, 2); + if (!array_key_exists($serviceName, $this->serviceProcessorMap_)) { + throw new TException("Service name not found: {$serviceName}. Did you forget " . + "to call registerProcessor()?"); + } + + // Dispatch processing to the stored processor + $processor = $this->serviceProcessorMap_[$serviceName]; + + return $processor->process( + new StoredMessageProtocol($input, $messageName, $mtype, $rseqid), + $output + ); + } +} diff --git a/vendor/packaged/thrift/src/Transport/TBufferedTransport.php b/vendor/packaged/thrift/src/Transport/TBufferedTransport.php new file mode 100644 index 000000000..253c5acfb --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TBufferedTransport.php @@ -0,0 +1,206 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TTransportException; +use Thrift\Factory\TStringFuncFactory; + +/** + * Buffered transport. Stores data to an internal buffer that it doesn't + * actually write out until flush is called. For reading, we do a greedy + * read and then serve data out of the internal buffer. + * + * @package thrift.transport + */ +class TBufferedTransport extends TTransport +{ + /** + * The underlying transport + * + * @var TTransport + */ + protected $transport_; + + /** + * The receive buffer size + * + * @var int + */ + protected $rBufSize_ = 512; + + /** + * The write buffer size + * + * @var int + */ + protected $wBufSize_ = 512; + + /** + * The write buffer. + * + * @var string + */ + protected $wBuf_ = ''; + + /** + * The read buffer. + * + * @var string + */ + protected $rBuf_ = ''; + + /** + * Constructor. Creates a buffered transport around an underlying transport + */ + public function __construct($transport, $rBufSize = 512, $wBufSize = 512) + { + $this->transport_ = $transport; + $this->rBufSize_ = $rBufSize; + $this->wBufSize_ = $wBufSize; + } + + public function isOpen() + { + return $this->transport_->isOpen(); + } + + /** + * @inheritdoc + * + * @throws TTransportException + */ + public function open() + { + $this->transport_->open(); + } + + public function close() + { + $this->transport_->close(); + } + + public function putBack($data) + { + if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { + $this->rBuf_ = $data; + } else { + $this->rBuf_ = ($data . $this->rBuf_); + } + } + + /** + * The reason that we customize readAll here is that the majority of PHP + * streams are already internally buffered by PHP. The socket stream, for + * example, buffers internally and blocks if you call read with $len greater + * than the amount of data available, unlike recv() in C. + * + * Therefore, use the readAll method of the wrapped transport inside + * the buffered readAll. + * + * @throws TTransportException + */ + public function readAll($len) + { + $have = TStringFuncFactory::create()->strlen($this->rBuf_); + if ($have == 0) { + $data = $this->transport_->readAll($len); + } elseif ($have < $len) { + $data = $this->rBuf_; + $this->rBuf_ = ''; + $data .= $this->transport_->readAll($len - $have); + } elseif ($have == $len) { + $data = $this->rBuf_; + $this->rBuf_ = ''; + } elseif ($have > $len) { + $data = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len); + $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len); + } + + return $data; + } + + /** + * @inheritdoc + * + * @param int $len + * @return string + * @throws TTransportException + */ + public function read($len) + { + if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { + $this->rBuf_ = $this->transport_->read($this->rBufSize_); + } + + if (TStringFuncFactory::create()->strlen($this->rBuf_) <= $len) { + $ret = $this->rBuf_; + $this->rBuf_ = ''; + + return $ret; + } + + $ret = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len); + $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len); + + return $ret; + } + + /** + * @inheritdoc + * + * @param string $buf + * @throws TTransportException + */ + public function write($buf) + { + $this->wBuf_ .= $buf; + if (TStringFuncFactory::create()->strlen($this->wBuf_) >= $this->wBufSize_) { + $out = $this->wBuf_; + + // Note that we clear the internal wBuf_ prior to the underlying write + // to ensure we're in a sane state (i.e. internal buffer cleaned) + // if the underlying write throws up an exception + $this->wBuf_ = ''; + $this->transport_->write($out); + } + } + + /** + * @inheritdoc + * + * @throws TTransportException + */ + public function flush() + { + if (TStringFuncFactory::create()->strlen($this->wBuf_) > 0) { + $out = $this->wBuf_; + + // Note that we clear the internal wBuf_ prior to the underlying write + // to ensure we're in a sane state (i.e. internal buffer cleaned) + // if the underlying write throws up an exception + $this->wBuf_ = ''; + $this->transport_->write($out); + } + $this->transport_->flush(); + } +} diff --git a/vendor/packaged/thrift/src/Transport/TCurlClient.php b/vendor/packaged/thrift/src/Transport/TCurlClient.php new file mode 100644 index 000000000..f781da969 --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TCurlClient.php @@ -0,0 +1,281 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TTransportException; +use Thrift\Factory\TStringFuncFactory; + +/** + * HTTP client for Thrift + * + * @package thrift.transport + */ +class TCurlClient extends TTransport +{ + private static $curlHandle; + + /** + * The host to connect to + * + * @var string + */ + protected $host_; + + /** + * The port to connect on + * + * @var int + */ + protected $port_; + + /** + * The URI to request + * + * @var string + */ + protected $uri_; + + /** + * The scheme to use for the request, i.e. http, https + * + * @var string + */ + protected $scheme_; + + /** + * Buffer for the HTTP request data + * + * @var string + */ + protected $request_; + + /** + * Buffer for the HTTP response data. + * + * @var binary string + */ + protected $response_; + + /** + * Read timeout + * + * @var float + */ + protected $timeout_; + + /** + * http headers + * + * @var array + */ + protected $headers_; + + /** + * Make a new HTTP client. + * + * @param string $host + * @param int $port + * @param string $uri + */ + public function __construct($host, $port = 80, $uri = '', $scheme = 'http') + { + if ((TStringFuncFactory::create()->strlen($uri) > 0) && ($uri[0] != '/')) { + $uri = '/' . $uri; + } + $this->scheme_ = $scheme; + $this->host_ = $host; + $this->port_ = $port; + $this->uri_ = $uri; + $this->request_ = ''; + $this->response_ = null; + $this->timeout_ = null; + $this->headers_ = array(); + } + + /** + * Set read timeout + * + * @param float $timeout + */ + public function setTimeoutSecs($timeout) + { + $this->timeout_ = $timeout; + } + + /** + * Whether this transport is open. + * + * @return boolean true if open + */ + public function isOpen() + { + return true; + } + + /** + * Open the transport for reading/writing + * + * @throws TTransportException if cannot open + */ + public function open() + { + } + + /** + * Close the transport. + */ + public function close() + { + $this->request_ = ''; + $this->response_ = null; + } + + /** + * Read some data into the array. + * + * @param int $len How much to read + * @return string The data that has been read + * @throws TTransportException if cannot read any more data + */ + public function read($len) + { + if ($len >= strlen($this->response_)) { + return $this->response_; + } else { + $ret = substr($this->response_, 0, $len); + $this->response_ = substr($this->response_, $len); + + return $ret; + } + } + + /** + * Guarantees that the full amount of data is read. Since TCurlClient gets entire payload at + * once, parent readAll cannot be used. + * + * @return string The data, of exact length + * @throws TTransportException if cannot read data + */ + public function readAll($len) + { + $data = $this->read($len); + + if (TStringFuncFactory::create()->strlen($data) !== $len) { + throw new TTransportException('TCurlClient could not read '.$len.' bytes'); + } + + return $data; + } + + /** + * Writes some data into the pending buffer + * + * @param string $buf The data to write + * @throws TTransportException if writing fails + */ + public function write($buf) + { + $this->request_ .= $buf; + } + + /** + * Opens and sends the actual request over the HTTP connection + * + * @throws TTransportException if a writing error occurs + */ + public function flush() + { + if (!self::$curlHandle) { + register_shutdown_function(array('Thrift\\Transport\\TCurlClient', 'closeCurlHandle')); + self::$curlHandle = curl_init(); + curl_setopt(self::$curlHandle, CURLOPT_RETURNTRANSFER, true); + curl_setopt(self::$curlHandle, CURLOPT_BINARYTRANSFER, true); + curl_setopt(self::$curlHandle, CURLOPT_USERAGENT, 'PHP/TCurlClient'); + curl_setopt(self::$curlHandle, CURLOPT_CUSTOMREQUEST, 'POST'); + curl_setopt(self::$curlHandle, CURLOPT_FOLLOWLOCATION, true); + curl_setopt(self::$curlHandle, CURLOPT_MAXREDIRS, 1); + } + // God, PHP really has some esoteric ways of doing simple things. + $host = $this->host_ . ($this->port_ != 80 ? ':' . $this->port_ : ''); + $fullUrl = $this->scheme_ . "://" . $host . $this->uri_; + + $headers = array(); + $defaultHeaders = array('Accept' => 'application/x-thrift', + 'Content-Type' => 'application/x-thrift', + 'Content-Length' => TStringFuncFactory::create()->strlen($this->request_)); + foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) { + $headers[] = "$key: $value"; + } + + curl_setopt(self::$curlHandle, CURLOPT_HTTPHEADER, $headers); + + if ($this->timeout_ > 0) { + if ($this->timeout_ < 1.0) { + // Timestamps smaller than 1 second are ignored when CURLOPT_TIMEOUT is used + curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT_MS, 1000 * $this->timeout_); + } else { + curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_); + } + } + curl_setopt(self::$curlHandle, CURLOPT_POSTFIELDS, $this->request_); + $this->request_ = ''; + + curl_setopt(self::$curlHandle, CURLOPT_URL, $fullUrl); + $this->response_ = curl_exec(self::$curlHandle); + $responseError = curl_error(self::$curlHandle); + + $code = curl_getinfo(self::$curlHandle, CURLINFO_HTTP_CODE); + + // Handle non 200 status code / connect failure + if ($this->response_ === false || $code !== 200) { + curl_close(self::$curlHandle); + self::$curlHandle = null; + $this->response_ = null; + $error = 'TCurlClient: Could not connect to ' . $fullUrl; + if ($responseError) { + $error .= ', ' . $responseError; + } + if ($code) { + $error .= ', HTTP status code: ' . $code; + } + throw new TTransportException($error, TTransportException::UNKNOWN); + } + } + + public static function closeCurlHandle() + { + try { + if (self::$curlHandle) { + curl_close(self::$curlHandle); + self::$curlHandle = null; + } + } catch (\Exception $x) { + error_log('There was an error closing the curl handle: ' . $x->getMessage()); + } + } + + public function addHeaders($headers) + { + $this->headers_ = array_merge($this->headers_, $headers); + } +} diff --git a/vendor/packaged/thrift/src/Transport/TFramedTransport.php b/vendor/packaged/thrift/src/Transport/TFramedTransport.php new file mode 100644 index 000000000..39d186987 --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TFramedTransport.php @@ -0,0 +1,192 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Factory\TStringFuncFactory; + +/** + * Framed transport. Writes and reads data in chunks that are stamped with + * their length. + * + * @package thrift.transport + */ +class TFramedTransport extends TTransport +{ + /** + * Underlying transport object. + * + * @var TTransport + */ + private $transport_; + + /** + * Buffer for read data. + * + * @var string + */ + private $rBuf_; + + /** + * Buffer for queued output data + * + * @var string + */ + private $wBuf_; + + /** + * Whether to frame reads + * + * @var bool + */ + private $read_; + + /** + * Whether to frame writes + * + * @var bool + */ + private $write_; + + /** + * Constructor. + * + * @param TTransport $transport Underlying transport + */ + public function __construct($transport = null, $read = true, $write = true) + { + $this->transport_ = $transport; + $this->read_ = $read; + $this->write_ = $write; + } + + public function isOpen() + { + return $this->transport_->isOpen(); + } + + public function open() + { + $this->transport_->open(); + } + + public function close() + { + $this->transport_->close(); + } + + /** + * Reads from the buffer. When more data is required reads another entire + * chunk and serves future reads out of that. + * + * @param int $len How much data + */ + public function read($len) + { + if (!$this->read_) { + return $this->transport_->read($len); + } + + if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { + $this->readFrame(); + } + + // Just return full buff + if ($len >= TStringFuncFactory::create()->strlen($this->rBuf_)) { + $out = $this->rBuf_; + $this->rBuf_ = null; + + return $out; + } + + // Return TStringFuncFactory::create()->substr + $out = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len); + $this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len); + + return $out; + } + + /** + * Put previously read data back into the buffer + * + * @param string $data data to return + */ + public function putBack($data) + { + if (TStringFuncFactory::create()->strlen($this->rBuf_) === 0) { + $this->rBuf_ = $data; + } else { + $this->rBuf_ = ($data . $this->rBuf_); + } + } + + /** + * Reads a chunk of data into the internal read buffer. + */ + private function readFrame() + { + $buf = $this->transport_->readAll(4); + $val = unpack('N', $buf); + $sz = $val[1]; + + $this->rBuf_ = $this->transport_->readAll($sz); + } + + /** + * Writes some data to the pending output buffer. + * + * @param string $buf The data + * @param int $len Limit of bytes to write + */ + public function write($buf, $len = null) + { + if (!$this->write_) { + return $this->transport_->write($buf, $len); + } + + if ($len !== null && $len < TStringFuncFactory::create()->strlen($buf)) { + $buf = TStringFuncFactory::create()->substr($buf, 0, $len); + } + $this->wBuf_ .= $buf; + } + + /** + * Writes the output buffer to the stream in the format of a 4-byte length + * followed by the actual data. + */ + public function flush() + { + if (!$this->write_ || TStringFuncFactory::create()->strlen($this->wBuf_) == 0) { + return $this->transport_->flush(); + } + + $out = pack('N', TStringFuncFactory::create()->strlen($this->wBuf_)); + $out .= $this->wBuf_; + + // Note that we clear the internal wBuf_ prior to the underlying write + // to ensure we're in a sane state (i.e. internal buffer cleaned) + // if the underlying write throws up an exception + $this->wBuf_ = ''; + $this->transport_->write($out); + $this->transport_->flush(); + } +} diff --git a/vendor/packaged/thrift/src/Transport/THttpClient.php b/vendor/packaged/thrift/src/Transport/THttpClient.php new file mode 100644 index 000000000..4d6be32fe --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/THttpClient.php @@ -0,0 +1,258 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TTransportException; +use Thrift\Factory\TStringFuncFactory; + +/** + * HTTP client for Thrift + * + * @package thrift.transport + */ +class THttpClient extends TTransport +{ + /** + * The host to connect to + * + * @var string + */ + protected $host_; + + /** + * The port to connect on + * + * @var int + */ + protected $port_; + + /** + * The URI to request + * + * @var string + */ + protected $uri_; + + /** + * The scheme to use for the request, i.e. http, https + * + * @var string + */ + protected $scheme_; + + /** + * Buffer for the HTTP request data + * + * @var string + */ + protected $buf_; + + /** + * Input socket stream. + * + * @var resource + */ + protected $handle_; + + /** + * Read timeout + * + * @var float + */ + protected $timeout_; + + /** + * http headers + * + * @var array + */ + protected $headers_; + + /** + * Context additional options + * + * @var array + */ + protected $context_; + + /** + * Make a new HTTP client. + * + * @param string $host + * @param int $port + * @param string $uri + * @param string $scheme + * @param array $context + */ + public function __construct($host, $port = 80, $uri = '', $scheme = 'http', array $context = array()) + { + if ((TStringFuncFactory::create()->strlen($uri) > 0) && ($uri[0] != '/')) { + $uri = '/' . $uri; + } + $this->scheme_ = $scheme; + $this->host_ = $host; + $this->port_ = $port; + $this->uri_ = $uri; + $this->buf_ = ''; + $this->handle_ = null; + $this->timeout_ = null; + $this->headers_ = array(); + $this->context_ = $context; + } + + /** + * Set read timeout + * + * @param float $timeout + */ + public function setTimeoutSecs($timeout) + { + $this->timeout_ = $timeout; + } + + /** + * Whether this transport is open. + * + * @return boolean true if open + */ + public function isOpen() + { + return true; + } + + /** + * Open the transport for reading/writing + * + * @throws TTransportException if cannot open + */ + public function open() + { + } + + /** + * Close the transport. + */ + public function close() + { + if ($this->handle_) { + @fclose($this->handle_); + $this->handle_ = null; + } + } + + /** + * Read some data into the array. + * + * @param int $len How much to read + * @return string The data that has been read + * @throws TTransportException if cannot read any more data + */ + public function read($len) + { + $data = @fread($this->handle_, $len); + if ($data === false || $data === '') { + $md = stream_get_meta_data($this->handle_); + if ($md['timed_out']) { + throw new TTransportException( + 'THttpClient: timed out reading ' . $len . ' bytes from ' . + $this->host_ . ':' . $this->port_ . $this->uri_, + TTransportException::TIMED_OUT + ); + } else { + throw new TTransportException( + 'THttpClient: Could not read ' . $len . ' bytes from ' . + $this->host_ . ':' . $this->port_ . $this->uri_, + TTransportException::UNKNOWN + ); + } + } + + return $data; + } + + /** + * Writes some data into the pending buffer + * + * @param string $buf The data to write + * @throws TTransportException if writing fails + */ + public function write($buf) + { + $this->buf_ .= $buf; + } + + /** + * Opens and sends the actual request over the HTTP connection + * + * @throws TTransportException if a writing error occurs + */ + public function flush() + { + // God, PHP really has some esoteric ways of doing simple things. + $host = $this->host_ . ($this->port_ != 80 ? ':' . $this->port_ : ''); + + $headers = array(); + $defaultHeaders = array('Host' => $host, + 'Accept' => 'application/x-thrift', + 'User-Agent' => 'PHP/THttpClient', + 'Content-Type' => 'application/x-thrift', + 'Content-Length' => TStringFuncFactory::create()->strlen($this->buf_)); + foreach (array_merge($defaultHeaders, $this->headers_) as $key => $value) { + $headers[] = "$key: $value"; + } + + $options = $this->context_; + + $baseHttpOptions = isset($options["http"]) ? $options["http"] : array(); + + $httpOptions = $baseHttpOptions + array('method' => 'POST', + 'header' => implode("\r\n", $headers), + 'max_redirects' => 1, + 'content' => $this->buf_); + if ($this->timeout_ > 0) { + $httpOptions['timeout'] = $this->timeout_; + } + $this->buf_ = ''; + + $options["http"] = $httpOptions; + $contextid = stream_context_create($options); + $this->handle_ = @fopen( + $this->scheme_ . '://' . $host . $this->uri_, + 'r', + false, + $contextid + ); + + // Connect failed? + if ($this->handle_ === false) { + $this->handle_ = null; + $error = 'THttpClient: Could not connect to ' . $host . $this->uri_; + throw new TTransportException($error, TTransportException::NOT_OPEN); + } + } + + public function addHeaders($headers) + { + $this->headers_ = array_merge($this->headers_, $headers); + } +} diff --git a/vendor/packaged/thrift/src/Transport/TMemoryBuffer.php b/vendor/packaged/thrift/src/Transport/TMemoryBuffer.php new file mode 100644 index 000000000..fee03a2a4 --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TMemoryBuffer.php @@ -0,0 +1,106 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TTransportException; +use Thrift\Factory\TStringFuncFactory; + +/** + * A memory buffer is a tranpsort that simply reads from and writes to an + * in-memory string buffer. Anytime you call write on it, the data is simply + * placed into a buffer, and anytime you call read, data is read from that + * buffer. + * + * @package thrift.transport + */ +class TMemoryBuffer extends TTransport +{ + /** + * Constructor. Optionally pass an initial value + * for the buffer. + */ + public function __construct($buf = '') + { + $this->buf_ = $buf; + } + + protected $buf_ = ''; + + public function isOpen() + { + return true; + } + + public function open() + { + } + + public function close() + { + } + + public function write($buf) + { + $this->buf_ .= $buf; + } + + public function read($len) + { + $bufLength = TStringFuncFactory::create()->strlen($this->buf_); + + if ($bufLength === 0) { + throw new TTransportException( + 'TMemoryBuffer: Could not read ' . + $len . ' bytes from buffer.', + TTransportException::UNKNOWN + ); + } + + if ($bufLength <= $len) { + $ret = $this->buf_; + $this->buf_ = ''; + + return $ret; + } + + $ret = TStringFuncFactory::create()->substr($this->buf_, 0, $len); + $this->buf_ = TStringFuncFactory::create()->substr($this->buf_, $len); + + return $ret; + } + + public function getBuffer() + { + return $this->buf_; + } + + public function available() + { + return TStringFuncFactory::create()->strlen($this->buf_); + } + + public function putBack($data) + { + $this->buf_ = $data . $this->buf_; + } +} diff --git a/vendor/packaged/thrift/src/Transport/TNullTransport.php b/vendor/packaged/thrift/src/Transport/TNullTransport.php new file mode 100644 index 000000000..7e086b67c --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TNullTransport.php @@ -0,0 +1,56 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TTransportException; + +/** + * Transport that only accepts writes and ignores them. + * This is useful for measuring the serialized size of structures. + * + * @package thrift.transport + */ +class TNullTransport extends TTransport +{ + public function isOpen() + { + return true; + } + + public function open() + { + } + + public function close() + { + } + + public function read($len) + { + throw new TTransportException("Can't read from TNullTransport."); + } + + public function write($buf) + { + } +} diff --git a/vendor/packaged/thrift/src/Transport/TPhpStream.php b/vendor/packaged/thrift/src/Transport/TPhpStream.php new file mode 100644 index 000000000..42823ff33 --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TPhpStream.php @@ -0,0 +1,124 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TException; +use Thrift\Factory\TStringFuncFactory; + +/** + * Php stream transport. Reads to and writes from the php standard streams + * php://input and php://output + * + * @package thrift.transport + */ +class TPhpStream extends TTransport +{ + const MODE_R = 1; + const MODE_W = 2; + + private $inStream_ = null; + + private $outStream_ = null; + + private $read_ = false; + + private $write_ = false; + + public function __construct($mode) + { + $this->read_ = $mode & self::MODE_R; + $this->write_ = $mode & self::MODE_W; + } + + public function open() + { + if ($this->read_) { + $this->inStream_ = @fopen(self::inStreamName(), 'r'); + if (!is_resource($this->inStream_)) { + throw new TException('TPhpStream: Could not open php://input'); + } + } + if ($this->write_) { + $this->outStream_ = @fopen('php://output', 'w'); + if (!is_resource($this->outStream_)) { + throw new TException('TPhpStream: Could not open php://output'); + } + } + } + + public function close() + { + if ($this->read_) { + @fclose($this->inStream_); + $this->inStream_ = null; + } + if ($this->write_) { + @fclose($this->outStream_); + $this->outStream_ = null; + } + } + + public function isOpen() + { + return + (!$this->read_ || is_resource($this->inStream_)) && + (!$this->write_ || is_resource($this->outStream_)); + } + + public function read($len) + { + $data = @fread($this->inStream_, $len); + if ($data === false || $data === '') { + throw new TException('TPhpStream: Could not read ' . $len . ' bytes'); + } + + return $data; + } + + public function write($buf) + { + while (TStringFuncFactory::create()->strlen($buf) > 0) { + $got = @fwrite($this->outStream_, $buf); + if ($got === 0 || $got === false) { + throw new TException( + 'TPhpStream: Could not write ' . TStringFuncFactory::create()->strlen($buf) . ' bytes' + ); + } + $buf = TStringFuncFactory::create()->substr($buf, $got); + } + } + + public function flush() + { + @fflush($this->outStream_); + } + + private static function inStreamName() + { + if (php_sapi_name() == 'cli') { + return 'php://stdin'; + } + + return 'php://input'; + } +} diff --git a/vendor/packaged/thrift/src/Transport/TSSLSocket.php b/vendor/packaged/thrift/src/Transport/TSSLSocket.php new file mode 100644 index 000000000..b4a0adb54 --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TSSLSocket.php @@ -0,0 +1,117 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TException; +use Thrift\Exception\TTransportException; +use Thrift\Factory\TStringFuncFactory; + +/** + * Sockets implementation of the TTransport interface. + * + * @package thrift.transport + */ +class TSSLSocket extends TSocket +{ + /** + * Remote port + * + * @var resource + */ + protected $context_ = null; + + /** + * Socket constructor + * + * @param string $host Remote hostname + * @param int $port Remote port + * @param resource $context Stream context + * @param bool $persist Whether to use a persistent socket + * @param string $debugHandler Function to call for error logging + */ + public function __construct( + $host = 'localhost', + $port = 9090, + $context = null, + $debugHandler = null + ) { + $this->host_ = $this->getSSLHost($host); + $this->port_ = $port; + $this->context_ = $context; + $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log'; + } + + /** + * Creates a host name with SSL transport protocol + * if no transport protocol already specified in + * the host name. + * + * @param string $host Host to listen on + * @return string $host Host name with transport protocol + */ + private function getSSLHost($host) + { + $transport_protocol_loc = strpos($host, "://"); + if ($transport_protocol_loc === false) { + $host = 'ssl://' . $host; + } + return $host; + } + + /** + * Connects the socket. + */ + public function open() + { + if ($this->isOpen()) { + throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN); + } + + if (empty($this->host_)) { + throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN); + } + + if ($this->port_ <= 0) { + throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN); + } + + $this->handle_ = @stream_socket_client( + $this->host_ . ':' . $this->port_, + $errno, + $errstr, + $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000), + STREAM_CLIENT_CONNECT, + $this->context_ + ); + + // Connect failed? + if ($this->handle_ === false) { + $error = 'TSocket: Could not connect to ' . + $this->host_ . ':' . $this->port_ . ' (' . $errstr . ' [' . $errno . '])'; + if ($this->debug_) { + call_user_func($this->debugHandler_, $error); + } + throw new TException($error); + } + } +} diff --git a/vendor/packaged/thrift/src/Transport/TSocket.php b/vendor/packaged/thrift/src/Transport/TSocket.php new file mode 100644 index 000000000..5147efa63 --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TSocket.php @@ -0,0 +1,366 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TException; +use Thrift\Exception\TTransportException; +use Thrift\Factory\TStringFuncFactory; + +/** + * Sockets implementation of the TTransport interface. + * + * @package thrift.transport + */ +class TSocket extends TTransport +{ + /** + * Handle to PHP socket + * + * @var resource + */ + protected $handle_ = null; + + /** + * Remote hostname + * + * @var string + */ + protected $host_ = 'localhost'; + + /** + * Remote port + * + * @var int + */ + protected $port_ = '9090'; + + /** + * Send timeout in seconds. + * + * Combined with sendTimeoutUsec this is used for send timeouts. + * + * @var int + */ + protected $sendTimeoutSec_ = 0; + + /** + * Send timeout in microseconds. + * + * Combined with sendTimeoutSec this is used for send timeouts. + * + * @var int + */ + protected $sendTimeoutUsec_ = 100000; + + /** + * Recv timeout in seconds + * + * Combined with recvTimeoutUsec this is used for recv timeouts. + * + * @var int + */ + protected $recvTimeoutSec_ = 0; + + /** + * Recv timeout in microseconds + * + * Combined with recvTimeoutSec this is used for recv timeouts. + * + * @var int + */ + protected $recvTimeoutUsec_ = 750000; + + /** + * Persistent socket or plain? + * + * @var bool + */ + protected $persist_ = false; + + /** + * Debugging on? + * + * @var bool + */ + protected $debug_ = false; + + /** + * Debug handler + * + * @var mixed + */ + protected $debugHandler_ = null; + + /** + * Socket constructor + * + * @param string $host Remote hostname + * @param int $port Remote port + * @param bool $persist Whether to use a persistent socket + * @param string $debugHandler Function to call for error logging + */ + public function __construct( + $host = 'localhost', + $port = 9090, + $persist = false, + $debugHandler = null + ) { + $this->host_ = $host; + $this->port_ = $port; + $this->persist_ = $persist; + $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log'; + } + + /** + * @param resource $handle + * @return void + */ + public function setHandle($handle) + { + $this->handle_ = $handle; + stream_set_blocking($this->handle_, false); + } + + /** + * Sets the send timeout. + * + * @param int $timeout Timeout in milliseconds. + */ + public function setSendTimeout($timeout) + { + $this->sendTimeoutSec_ = floor($timeout / 1000); + $this->sendTimeoutUsec_ = + ($timeout - ($this->sendTimeoutSec_ * 1000)) * 1000; + } + + /** + * Sets the receive timeout. + * + * @param int $timeout Timeout in milliseconds. + */ + public function setRecvTimeout($timeout) + { + $this->recvTimeoutSec_ = floor($timeout / 1000); + $this->recvTimeoutUsec_ = + ($timeout - ($this->recvTimeoutSec_ * 1000)) * 1000; + } + + /** + * Sets debugging output on or off + * + * @param bool $debug + */ + public function setDebug($debug) + { + $this->debug_ = $debug; + } + + /** + * Get the host that this socket is connected to + * + * @return string host + */ + public function getHost() + { + return $this->host_; + } + + /** + * Get the remote port that this socket is connected to + * + * @return int port + */ + public function getPort() + { + return $this->port_; + } + + /** + * Tests whether this is open + * + * @return bool true if the socket is open + */ + public function isOpen() + { + return is_resource($this->handle_); + } + + /** + * Connects the socket. + */ + public function open() + { + if ($this->isOpen()) { + throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN); + } + + if (empty($this->host_)) { + throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN); + } + + if ($this->port_ <= 0) { + throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN); + } + + if ($this->persist_) { + $this->handle_ = @pfsockopen( + $this->host_, + $this->port_, + $errno, + $errstr, + $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000) + ); + } else { + $this->handle_ = @fsockopen( + $this->host_, + $this->port_, + $errno, + $errstr, + $this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000) + ); + } + + // Connect failed? + if ($this->handle_ === false) { + $error = 'TSocket: Could not connect to ' . + $this->host_ . ':' . $this->port_ . ' (' . $errstr . ' [' . $errno . '])'; + if ($this->debug_) { + call_user_func($this->debugHandler_, $error); + } + throw new TException($error); + } + + if (function_exists('socket_import_stream') && function_exists('socket_set_option')) { + $socket = socket_import_stream($this->handle_); + socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1); + } + } + + /** + * Closes the socket. + */ + public function close() + { + @fclose($this->handle_); + $this->handle_ = null; + } + + /** + * Read from the socket at most $len bytes. + * + * This method will not wait for all the requested data, it will return as + * soon as any data is received. + * + * @param int $len Maximum number of bytes to read. + * @return string Binary data + */ + public function read($len) + { + $null = null; + $read = array($this->handle_); + $readable = @stream_select( + $read, + $null, + $null, + $this->recvTimeoutSec_, + $this->recvTimeoutUsec_ + ); + + if ($readable > 0) { + $data = fread($this->handle_, $len); + if ($data === false) { + throw new TTransportException('TSocket: Could not read ' . $len . ' bytes from ' . + $this->host_ . ':' . $this->port_); + } elseif ($data == '' && feof($this->handle_)) { + throw new TTransportException('TSocket read 0 bytes'); + } + + return $data; + } elseif ($readable === 0) { + throw new TTransportException('TSocket: timed out reading ' . $len . ' bytes from ' . + $this->host_ . ':' . $this->port_); + } else { + throw new TTransportException('TSocket: Could not read ' . $len . ' bytes from ' . + $this->host_ . ':' . $this->port_); + } + } + + /** + * Write to the socket. + * + * @param string $buf The data to write + */ + public function write($buf) + { + $null = null; + $write = array($this->handle_); + + // keep writing until all the data has been written + while (TStringFuncFactory::create()->strlen($buf) > 0) { + // wait for stream to become available for writing + $writable = @stream_select( + $null, + $write, + $null, + $this->sendTimeoutSec_, + $this->sendTimeoutUsec_ + ); + if ($writable > 0) { + // write buffer to stream + $written = fwrite($this->handle_, $buf); + if ($written === -1 || $written === false) { + throw new TTransportException( + 'TSocket: Could not write ' . TStringFuncFactory::create()->strlen($buf) . ' bytes ' . + $this->host_ . ':' . $this->port_ + ); + } + // determine how much of the buffer is left to write + $buf = TStringFuncFactory::create()->substr($buf, $written); + } elseif ($writable === 0) { + throw new TTransportException( + 'TSocket: timed out writing ' . TStringFuncFactory::create()->strlen($buf) . ' bytes from ' . + $this->host_ . ':' . $this->port_ + ); + } else { + throw new TTransportException( + 'TSocket: Could not write ' . TStringFuncFactory::create()->strlen($buf) . ' bytes ' . + $this->host_ . ':' . $this->port_ + ); + } + } + } + + /** + * Flush output to the socket. + * + * Since read(), readAll() and write() operate on the sockets directly, + * this is a no-op + * + * If you wish to have flushable buffering behaviour, wrap this TSocket + * in a TBufferedTransport. + */ + public function flush() + { + // no-op + } +} diff --git a/vendor/packaged/thrift/src/Transport/TSocketPool.php b/vendor/packaged/thrift/src/Transport/TSocketPool.php new file mode 100644 index 000000000..cb9e8ddfa --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TSocketPool.php @@ -0,0 +1,310 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TException; + +/** + * This library makes use of APC cache to make hosts as down in a web + * environment. If you are running from the CLI or on a system without APC + * installed, then these null functions will step in and act like cache + * misses. + */ +if (!function_exists('apc_fetch')) { + function apc_fetch($key) + { + return false; + } + + function apc_store($key, $var, $ttl = 0) + { + return false; + } +} + +/** + * Sockets implementation of the TTransport interface that allows connection + * to a pool of servers. + * + * @package thrift.transport + */ +class TSocketPool extends TSocket +{ + /** + * Remote servers. Array of associative arrays with 'host' and 'port' keys + */ + private $servers_ = array(); + + /** + * How many times to retry each host in connect + * + * @var int + */ + private $numRetries_ = 1; + + /** + * Retry interval in seconds, how long to not try a host if it has been + * marked as down. + * + * @var int + */ + private $retryInterval_ = 60; + + /** + * Max consecutive failures before marking a host down. + * + * @var int + */ + private $maxConsecutiveFailures_ = 1; + + /** + * Try hosts in order? or Randomized? + * + * @var bool + */ + private $randomize_ = true; + + /** + * Always try last host, even if marked down? + * + * @var bool + */ + private $alwaysTryLast_ = true; + + /** + * Socket pool constructor + * + * @param array $hosts List of remote hostnames + * @param mixed $ports Array of remote ports, or a single common port + * @param bool $persist Whether to use a persistent socket + * @param mixed $debugHandler Function for error logging + */ + public function __construct( + $hosts = array('localhost'), + $ports = array(9090), + $persist = false, + $debugHandler = null + ) { + parent::__construct(null, 0, $persist, $debugHandler); + + if (!is_array($ports)) { + $port = $ports; + $ports = array(); + foreach ($hosts as $key => $val) { + $ports[$key] = $port; + } + } + + foreach ($hosts as $key => $host) { + $this->servers_ [] = array('host' => $host, + 'port' => $ports[$key]); + } + } + + /** + * Add a server to the pool + * + * This function does not prevent you from adding a duplicate server entry. + * + * @param string $host hostname or IP + * @param int $port port + */ + public function addServer($host, $port) + { + $this->servers_[] = array('host' => $host, 'port' => $port); + } + + /** + * Sets how many time to keep retrying a host in the connect function. + * + * @param int $numRetries + */ + public function setNumRetries($numRetries) + { + $this->numRetries_ = $numRetries; + } + + /** + * Sets how long to wait until retrying a host if it was marked down + * + * @param int $numRetries + */ + public function setRetryInterval($retryInterval) + { + $this->retryInterval_ = $retryInterval; + } + + /** + * Sets how many time to keep retrying a host before marking it as down. + * + * @param int $numRetries + */ + public function setMaxConsecutiveFailures($maxConsecutiveFailures) + { + $this->maxConsecutiveFailures_ = $maxConsecutiveFailures; + } + + /** + * Turns randomization in connect order on or off. + * + * @param bool $randomize + */ + public function setRandomize($randomize) + { + $this->randomize_ = $randomize; + } + + /** + * Whether to always try the last server. + * + * @param bool $alwaysTryLast + */ + public function setAlwaysTryLast($alwaysTryLast) + { + $this->alwaysTryLast_ = $alwaysTryLast; + } + + /** + * Connects the socket by iterating through all the servers in the pool + * and trying to find one that works. + */ + public function open() + { + // Check if we want order randomization + if ($this->randomize_) { + shuffle($this->servers_); + } + + // Count servers to identify the "last" one + $numServers = count($this->servers_); + + for ($i = 0; $i < $numServers; ++$i) { + // This extracts the $host and $port variables + extract($this->servers_[$i]); + + // Check APC cache for a record of this server being down + $failtimeKey = 'thrift_failtime:' . $host . ':' . $port . '~'; + + // Cache miss? Assume it's OK + $lastFailtime = apc_fetch($failtimeKey); + if ($lastFailtime === false) { + $lastFailtime = 0; + } + + $retryIntervalPassed = false; + + // Cache hit...make sure enough the retry interval has elapsed + if ($lastFailtime > 0) { + $elapsed = time() - $lastFailtime; + if ($elapsed > $this->retryInterval_) { + $retryIntervalPassed = true; + if ($this->debug_) { + call_user_func( + $this->debugHandler_, + 'TSocketPool: retryInterval ' . + '(' . $this->retryInterval_ . ') ' . + 'has passed for host ' . $host . ':' . $port + ); + } + } + } + + // Only connect if not in the middle of a fail interval, OR if this + // is the LAST server we are trying, just hammer away on it + $isLastServer = false; + if ($this->alwaysTryLast_) { + $isLastServer = ($i == ($numServers - 1)); + } + + if (($lastFailtime === 0) || + ($isLastServer) || + ($lastFailtime > 0 && $retryIntervalPassed)) { + // Set underlying TSocket params to this one + $this->host_ = $host; + $this->port_ = $port; + + // Try up to numRetries_ connections per server + for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) { + try { + // Use the underlying TSocket open function + parent::open(); + + // Only clear the failure counts if required to do so + if ($lastFailtime > 0) { + apc_store($failtimeKey, 0); + } + + // Successful connection, return now + return; + } catch (TException $tx) { + // Connection failed + } + } + + // Mark failure of this host in the cache + $consecfailsKey = 'thrift_consecfails:' . $host . ':' . $port . '~'; + + // Ignore cache misses + $consecfails = apc_fetch($consecfailsKey); + if ($consecfails === false) { + $consecfails = 0; + } + + // Increment by one + $consecfails++; + + // Log and cache this failure + if ($consecfails >= $this->maxConsecutiveFailures_) { + if ($this->debug_) { + call_user_func( + $this->debugHandler_, + 'TSocketPool: marking ' . $host . ':' . $port . + ' as down for ' . $this->retryInterval_ . ' secs ' . + 'after ' . $consecfails . ' failed attempts.' + ); + } + // Store the failure time + apc_store($failtimeKey, time()); + + // Clear the count of consecutive failures + apc_store($consecfailsKey, 0); + } else { + apc_store($consecfailsKey, $consecfails); + } + } + } + + // Oh no; we failed them all. The system is totally ill! + $error = 'TSocketPool: All hosts in pool are down. '; + $hosts = array(); + foreach ($this->servers_ as $server) { + $hosts [] = $server['host'] . ':' . $server['port']; + } + $hostlist = implode(',', $hosts); + $error .= '(' . $hostlist . ')'; + if ($this->debug_) { + call_user_func($this->debugHandler_, $error); + } + throw new TException($error); + } +} diff --git a/vendor/packaged/thrift/src/Transport/TTransport.php b/vendor/packaged/thrift/src/Transport/TTransport.php new file mode 100644 index 000000000..35921c666 --- /dev/null +++ b/vendor/packaged/thrift/src/Transport/TTransport.php @@ -0,0 +1,98 @@ +<?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.transport + */ + +namespace Thrift\Transport; + +use Thrift\Exception\TTransportException; +use Thrift\Factory\TStringFuncFactory; + +/** + * Base interface for a transport agent. + * + * @package thrift.transport + */ +abstract class TTransport +{ + /** + * Whether this transport is open. + * + * @return boolean true if open + */ + abstract public function isOpen(); + + /** + * Open the transport for reading/writing + * + * @throws TTransportException if cannot open + */ + abstract public function open(); + + /** + * Close the transport. + */ + abstract public function close(); + + /** + * Read some data into the array. + * + * @param int $len How much to read + * @return string The data that has been read + * @throws TTransportException if cannot read any more data + */ + abstract public function read($len); + + /** + * Guarantees that the full amount of data is read. + * + * @return string The data, of exact length + * @throws TTransportException if cannot read data + */ + public function readAll($len) + { + // return $this->read($len); + + $data = ''; + $got = 0; + while (($got = TStringFuncFactory::create()->strlen($data)) < $len) { + $data .= $this->read($len - $got); + } + + return $data; + } + + /** + * Writes the given data out. + * + * @param string $buf The data to write + * @throws TTransportException if writing fails + */ + abstract public function write($buf); + + /** + * Flushes any pending data out of a buffer + * + * @throws TTransportException if a writing error occurs + */ + public function flush() + { + } +} diff --git a/vendor/packaged/thrift/src/Type/TConstant.php b/vendor/packaged/thrift/src/Type/TConstant.php new file mode 100644 index 000000000..215da4a3d --- /dev/null +++ b/vendor/packaged/thrift/src/Type/TConstant.php @@ -0,0 +1,52 @@ +<?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 + */ + +namespace Thrift\Type; + +/** + * Base class for constant Management + */ +abstract class TConstant +{ + /** + * Don't instanciate this class + */ + protected function __construct() + { + } + + /** + * Get a constant value + * @param string $constant + * @return mixed + */ + public static function get($constant) + { + if (is_null(static::$$constant)) { + static::$$constant = call_user_func( + sprintf('static::init_%s', $constant) + ); + } + + return static::$$constant; + } +} diff --git a/vendor/packaged/thrift/src/Type/TMessageType.php b/vendor/packaged/thrift/src/Type/TMessageType.php new file mode 100644 index 000000000..dc9ae6284 --- /dev/null +++ b/vendor/packaged/thrift/src/Type/TMessageType.php @@ -0,0 +1,34 @@ +<?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 + */ + +namespace Thrift\Type; + +/** + * Message types for RPC + */ +class TMessageType +{ + const CALL = 1; + const REPLY = 2; + const EXCEPTION = 3; + const ONEWAY = 4; +} diff --git a/vendor/packaged/thrift/src/Type/TType.php b/vendor/packaged/thrift/src/Type/TType.php new file mode 100644 index 000000000..3fdb15f53 --- /dev/null +++ b/vendor/packaged/thrift/src/Type/TType.php @@ -0,0 +1,47 @@ +<?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 + */ + +namespace Thrift\Type; + +/** + * 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; +} diff --git a/vendor/packaged/thrift/update.sh b/vendor/packaged/thrift/update.sh new file mode 100644 index 000000000..20cf145a7 --- /dev/null +++ b/vendor/packaged/thrift/update.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +TAG=$1 + +if [[ "$TAG" == "" ]]; then + echo "no branch or tag specified" + exit 1 +fi + +cd "$(dirname $0)" +git clone --depth=1 --branch=$TAG [email protected]:apache/thrift tmp + +# Move old file to an upper level to fit the new requirements of psr-4 +if [ -d "src/Thrift" ] +then + mv src/Thrift/* src/ && rm -Rf src/Thrift +fi + +rm -Rf src/Thrift +cp -R tmp/lib/php/lib/* src/ +rm -Rf tmp +cd - |