├── README.md
├── Thrift
├── Base
│ └── TBase.php
├── ClassLoader
│ └── ThriftClassLoader.php
├── Exception
│ ├── TApplicationException.php
│ ├── TException.php
│ ├── TProtocolException.php
│ └── TTransportException.php
├── Factory
│ ├── TBinaryProtocolFactory.php
│ ├── TCompactProtocolFactory.php
│ ├── TJSONProtocolFactory.php
│ ├── TProtocolFactory.php
│ ├── TStringFuncFactory.php
│ └── TTransportFactory.php
├── Protocol
│ ├── JSON
│ │ ├── BaseContext.php
│ │ ├── ListContext.php
│ │ ├── LookaheadReader.php
│ │ └── PairContext.php
│ ├── SimpleJSON
│ │ ├── CollectionMapKeyException.php
│ │ ├── Context.php
│ │ ├── ListContext.php
│ │ ├── MapContext.php
│ │ └── StructContext.php
│ ├── TBinaryProtocol.php
│ ├── TBinaryProtocolAccelerated.php
│ ├── TCompactProtocol.php
│ ├── TJSONProtocol.php
│ ├── TMultiplexedProtocol.php
│ ├── TProtocol.php
│ ├── TProtocolDecorator.php
│ └── TSimpleJSONProtocol.php
├── Serializer
│ └── TBinarySerializer.php
├── Server
│ ├── TForkingServer.php
│ ├── TServer.php
│ ├── TServerSocket.php
│ ├── TServerTransport.php
│ └── TSimpleServer.php
├── StringFunc
│ ├── Core.php
│ ├── Mbstring.php
│ └── TStringFunc.php
├── TMultiplexedProcessor.php
├── Transport
│ ├── TBufferedTransport.php
│ ├── TCurlClient.php
│ ├── TFramedTransport.php
│ ├── THttpClient.php
│ ├── TMemoryBuffer.php
│ ├── TNullTransport.php
│ ├── TPhpStream.php
│ ├── TSocket.php
│ ├── TSocketPool.php
│ └── TTransport.php
└── Type
│ ├── TConstant.php
│ ├── TMessageType.php
│ └── TType.php
├── client.php
├── gen-php
├── shared
│ ├── SharedService.php
│ └── Types.php
└── tutorial
│ ├── Calculator.php
│ └── Types.php
├── server.php
├── shared.thrift
└── tutorial.thrift
/README.md:
--------------------------------------------------------------------------------
1 | # php thrift server
2 |
3 |
4 | 一个简单的php thrift client和server示例。 主要参考自thrift官网样例参考,集成了各个模块,使得执行更加简单,利用`php -S`使得server的显示和thrift调用更加清楚。
5 |
6 |
7 | 在根目录下执行命令即可执行。
8 |
9 | server执行方法:`php -S localhost:9999`
10 |
11 | client执行方法:`php client.php`
12 |
13 | A simple demo of php thrift client with server. Reference from thrift, we simplify the module and use `php -S` , you can simply use it, making understanding thrift more clear.
14 |
15 | Do commands under the root document of repo.
16 |
17 | For Server : `php -S localhost:9999`
18 |
19 |
20 | For Client: `php client.php`
21 |
22 |
--------------------------------------------------------------------------------
/Thrift/Base/TBase.php:
--------------------------------------------------------------------------------
1 | 'Bool',
37 | TType::BYTE => 'Byte',
38 | TType::I16 => 'I16',
39 | TType::I32 => 'I32',
40 | TType::I64 => 'I64',
41 | TType::DOUBLE => 'Double',
42 | TType::STRING => 'String');
43 |
44 | abstract public function read($input);
45 |
46 | abstract public function write($output);
47 |
48 | public function __construct($spec=null, $vals=null)
49 | {
50 | if (is_array($spec) && is_array($vals)) {
51 | foreach ($spec as $fid => $fspec) {
52 | $var = $fspec['var'];
53 | if (isset($vals[$var])) {
54 | $this->$var = $vals[$var];
55 | }
56 | }
57 | }
58 | }
59 |
60 | public function __wakeup()
61 | {
62 | $this->__construct(get_object_vars($this));
63 | }
64 |
65 | private function _readMap(&$var, $spec, $input)
66 | {
67 | $xfer = 0;
68 | $ktype = $spec['ktype'];
69 | $vtype = $spec['vtype'];
70 | $kread = $vread = null;
71 | if (isset(TBase::$tmethod[$ktype])) {
72 | $kread = 'read'.TBase::$tmethod[$ktype];
73 | } else {
74 | $kspec = $spec['key'];
75 | }
76 | if (isset(TBase::$tmethod[$vtype])) {
77 | $vread = 'read'.TBase::$tmethod[$vtype];
78 | } else {
79 | $vspec = $spec['val'];
80 | }
81 | $var = array();
82 | $_ktype = $_vtype = $size = 0;
83 | $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
84 | for ($i = 0; $i < $size; ++$i) {
85 | $key = $val = null;
86 | if ($kread !== null) {
87 | $xfer += $input->$kread($key);
88 | } else {
89 | switch ($ktype) {
90 | case TType::STRUCT:
91 | $class = $kspec['class'];
92 | $key = new $class();
93 | $xfer += $key->read($input);
94 | break;
95 | case TType::MAP:
96 | $xfer += $this->_readMap($key, $kspec, $input);
97 | break;
98 | case TType::LST:
99 | $xfer += $this->_readList($key, $kspec, $input, false);
100 | break;
101 | case TType::SET:
102 | $xfer += $this->_readList($key, $kspec, $input, true);
103 | break;
104 | }
105 | }
106 | if ($vread !== null) {
107 | $xfer += $input->$vread($val);
108 | } else {
109 | switch ($vtype) {
110 | case TType::STRUCT:
111 | $class = $vspec['class'];
112 | $val = new $class();
113 | $xfer += $val->read($input);
114 | break;
115 | case TType::MAP:
116 | $xfer += $this->_readMap($val, $vspec, $input);
117 | break;
118 | case TType::LST:
119 | $xfer += $this->_readList($val, $vspec, $input, false);
120 | break;
121 | case TType::SET:
122 | $xfer += $this->_readList($val, $vspec, $input, true);
123 | break;
124 | }
125 | }
126 | $var[$key] = $val;
127 | }
128 | $xfer += $input->readMapEnd();
129 |
130 | return $xfer;
131 | }
132 |
133 | private function _readList(&$var, $spec, $input, $set=false)
134 | {
135 | $xfer = 0;
136 | $etype = $spec['etype'];
137 | $eread = $vread = null;
138 | if (isset(TBase::$tmethod[$etype])) {
139 | $eread = 'read'.TBase::$tmethod[$etype];
140 | } else {
141 | $espec = $spec['elem'];
142 | }
143 | $var = array();
144 | $_etype = $size = 0;
145 | if ($set) {
146 | $xfer += $input->readSetBegin($_etype, $size);
147 | } else {
148 | $xfer += $input->readListBegin($_etype, $size);
149 | }
150 | for ($i = 0; $i < $size; ++$i) {
151 | $elem = null;
152 | if ($eread !== null) {
153 | $xfer += $input->$eread($elem);
154 | } else {
155 | $espec = $spec['elem'];
156 | switch ($etype) {
157 | case TType::STRUCT:
158 | $class = $espec['class'];
159 | $elem = new $class();
160 | $xfer += $elem->read($input);
161 | break;
162 | case TType::MAP:
163 | $xfer += $this->_readMap($elem, $espec, $input);
164 | break;
165 | case TType::LST:
166 | $xfer += $this->_readList($elem, $espec, $input, false);
167 | break;
168 | case TType::SET:
169 | $xfer += $this->_readList($elem, $espec, $input, true);
170 | break;
171 | }
172 | }
173 | if ($set) {
174 | $var[$elem] = true;
175 | } else {
176 | $var []= $elem;
177 | }
178 | }
179 | if ($set) {
180 | $xfer += $input->readSetEnd();
181 | } else {
182 | $xfer += $input->readListEnd();
183 | }
184 |
185 | return $xfer;
186 | }
187 |
188 | protected function _read($class, $spec, $input)
189 | {
190 | $xfer = 0;
191 | $fname = null;
192 | $ftype = 0;
193 | $fid = 0;
194 | $xfer += $input->readStructBegin($fname);
195 | while (true) {
196 | $xfer += $input->readFieldBegin($fname, $ftype, $fid);
197 | if ($ftype == TType::STOP) {
198 | break;
199 | }
200 | if (isset($spec[$fid])) {
201 | $fspec = $spec[$fid];
202 | $var = $fspec['var'];
203 | if ($ftype == $fspec['type']) {
204 | $xfer = 0;
205 | if (isset(TBase::$tmethod[$ftype])) {
206 | $func = 'read'.TBase::$tmethod[$ftype];
207 | $xfer += $input->$func($this->$var);
208 | } else {
209 | switch ($ftype) {
210 | case TType::STRUCT:
211 | $class = $fspec['class'];
212 | $this->$var = new $class();
213 | $xfer += $this->$var->read($input);
214 | break;
215 | case TType::MAP:
216 | $xfer += $this->_readMap($this->$var, $fspec, $input);
217 | break;
218 | case TType::LST:
219 | $xfer += $this->_readList($this->$var, $fspec, $input, false);
220 | break;
221 | case TType::SET:
222 | $xfer += $this->_readList($this->$var, $fspec, $input, true);
223 | break;
224 | }
225 | }
226 | } else {
227 | $xfer += $input->skip($ftype);
228 | }
229 | } else {
230 | $xfer += $input->skip($ftype);
231 | }
232 | $xfer += $input->readFieldEnd();
233 | }
234 | $xfer += $input->readStructEnd();
235 |
236 | return $xfer;
237 | }
238 |
239 | private function _writeMap($var, $spec, $output)
240 | {
241 | $xfer = 0;
242 | $ktype = $spec['ktype'];
243 | $vtype = $spec['vtype'];
244 | $kwrite = $vwrite = null;
245 | if (isset(TBase::$tmethod[$ktype])) {
246 | $kwrite = 'write'.TBase::$tmethod[$ktype];
247 | } else {
248 | $kspec = $spec['key'];
249 | }
250 | if (isset(TBase::$tmethod[$vtype])) {
251 | $vwrite = 'write'.TBase::$tmethod[$vtype];
252 | } else {
253 | $vspec = $spec['val'];
254 | }
255 | $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
256 | foreach ($var as $key => $val) {
257 | if (isset($kwrite)) {
258 | $xfer += $output->$kwrite($key);
259 | } else {
260 | switch ($ktype) {
261 | case TType::STRUCT:
262 | $xfer += $key->write($output);
263 | break;
264 | case TType::MAP:
265 | $xfer += $this->_writeMap($key, $kspec, $output);
266 | break;
267 | case TType::LST:
268 | $xfer += $this->_writeList($key, $kspec, $output, false);
269 | break;
270 | case TType::SET:
271 | $xfer += $this->_writeList($key, $kspec, $output, true);
272 | break;
273 | }
274 | }
275 | if (isset($vwrite)) {
276 | $xfer += $output->$vwrite($val);
277 | } else {
278 | switch ($vtype) {
279 | case TType::STRUCT:
280 | $xfer += $val->write($output);
281 | break;
282 | case TType::MAP:
283 | $xfer += $this->_writeMap($val, $vspec, $output);
284 | break;
285 | case TType::LST:
286 | $xfer += $this->_writeList($val, $vspec, $output, false);
287 | break;
288 | case TType::SET:
289 | $xfer += $this->_writeList($val, $vspec, $output, true);
290 | break;
291 | }
292 | }
293 | }
294 | $xfer += $output->writeMapEnd();
295 |
296 | return $xfer;
297 | }
298 |
299 | private function _writeList($var, $spec, $output, $set=false)
300 | {
301 | $xfer = 0;
302 | $etype = $spec['etype'];
303 | $ewrite = null;
304 | if (isset(TBase::$tmethod[$etype])) {
305 | $ewrite = 'write'.TBase::$tmethod[$etype];
306 | } else {
307 | $espec = $spec['elem'];
308 | }
309 | if ($set) {
310 | $xfer += $output->writeSetBegin($etype, count($var));
311 | } else {
312 | $xfer += $output->writeListBegin($etype, count($var));
313 | }
314 | foreach ($var as $key => $val) {
315 | $elem = $set ? $key : $val;
316 | if (isset($ewrite)) {
317 | $xfer += $output->$ewrite($elem);
318 | } else {
319 | switch ($etype) {
320 | case TType::STRUCT:
321 | $xfer += $elem->write($output);
322 | break;
323 | case TType::MAP:
324 | $xfer += $this->_writeMap($elem, $espec, $output);
325 | break;
326 | case TType::LST:
327 | $xfer += $this->_writeList($elem, $espec, $output, false);
328 | break;
329 | case TType::SET:
330 | $xfer += $this->_writeList($elem, $espec, $output, true);
331 | break;
332 | }
333 | }
334 | }
335 | if ($set) {
336 | $xfer += $output->writeSetEnd();
337 | } else {
338 | $xfer += $output->writeListEnd();
339 | }
340 |
341 | return $xfer;
342 | }
343 |
344 | protected function _write($class, $spec, $output)
345 | {
346 | $xfer = 0;
347 | $xfer += $output->writeStructBegin($class);
348 | foreach ($spec as $fid => $fspec) {
349 | $var = $fspec['var'];
350 | if ($this->$var !== null) {
351 | $ftype = $fspec['type'];
352 | $xfer += $output->writeFieldBegin($var, $ftype, $fid);
353 | if (isset(TBase::$tmethod[$ftype])) {
354 | $func = 'write'.TBase::$tmethod[$ftype];
355 | $xfer += $output->$func($this->$var);
356 | } else {
357 | switch ($ftype) {
358 | case TType::STRUCT:
359 | $xfer += $this->$var->write($output);
360 | break;
361 | case TType::MAP:
362 | $xfer += $this->_writeMap($this->$var, $fspec, $output);
363 | break;
364 | case TType::LST:
365 | $xfer += $this->_writeList($this->$var, $fspec, $output, false);
366 | break;
367 | case TType::SET:
368 | $xfer += $this->_writeList($this->$var, $fspec, $output, true);
369 | break;
370 | }
371 | }
372 | $xfer += $output->writeFieldEnd();
373 | }
374 | }
375 | $xfer += $output->writeFieldStop();
376 | $xfer += $output->writeStructEnd();
377 |
378 | return $xfer;
379 | }
380 | }
381 |
--------------------------------------------------------------------------------
/Thrift/ClassLoader/ThriftClassLoader.php:
--------------------------------------------------------------------------------
1 | apc = $apc;
62 | $this->apc_prefix = $apc_prefix;
63 | }
64 |
65 | /**
66 | * Registers a namespace.
67 | *
68 | * @param string $namespace The namespace
69 | * @param array|string $paths The location(s) of the namespace
70 | */
71 | public function registerNamespace($namespace, $paths)
72 | {
73 | $this->namespaces[$namespace] = (array) $paths;
74 | }
75 |
76 | /**
77 | * Registers a Thrift definition namespace.
78 | *
79 | * @param string $namespace The definition namespace
80 | * @param array|string $paths The location(s) of the definition namespace
81 | */
82 | public function registerDefinition($namespace, $paths)
83 | {
84 | $this->definitions[$namespace] = (array) $paths;
85 | }
86 |
87 | /**
88 | * Registers this instance as an autoloader.
89 | *
90 | * @param Boolean $prepend Whether to prepend the autoloader or not
91 | */
92 | public function register($prepend = false)
93 | {
94 | spl_autoload_register(array($this, 'loadClass'), true, $prepend);
95 | }
96 |
97 | /**
98 | * Loads the given class, definition or interface.
99 | *
100 | * @param string $class The name of the class
101 | */
102 | public function loadClass($class)
103 | {
104 | if (
105 | (true === $this->apc && ($file = $this->findFileInApc($class))) or
106 | ($file = $this->findFile($class))
107 | )
108 | {
109 | require_once $file;
110 | }
111 | }
112 |
113 | /**
114 | * Loads the given class or interface in APC.
115 | * @param string $class The name of the class
116 | * @return string
117 | */
118 | protected function findFileInApc($class)
119 | {
120 | if (false === $file = apc_fetch($this->apc_prefix.$class)) {
121 | apc_store($this->apc_prefix.$class, $file = $this->findFile($class));
122 | }
123 |
124 | return $file;
125 | }
126 |
127 | /**
128 | * Find class in namespaces or definitions directories
129 | * @param string $class
130 | * @return string
131 | */
132 | public function findFile($class)
133 | {
134 | // Remove first backslash
135 | if ('\\' == $class[0]) {
136 | $class = substr($class, 1);
137 | }
138 |
139 | if (false !== $pos = strrpos($class, '\\')) {
140 | // Namespaced class name
141 | $namespace = substr($class, 0, $pos);
142 |
143 | // Iterate in normal namespaces
144 | foreach ($this->namespaces as $ns => $dirs) {
145 | //Don't interfere with other autoloaders
146 | if (0 !== strpos($namespace, $ns)) {
147 | continue;
148 | }
149 |
150 | foreach ($dirs as $dir) {
151 | $className = substr($class, $pos + 1);
152 |
153 | $file = $dir.DIRECTORY_SEPARATOR.
154 | str_replace('\\', DIRECTORY_SEPARATOR, $namespace).
155 | DIRECTORY_SEPARATOR.
156 | $className.'.php';
157 |
158 | if (file_exists($file)) {
159 | return $file;
160 | }
161 | }
162 | }
163 |
164 | // Iterate in Thrift namespaces
165 |
166 | // Remove first part of namespace
167 | $m = explode('\\', $class);
168 |
169 | // Ignore wrong call
170 | if (count($m) <= 1) {
171 | return;
172 | }
173 |
174 | $class = array_pop($m);
175 | $namespace = implode('\\', $m);
176 |
177 | foreach ($this->definitions as $ns => $dirs) {
178 | //Don't interfere with other autoloaders
179 | if (0 !== strpos($namespace, $ns)) {
180 | continue;
181 | }
182 |
183 | foreach ($dirs as $dir) {
184 | /**
185 | * Available in service: Interface, Client, Processor, Rest
186 | * And every service methods (_.+)
187 | */
188 | if(
189 | 0 === preg_match('#(.+)(if|client|processor|rest)$#i', $class, $n) and
190 | 0 === preg_match('#(.+)_[a-z0-9]+_(args|result)$#i', $class, $n)
191 | )
192 | {
193 | $className = 'Types';
194 | } else {
195 | $className = $n[1];
196 | }
197 |
198 | $file = $dir.DIRECTORY_SEPARATOR .
199 | str_replace('\\', DIRECTORY_SEPARATOR, $namespace) .
200 | DIRECTORY_SEPARATOR .
201 | $className . '.php';
202 |
203 | if (file_exists($file)) {
204 | return $file;
205 | }
206 | }
207 | }
208 | }
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/Thrift/Exception/TApplicationException.php:
--------------------------------------------------------------------------------
1 | array('var' => 'message',
31 | 'type' => TType::STRING),
32 | 2 => array('var' => 'code',
33 | 'type' => TType::I32));
34 |
35 | const UNKNOWN = 0;
36 | const UNKNOWN_METHOD = 1;
37 | const INVALID_MESSAGE_TYPE = 2;
38 | const WRONG_METHOD_NAME = 3;
39 | const BAD_SEQUENCE_ID = 4;
40 | const MISSING_RESULT = 5;
41 | const INTERNAL_ERROR = 6;
42 | const PROTOCOL_ERROR = 7;
43 | const INVALID_TRANSFORM = 8;
44 | const INVALID_PROTOCOL = 9;
45 | const UNSUPPORTED_CLIENT_TYPE = 10;
46 |
47 | public function __construct($message=null, $code=0)
48 | {
49 | parent::__construct($message, $code);
50 | }
51 |
52 | public function read($output)
53 | {
54 | return $this->_read('TApplicationException', self::$_TSPEC, $output);
55 | }
56 |
57 | public function write($output)
58 | {
59 | $xfer = 0;
60 | $xfer += $output->writeStructBegin('TApplicationException');
61 | if ($message = $this->getMessage()) {
62 | $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
63 | $xfer += $output->writeString($message);
64 | $xfer += $output->writeFieldEnd();
65 | }
66 | if ($code = $this->getCode()) {
67 | $xfer += $output->writeFieldBegin('type', TType::I32, 2);
68 | $xfer += $output->writeI32($code);
69 | $xfer += $output->writeFieldEnd();
70 | }
71 | $xfer += $output->writeFieldStop();
72 | $xfer += $output->writeStructEnd();
73 |
74 | return $xfer;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Thrift/Exception/TException.php:
--------------------------------------------------------------------------------
1 | $fspec) {
49 | $var = $fspec['var'];
50 | if (isset($vals[$var])) {
51 | $this->$var = $vals[$var];
52 | }
53 | }
54 | } else {
55 | parent::__construct($p1, $p2);
56 | }
57 | }
58 |
59 | static $tmethod = array(TType::BOOL => 'Bool',
60 | TType::BYTE => 'Byte',
61 | TType::I16 => 'I16',
62 | TType::I32 => 'I32',
63 | TType::I64 => 'I64',
64 | TType::DOUBLE => 'Double',
65 | TType::STRING => 'String');
66 |
67 | private function _readMap(&$var, $spec, $input)
68 | {
69 | $xfer = 0;
70 | $ktype = $spec['ktype'];
71 | $vtype = $spec['vtype'];
72 | $kread = $vread = null;
73 | if (isset(TBase::$tmethod[$ktype])) {
74 | $kread = 'read'.TBase::$tmethod[$ktype];
75 | } else {
76 | $kspec = $spec['key'];
77 | }
78 | if (isset(TBase::$tmethod[$vtype])) {
79 | $vread = 'read'.TBase::$tmethod[$vtype];
80 | } else {
81 | $vspec = $spec['val'];
82 | }
83 | $var = array();
84 | $_ktype = $_vtype = $size = 0;
85 | $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
86 | for ($i = 0; $i < $size; ++$i) {
87 | $key = $val = null;
88 | if ($kread !== null) {
89 | $xfer += $input->$kread($key);
90 | } else {
91 | switch ($ktype) {
92 | case TType::STRUCT:
93 | $class = $kspec['class'];
94 | $key = new $class();
95 | $xfer += $key->read($input);
96 | break;
97 | case TType::MAP:
98 | $xfer += $this->_readMap($key, $kspec, $input);
99 | break;
100 | case TType::LST:
101 | $xfer += $this->_readList($key, $kspec, $input, false);
102 | break;
103 | case TType::SET:
104 | $xfer += $this->_readList($key, $kspec, $input, true);
105 | break;
106 | }
107 | }
108 | if ($vread !== null) {
109 | $xfer += $input->$vread($val);
110 | } else {
111 | switch ($vtype) {
112 | case TType::STRUCT:
113 | $class = $vspec['class'];
114 | $val = new $class();
115 | $xfer += $val->read($input);
116 | break;
117 | case TType::MAP:
118 | $xfer += $this->_readMap($val, $vspec, $input);
119 | break;
120 | case TType::LST:
121 | $xfer += $this->_readList($val, $vspec, $input, false);
122 | break;
123 | case TType::SET:
124 | $xfer += $this->_readList($val, $vspec, $input, true);
125 | break;
126 | }
127 | }
128 | $var[$key] = $val;
129 | }
130 | $xfer += $input->readMapEnd();
131 |
132 | return $xfer;
133 | }
134 |
135 | private function _readList(&$var, $spec, $input, $set=false)
136 | {
137 | $xfer = 0;
138 | $etype = $spec['etype'];
139 | $eread = $vread = null;
140 | if (isset(TBase::$tmethod[$etype])) {
141 | $eread = 'read'.TBase::$tmethod[$etype];
142 | } else {
143 | $espec = $spec['elem'];
144 | }
145 | $var = array();
146 | $_etype = $size = 0;
147 | if ($set) {
148 | $xfer += $input->readSetBegin($_etype, $size);
149 | } else {
150 | $xfer += $input->readListBegin($_etype, $size);
151 | }
152 | for ($i = 0; $i < $size; ++$i) {
153 | $elem = null;
154 | if ($eread !== null) {
155 | $xfer += $input->$eread($elem);
156 | } else {
157 | $espec = $spec['elem'];
158 | switch ($etype) {
159 | case TType::STRUCT:
160 | $class = $espec['class'];
161 | $elem = new $class();
162 | $xfer += $elem->read($input);
163 | break;
164 | case TType::MAP:
165 | $xfer += $this->_readMap($elem, $espec, $input);
166 | break;
167 | case TType::LST:
168 | $xfer += $this->_readList($elem, $espec, $input, false);
169 | break;
170 | case TType::SET:
171 | $xfer += $this->_readList($elem, $espec, $input, true);
172 | break;
173 | }
174 | }
175 | if ($set) {
176 | $var[$elem] = true;
177 | } else {
178 | $var []= $elem;
179 | }
180 | }
181 | if ($set) {
182 | $xfer += $input->readSetEnd();
183 | } else {
184 | $xfer += $input->readListEnd();
185 | }
186 |
187 | return $xfer;
188 | }
189 |
190 | protected function _read($class, $spec, $input)
191 | {
192 | $xfer = 0;
193 | $fname = null;
194 | $ftype = 0;
195 | $fid = 0;
196 | $xfer += $input->readStructBegin($fname);
197 | while (true) {
198 | $xfer += $input->readFieldBegin($fname, $ftype, $fid);
199 | if ($ftype == TType::STOP) {
200 | break;
201 | }
202 | if (isset($spec[$fid])) {
203 | $fspec = $spec[$fid];
204 | $var = $fspec['var'];
205 | if ($ftype == $fspec['type']) {
206 | $xfer = 0;
207 | if (isset(TBase::$tmethod[$ftype])) {
208 | $func = 'read'.TBase::$tmethod[$ftype];
209 | $xfer += $input->$func($this->$var);
210 | } else {
211 | switch ($ftype) {
212 | case TType::STRUCT:
213 | $class = $fspec['class'];
214 | $this->$var = new $class();
215 | $xfer += $this->$var->read($input);
216 | break;
217 | case TType::MAP:
218 | $xfer += $this->_readMap($this->$var, $fspec, $input);
219 | break;
220 | case TType::LST:
221 | $xfer += $this->_readList($this->$var, $fspec, $input, false);
222 | break;
223 | case TType::SET:
224 | $xfer += $this->_readList($this->$var, $fspec, $input, true);
225 | break;
226 | }
227 | }
228 | } else {
229 | $xfer += $input->skip($ftype);
230 | }
231 | } else {
232 | $xfer += $input->skip($ftype);
233 | }
234 | $xfer += $input->readFieldEnd();
235 | }
236 | $xfer += $input->readStructEnd();
237 |
238 | return $xfer;
239 | }
240 |
241 | private function _writeMap($var, $spec, $output)
242 | {
243 | $xfer = 0;
244 | $ktype = $spec['ktype'];
245 | $vtype = $spec['vtype'];
246 | $kwrite = $vwrite = null;
247 | if (isset(TBase::$tmethod[$ktype])) {
248 | $kwrite = 'write'.TBase::$tmethod[$ktype];
249 | } else {
250 | $kspec = $spec['key'];
251 | }
252 | if (isset(TBase::$tmethod[$vtype])) {
253 | $vwrite = 'write'.TBase::$tmethod[$vtype];
254 | } else {
255 | $vspec = $spec['val'];
256 | }
257 | $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
258 | foreach ($var as $key => $val) {
259 | if (isset($kwrite)) {
260 | $xfer += $output->$kwrite($key);
261 | } else {
262 | switch ($ktype) {
263 | case TType::STRUCT:
264 | $xfer += $key->write($output);
265 | break;
266 | case TType::MAP:
267 | $xfer += $this->_writeMap($key, $kspec, $output);
268 | break;
269 | case TType::LST:
270 | $xfer += $this->_writeList($key, $kspec, $output, false);
271 | break;
272 | case TType::SET:
273 | $xfer += $this->_writeList($key, $kspec, $output, true);
274 | break;
275 | }
276 | }
277 | if (isset($vwrite)) {
278 | $xfer += $output->$vwrite($val);
279 | } else {
280 | switch ($vtype) {
281 | case TType::STRUCT:
282 | $xfer += $val->write($output);
283 | break;
284 | case TType::MAP:
285 | $xfer += $this->_writeMap($val, $vspec, $output);
286 | break;
287 | case TType::LST:
288 | $xfer += $this->_writeList($val, $vspec, $output, false);
289 | break;
290 | case TType::SET:
291 | $xfer += $this->_writeList($val, $vspec, $output, true);
292 | break;
293 | }
294 | }
295 | }
296 | $xfer += $output->writeMapEnd();
297 |
298 | return $xfer;
299 | }
300 |
301 | private function _writeList($var, $spec, $output, $set=false)
302 | {
303 | $xfer = 0;
304 | $etype = $spec['etype'];
305 | $ewrite = null;
306 | if (isset(TBase::$tmethod[$etype])) {
307 | $ewrite = 'write'.TBase::$tmethod[$etype];
308 | } else {
309 | $espec = $spec['elem'];
310 | }
311 | if ($set) {
312 | $xfer += $output->writeSetBegin($etype, count($var));
313 | } else {
314 | $xfer += $output->writeListBegin($etype, count($var));
315 | }
316 | foreach ($var as $key => $val) {
317 | $elem = $set ? $key : $val;
318 | if (isset($ewrite)) {
319 | $xfer += $output->$ewrite($elem);
320 | } else {
321 | switch ($etype) {
322 | case TType::STRUCT:
323 | $xfer += $elem->write($output);
324 | break;
325 | case TType::MAP:
326 | $xfer += $this->_writeMap($elem, $espec, $output);
327 | break;
328 | case TType::LST:
329 | $xfer += $this->_writeList($elem, $espec, $output, false);
330 | break;
331 | case TType::SET:
332 | $xfer += $this->_writeList($elem, $espec, $output, true);
333 | break;
334 | }
335 | }
336 | }
337 | if ($set) {
338 | $xfer += $output->writeSetEnd();
339 | } else {
340 | $xfer += $output->writeListEnd();
341 | }
342 |
343 | return $xfer;
344 | }
345 |
346 | protected function _write($class, $spec, $output)
347 | {
348 | $xfer = 0;
349 | $xfer += $output->writeStructBegin($class);
350 | foreach ($spec as $fid => $fspec) {
351 | $var = $fspec['var'];
352 | if ($this->$var !== null) {
353 | $ftype = $fspec['type'];
354 | $xfer += $output->writeFieldBegin($var, $ftype, $fid);
355 | if (isset(TBase::$tmethod[$ftype])) {
356 | $func = 'write'.TBase::$tmethod[$ftype];
357 | $xfer += $output->$func($this->$var);
358 | } else {
359 | switch ($ftype) {
360 | case TType::STRUCT:
361 | $xfer += $this->$var->write($output);
362 | break;
363 | case TType::MAP:
364 | $xfer += $this->_writeMap($this->$var, $fspec, $output);
365 | break;
366 | case TType::LST:
367 | $xfer += $this->_writeList($this->$var, $fspec, $output, false);
368 | break;
369 | case TType::SET:
370 | $xfer += $this->_writeList($this->$var, $fspec, $output, true);
371 | break;
372 | }
373 | }
374 | $xfer += $output->writeFieldEnd();
375 | }
376 | }
377 | $xfer += $output->writeFieldStop();
378 | $xfer += $output->writeStructEnd();
379 |
380 | return $xfer;
381 | }
382 |
383 | }
384 |
--------------------------------------------------------------------------------
/Thrift/Exception/TProtocolException.php:
--------------------------------------------------------------------------------
1 | strictRead_ = $strictRead;
38 | $this->strictWrite_ = $strictWrite;
39 | }
40 |
41 | public function getProtocol($trans)
42 | {
43 | return new TBinaryProtocol($trans, $this->strictRead_, $this->strictWrite_);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Thrift/Factory/TCompactProtocolFactory.php:
--------------------------------------------------------------------------------
1 | p_ = $p;
35 | }
36 |
37 | public function write()
38 | {
39 | if ($this->first_) {
40 | $this->first_ = false;
41 | } else {
42 | $this->p_->getTransport()->write(TJSONProtocol::COMMA);
43 | }
44 | }
45 |
46 | public function read()
47 | {
48 | if ($this->first_) {
49 | $this->first_ = false;
50 | } else {
51 | $this->p_->readJSONSyntaxChar(TJSONProtocol::COMMA);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Thrift/Protocol/JSON/LookaheadReader.php:
--------------------------------------------------------------------------------
1 | p_ = $p;
34 | }
35 |
36 | public function read()
37 | {
38 | if ($this->hasData_) {
39 | $this->hasData_ = false;
40 | } else {
41 | $this->data_ = $this->p_->getTransport()->readAll(1);
42 | }
43 |
44 | return substr($this->data_, 0, 1);
45 | }
46 |
47 | public function peek()
48 | {
49 | if (!$this->hasData_) {
50 | $this->data_ = $this->p_->getTransport()->readAll(1);
51 | }
52 |
53 | $this->hasData_ = true;
54 |
55 | return substr($this->data_, 0, 1);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Thrift/Protocol/JSON/PairContext.php:
--------------------------------------------------------------------------------
1 | p_ = $p;
36 | }
37 |
38 | public function write()
39 | {
40 | if ($this->first_) {
41 | $this->first_ = false;
42 | $this->colon_ = true;
43 | } else {
44 | $this->p_->getTransport()->write($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA);
45 | $this->colon_ = !$this->colon_;
46 | }
47 | }
48 |
49 | public function read()
50 | {
51 | if ($this->first_) {
52 | $this->first_ = false;
53 | $this->colon_ = true;
54 | } else {
55 | $this->p_->readJSONSyntaxChar($this->colon_ ? TJSONProtocol::COLON : TJSONProtocol::COMMA);
56 | $this->colon_ = !$this->colon_;
57 | }
58 | }
59 |
60 | public function escapeNum()
61 | {
62 | return $this->colon_;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Thrift/Protocol/SimpleJSON/CollectionMapKeyException.php:
--------------------------------------------------------------------------------
1 | p_ = $p;
35 | }
36 |
37 | public function write()
38 | {
39 | if ($this->first_) {
40 | $this->first_ = false;
41 | } else {
42 | $this->p_->getTransport()->write(TSimpleJSONProtocol::COMMA);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Thrift/Protocol/SimpleJSON/MapContext.php:
--------------------------------------------------------------------------------
1 | isKey = !$this->isKey;
41 | }
42 |
43 | public function isMapKey()
44 | {
45 | // we want to coerce map keys to json strings regardless
46 | // of their type
47 | return $this->isKey;
48 | }
49 | }
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Thrift/Protocol/SimpleJSON/StructContext.php:
--------------------------------------------------------------------------------
1 | p_ = $p;
36 | }
37 |
38 | public function write()
39 | {
40 | if ($this->first_) {
41 | $this->first_ = false;
42 | $this->colon_ = true;
43 | } else {
44 | $this->p_->getTransport()->write(
45 | $this->colon_ ?
46 | TSimpleJSONProtocol::COLON :
47 | TSimpleJSONProtocol::COMMA
48 | );
49 | $this->colon_ = !$this->colon_;
50 | }
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/Thrift/Protocol/TBinaryProtocol.php:
--------------------------------------------------------------------------------
1 | strictRead_ = $strictRead;
45 | $this->strictWrite_ = $strictWrite;
46 | }
47 |
48 | public function writeMessageBegin($name, $type, $seqid)
49 | {
50 | if ($this->strictWrite_) {
51 | $version = self::VERSION_1 | $type;
52 |
53 | return
54 | $this->writeI32($version) +
55 | $this->writeString($name) +
56 | $this->writeI32($seqid);
57 | } else {
58 | return
59 | $this->writeString($name) +
60 | $this->writeByte($type) +
61 | $this->writeI32($seqid);
62 | }
63 | }
64 |
65 | public function writeMessageEnd()
66 | {
67 | return 0;
68 | }
69 |
70 | public function writeStructBegin($name)
71 | {
72 | return 0;
73 | }
74 |
75 | public function writeStructEnd()
76 | {
77 | return 0;
78 | }
79 |
80 | public function writeFieldBegin($fieldName, $fieldType, $fieldId)
81 | {
82 | return
83 | $this->writeByte($fieldType) +
84 | $this->writeI16($fieldId);
85 | }
86 |
87 | public function writeFieldEnd()
88 | {
89 | return 0;
90 | }
91 |
92 | public function writeFieldStop()
93 | {
94 | return
95 | $this->writeByte(TType::STOP);
96 | }
97 |
98 | public function writeMapBegin($keyType, $valType, $size)
99 | {
100 | return
101 | $this->writeByte($keyType) +
102 | $this->writeByte($valType) +
103 | $this->writeI32($size);
104 | }
105 |
106 | public function writeMapEnd()
107 | {
108 | return 0;
109 | }
110 |
111 | public function writeListBegin($elemType, $size)
112 | {
113 | return
114 | $this->writeByte($elemType) +
115 | $this->writeI32($size);
116 | }
117 |
118 | public function writeListEnd()
119 | {
120 | return 0;
121 | }
122 |
123 | public function writeSetBegin($elemType, $size)
124 | {
125 | return
126 | $this->writeByte($elemType) +
127 | $this->writeI32($size);
128 | }
129 |
130 | public function writeSetEnd()
131 | {
132 | return 0;
133 | }
134 |
135 | public function writeBool($value)
136 | {
137 | $data = pack('c', $value ? 1 : 0);
138 | $this->trans_->write($data, 1);
139 |
140 | return 1;
141 | }
142 |
143 | public function writeByte($value)
144 | {
145 | $data = pack('c', $value);
146 | $this->trans_->write($data, 1);
147 |
148 | return 1;
149 | }
150 |
151 | public function writeI16($value)
152 | {
153 | $data = pack('n', $value);
154 | $this->trans_->write($data, 2);
155 |
156 | return 2;
157 | }
158 |
159 | public function writeI32($value)
160 | {
161 | $data = pack('N', $value);
162 | $this->trans_->write($data, 4);
163 |
164 | return 4;
165 | }
166 |
167 | public function writeI64($value)
168 | {
169 | // If we are on a 32bit architecture we have to explicitly deal with
170 | // 64-bit twos-complement arithmetic since PHP wants to treat all ints
171 | // as signed and any int over 2^31 - 1 as a float
172 | if (PHP_INT_SIZE == 4) {
173 | $neg = $value < 0;
174 |
175 | if ($neg) {
176 | $value *= -1;
177 | }
178 |
179 | $hi = (int) ($value / 4294967296);
180 | $lo = (int) $value;
181 |
182 | if ($neg) {
183 | $hi = ~$hi;
184 | $lo = ~$lo;
185 | if (($lo & (int) 0xffffffff) == (int) 0xffffffff) {
186 | $lo = 0;
187 | $hi++;
188 | } else {
189 | $lo++;
190 | }
191 | }
192 | $data = pack('N2', $hi, $lo);
193 |
194 | } else {
195 | $hi = $value >> 32;
196 | $lo = $value & 0xFFFFFFFF;
197 | $data = pack('N2', $hi, $lo);
198 | }
199 |
200 | $this->trans_->write($data, 8);
201 |
202 | return 8;
203 | }
204 |
205 | public function writeDouble($value)
206 | {
207 | $data = pack('d', $value);
208 | $this->trans_->write(strrev($data), 8);
209 |
210 | return 8;
211 | }
212 |
213 | public function writeString($value)
214 | {
215 | $len = TStringFuncFactory::create()->strlen($value);
216 | $result = $this->writeI32($len);
217 | if ($len) {
218 | $this->trans_->write($value, $len);
219 | }
220 |
221 | return $result + $len;
222 | }
223 |
224 | public function readMessageBegin(&$name, &$type, &$seqid)
225 | {
226 | $result = $this->readI32($sz);
227 | if ($sz < 0) {
228 | $version = (int) ($sz & self::VERSION_MASK);
229 | if ($version != (int) self::VERSION_1) {
230 | throw new TProtocolException('Bad version identifier: '.$sz, TProtocolException::BAD_VERSION);
231 | }
232 | $type = $sz & 0x000000ff;
233 | $result +=
234 | $this->readString($name) +
235 | $this->readI32($seqid);
236 | } else {
237 | if ($this->strictRead_) {
238 | throw new TProtocolException('No version identifier, old protocol client?', TProtocolException::BAD_VERSION);
239 | } else {
240 | // Handle pre-versioned input
241 | $name = $this->trans_->readAll($sz);
242 | $result +=
243 | $sz +
244 | $this->readByte($type) +
245 | $this->readI32($seqid);
246 | }
247 | }
248 |
249 | return $result;
250 | }
251 |
252 | public function readMessageEnd()
253 | {
254 | return 0;
255 | }
256 |
257 | public function readStructBegin(&$name)
258 | {
259 | $name = '';
260 |
261 | return 0;
262 | }
263 |
264 | public function readStructEnd()
265 | {
266 | return 0;
267 | }
268 |
269 | public function readFieldBegin(&$name, &$fieldType, &$fieldId)
270 | {
271 | $result = $this->readByte($fieldType);
272 | if ($fieldType == TType::STOP) {
273 | $fieldId = 0;
274 |
275 | return $result;
276 | }
277 | $result += $this->readI16($fieldId);
278 |
279 | return $result;
280 | }
281 |
282 | public function readFieldEnd()
283 | {
284 | return 0;
285 | }
286 |
287 | public function readMapBegin(&$keyType, &$valType, &$size)
288 | {
289 | return
290 | $this->readByte($keyType) +
291 | $this->readByte($valType) +
292 | $this->readI32($size);
293 | }
294 |
295 | public function readMapEnd()
296 | {
297 | return 0;
298 | }
299 |
300 | public function readListBegin(&$elemType, &$size)
301 | {
302 | return
303 | $this->readByte($elemType) +
304 | $this->readI32($size);
305 | }
306 |
307 | public function readListEnd()
308 | {
309 | return 0;
310 | }
311 |
312 | public function readSetBegin(&$elemType, &$size)
313 | {
314 | return
315 | $this->readByte($elemType) +
316 | $this->readI32($size);
317 | }
318 |
319 | public function readSetEnd()
320 | {
321 | return 0;
322 | }
323 |
324 | public function readBool(&$value)
325 | {
326 | $data = $this->trans_->readAll(1);
327 | $arr = unpack('c', $data);
328 | $value = $arr[1] == 1;
329 |
330 | return 1;
331 | }
332 |
333 | public function readByte(&$value)
334 | {
335 | $data = $this->trans_->readAll(1);
336 | $arr = unpack('c', $data);
337 | $value = $arr[1];
338 |
339 | return 1;
340 | }
341 |
342 | public function readI16(&$value)
343 | {
344 | $data = $this->trans_->readAll(2);
345 | $arr = unpack('n', $data);
346 | $value = $arr[1];
347 | if ($value > 0x7fff) {
348 | $value = 0 - (($value - 1) ^ 0xffff);
349 | }
350 |
351 | return 2;
352 | }
353 |
354 | public function readI32(&$value)
355 | {
356 | $data = $this->trans_->readAll(4);
357 | $arr = unpack('N', $data);
358 | $value = $arr[1];
359 | if ($value > 0x7fffffff) {
360 | $value = 0 - (($value - 1) ^ 0xffffffff);
361 | }
362 |
363 | return 4;
364 | }
365 |
366 | public function readI64(&$value)
367 | {
368 | $data = $this->trans_->readAll(8);
369 |
370 | $arr = unpack('N2', $data);
371 |
372 | // If we are on a 32bit architecture we have to explicitly deal with
373 | // 64-bit twos-complement arithmetic since PHP wants to treat all ints
374 | // as signed and any int over 2^31 - 1 as a float
375 | if (PHP_INT_SIZE == 4) {
376 |
377 | $hi = $arr[1];
378 | $lo = $arr[2];
379 | $isNeg = $hi < 0;
380 |
381 | // Check for a negative
382 | if ($isNeg) {
383 | $hi = ~$hi & (int) 0xffffffff;
384 | $lo = ~$lo & (int) 0xffffffff;
385 |
386 | if ($lo == (int) 0xffffffff) {
387 | $hi++;
388 | $lo = 0;
389 | } else {
390 | $lo++;
391 | }
392 | }
393 |
394 | // Force 32bit words in excess of 2G to pe positive - we deal wigh sign
395 | // explicitly below
396 |
397 | if ($hi & (int) 0x80000000) {
398 | $hi &= (int) 0x7fffffff;
399 | $hi += 0x80000000;
400 | }
401 |
402 | if ($lo & (int) 0x80000000) {
403 | $lo &= (int) 0x7fffffff;
404 | $lo += 0x80000000;
405 | }
406 |
407 | $value = $hi * 4294967296 + $lo;
408 |
409 | if ($isNeg) {
410 | $value = 0 - $value;
411 | }
412 | } else {
413 |
414 | // Upcast negatives in LSB bit
415 | if ($arr[2] & 0x80000000) {
416 | $arr[2] = $arr[2] & 0xffffffff;
417 | }
418 |
419 | // Check for a negative
420 | if ($arr[1] & 0x80000000) {
421 | $arr[1] = $arr[1] & 0xffffffff;
422 | $arr[1] = $arr[1] ^ 0xffffffff;
423 | $arr[2] = $arr[2] ^ 0xffffffff;
424 | $value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
425 | } else {
426 | $value = $arr[1]*4294967296 + $arr[2];
427 | }
428 | }
429 |
430 | return 8;
431 | }
432 |
433 | public function readDouble(&$value)
434 | {
435 | $data = strrev($this->trans_->readAll(8));
436 | $arr = unpack('d', $data);
437 | $value = $arr[1];
438 |
439 | return 8;
440 | }
441 |
442 | public function readString(&$value)
443 | {
444 | $result = $this->readI32($len);
445 | if ($len) {
446 | $value = $this->trans_->readAll($len);
447 | } else {
448 | $value = '';
449 | }
450 |
451 | return $result + $len;
452 | }
453 | }
454 |
--------------------------------------------------------------------------------
/Thrift/Protocol/TBinaryProtocolAccelerated.php:
--------------------------------------------------------------------------------
1 | strictRead_;
60 | }
61 | public function isStrictWrite()
62 | {
63 | return $this->strictWrite_;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Thrift/Protocol/TMultiplexedProtocol.php:
--------------------------------------------------------------------------------
1 | TMultiplexedProtocol is a protocol-independent concrete decorator
29 | * that allows a Thrift client to communicate with a multiplexing Thrift server,
30 | * by prepending the service name to the function name during function calls.
31 | *
32 | * @package Thrift\Protocol
33 | */
34 | class TMultiplexedProtocol extends TProtocolDecorator
35 | {
36 | /**
37 | * Separator between service name and function name.
38 | * Should be the same as used at multiplexed Thrift server.
39 | *
40 | * @var string
41 | */
42 | const SEPARATOR = ":";
43 |
44 | /**
45 | * The name of service.
46 | *
47 | * @var string
48 | */
49 | private $serviceName_;
50 |
51 | /**
52 | * Constructor of TMultiplexedProtocol
class.
53 | *
54 | * Wrap the specified protocol, allowing it to be used to communicate with a
55 | * multiplexing server. The $serviceName
is required as it is
56 | * prepended to the message header so that the multiplexing server can broker
57 | * the function call to the proper service.
58 | *
59 | * @param TProtocol $protocol
60 | * @param string $serviceName The name of service.
61 | */
62 | public function __construct(TProtocol $protocol, $serviceName)
63 | {
64 | parent::__construct($protocol);
65 | $this->serviceName_ = $serviceName;
66 | }
67 |
68 | /**
69 | * Writes the message header.
70 | * Prepends the service name to the function name, separated by TMultiplexedProtocol::SEPARATOR
.
71 | *
72 | * @param string $name Function name.
73 | * @param int $type Message type.
74 | * @param int $seqid The sequence id of this message.
75 | */
76 | public function writeMessageBegin($name, $type, $seqid)
77 | {
78 | if ($type == TMessageType::CALL || $type == TMessageType::ONEWAY) {
79 | $nameWithService = $this->serviceName_ . self::SEPARATOR . $name;
80 | parent::writeMessageBegin($nameWithService, $type, $seqid);
81 | } else {
82 | parent::writeMessageBegin($name, $type, $seqid);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Thrift/Protocol/TProtocol.php:
--------------------------------------------------------------------------------
1 | trans_ = $trans;
46 | }
47 |
48 | /**
49 | * Accessor for transport
50 | *
51 | * @return TTransport
52 | */
53 | public function getTransport()
54 | {
55 | return $this->trans_;
56 | }
57 |
58 | /**
59 | * Writes the message header
60 | *
61 | * @param string $name Function name
62 | * @param int $type message type TMessageType::CALL or TMessageType::REPLY
63 | * @param int $seqid The sequence id of this message
64 | */
65 | abstract public function writeMessageBegin($name, $type, $seqid);
66 |
67 | /**
68 | * Close the message
69 | */
70 | abstract public function writeMessageEnd();
71 |
72 | /**
73 | * Writes a struct header.
74 | *
75 | * @param string $name Struct name
76 | * @throws TException on write error
77 | * @return int How many bytes written
78 | */
79 | abstract public function writeStructBegin($name);
80 |
81 | /**
82 | * Close a struct.
83 | *
84 | * @throws TException on write error
85 | * @return int How many bytes written
86 | */
87 | abstract public function writeStructEnd();
88 |
89 | /*
90 | * Starts a field.
91 | *
92 | * @param string $name Field name
93 | * @param int $type Field type
94 | * @param int $fid Field id
95 | * @throws TException on write error
96 | * @return int How many bytes written
97 | */
98 | abstract public function writeFieldBegin($fieldName, $fieldType, $fieldId);
99 |
100 | abstract public function writeFieldEnd();
101 |
102 | abstract public function writeFieldStop();
103 |
104 | abstract public function writeMapBegin($keyType, $valType, $size);
105 |
106 | abstract public function writeMapEnd();
107 |
108 | abstract public function writeListBegin($elemType, $size);
109 |
110 | abstract public function writeListEnd();
111 |
112 | abstract public function writeSetBegin($elemType, $size);
113 |
114 | abstract public function writeSetEnd();
115 |
116 | abstract public function writeBool($bool);
117 |
118 | abstract public function writeByte($byte);
119 |
120 | abstract public function writeI16($i16);
121 |
122 | abstract public function writeI32($i32);
123 |
124 | abstract public function writeI64($i64);
125 |
126 | abstract public function writeDouble($dub);
127 |
128 | abstract public function writeString($str);
129 |
130 | /**
131 | * Reads the message header
132 | *
133 | * @param string $name Function name
134 | * @param int $type message type TMessageType::CALL or TMessageType::REPLY
135 | * @parem int $seqid The sequence id of this message
136 | */
137 | abstract public function readMessageBegin(&$name, &$type, &$seqid);
138 |
139 | /**
140 | * Read the close of message
141 | */
142 | abstract public function readMessageEnd();
143 |
144 | abstract public function readStructBegin(&$name);
145 |
146 | abstract public function readStructEnd();
147 |
148 | abstract public function readFieldBegin(&$name, &$fieldType, &$fieldId);
149 |
150 | abstract public function readFieldEnd();
151 |
152 | abstract public function readMapBegin(&$keyType, &$valType, &$size);
153 |
154 | abstract public function readMapEnd();
155 |
156 | abstract public function readListBegin(&$elemType, &$size);
157 |
158 | abstract public function readListEnd();
159 |
160 | abstract public function readSetBegin(&$elemType, &$size);
161 |
162 | abstract public function readSetEnd();
163 |
164 | abstract public function readBool(&$bool);
165 |
166 | abstract public function readByte(&$byte);
167 |
168 | abstract public function readI16(&$i16);
169 |
170 | abstract public function readI32(&$i32);
171 |
172 | abstract public function readI64(&$i64);
173 |
174 | abstract public function readDouble(&$dub);
175 |
176 | abstract public function readString(&$str);
177 |
178 | /**
179 | * The skip function is a utility to parse over unrecognized date without
180 | * causing corruption.
181 | *
182 | * @param TType $type What type is it
183 | */
184 | public function skip($type)
185 | {
186 | switch ($type) {
187 | case TType::BOOL:
188 | return $this->readBool($bool);
189 | case TType::BYTE:
190 | return $this->readByte($byte);
191 | case TType::I16:
192 | return $this->readI16($i16);
193 | case TType::I32:
194 | return $this->readI32($i32);
195 | case TType::I64:
196 | return $this->readI64($i64);
197 | case TType::DOUBLE:
198 | return $this->readDouble($dub);
199 | case TType::STRING:
200 | return $this->readString($str);
201 | case TType::STRUCT:
202 | {
203 | $result = $this->readStructBegin($name);
204 | while (true) {
205 | $result += $this->readFieldBegin($name, $ftype, $fid);
206 | if ($ftype == TType::STOP) {
207 | break;
208 | }
209 | $result += $this->skip($ftype);
210 | $result += $this->readFieldEnd();
211 | }
212 | $result += $this->readStructEnd();
213 |
214 | return $result;
215 | }
216 | case TType::MAP:
217 | {
218 | $result = $this->readMapBegin($keyType, $valType, $size);
219 | for ($i = 0; $i < $size; $i++) {
220 | $result += $this->skip($keyType);
221 | $result += $this->skip($valType);
222 | }
223 | $result += $this->readMapEnd();
224 |
225 | return $result;
226 | }
227 | case TType::SET:
228 | {
229 | $result = $this->readSetBegin($elemType, $size);
230 | for ($i = 0; $i < $size; $i++) {
231 | $result += $this->skip($elemType);
232 | }
233 | $result += $this->readSetEnd();
234 |
235 | return $result;
236 | }
237 | case TType::LST:
238 | {
239 | $result = $this->readListBegin($elemType, $size);
240 | for ($i = 0; $i < $size; $i++) {
241 | $result += $this->skip($elemType);
242 | }
243 | $result += $this->readListEnd();
244 |
245 | return $result;
246 | }
247 | default:
248 | throw new TProtocolException('Unknown field type: '.$type,
249 | TProtocolException::INVALID_DATA);
250 | }
251 | }
252 |
253 | /**
254 | * Utility for skipping binary data
255 | *
256 | * @param TTransport $itrans TTransport object
257 | * @param int $type Field type
258 | */
259 | public static function skipBinary($itrans, $type)
260 | {
261 | switch ($type) {
262 | case TType::BOOL:
263 | return $itrans->readAll(1);
264 | case TType::BYTE:
265 | return $itrans->readAll(1);
266 | case TType::I16:
267 | return $itrans->readAll(2);
268 | case TType::I32:
269 | return $itrans->readAll(4);
270 | case TType::I64:
271 | return $itrans->readAll(8);
272 | case TType::DOUBLE:
273 | return $itrans->readAll(8);
274 | case TType::STRING:
275 | $len = unpack('N', $itrans->readAll(4));
276 | $len = $len[1];
277 | if ($len > 0x7fffffff) {
278 | $len = 0 - (($len - 1) ^ 0xffffffff);
279 | }
280 |
281 | return 4 + $itrans->readAll($len);
282 | case TType::STRUCT:
283 | {
284 | $result = 0;
285 | while (true) {
286 | $ftype = 0;
287 | $fid = 0;
288 | $data = $itrans->readAll(1);
289 | $arr = unpack('c', $data);
290 | $ftype = $arr[1];
291 | if ($ftype == TType::STOP) {
292 | break;
293 | }
294 | // I16 field id
295 | $result += $itrans->readAll(2);
296 | $result += self::skipBinary($itrans, $ftype);
297 | }
298 |
299 | return $result;
300 | }
301 | case TType::MAP:
302 | {
303 | // Ktype
304 | $data = $itrans->readAll(1);
305 | $arr = unpack('c', $data);
306 | $ktype = $arr[1];
307 | // Vtype
308 | $data = $itrans->readAll(1);
309 | $arr = unpack('c', $data);
310 | $vtype = $arr[1];
311 | // Size
312 | $data = $itrans->readAll(4);
313 | $arr = unpack('N', $data);
314 | $size = $arr[1];
315 | if ($size > 0x7fffffff) {
316 | $size = 0 - (($size - 1) ^ 0xffffffff);
317 | }
318 | $result = 6;
319 | for ($i = 0; $i < $size; $i++) {
320 | $result += self::skipBinary($itrans, $ktype);
321 | $result += self::skipBinary($itrans, $vtype);
322 | }
323 |
324 | return $result;
325 | }
326 | case TType::SET:
327 | case TType::LST:
328 | {
329 | // Vtype
330 | $data = $itrans->readAll(1);
331 | $arr = unpack('c', $data);
332 | $vtype = $arr[1];
333 | // Size
334 | $data = $itrans->readAll(4);
335 | $arr = unpack('N', $data);
336 | $size = $arr[1];
337 | if ($size > 0x7fffffff) {
338 | $size = 0 - (($size - 1) ^ 0xffffffff);
339 | }
340 | $result = 5;
341 | for ($i = 0; $i < $size; $i++) {
342 | $result += self::skipBinary($itrans, $vtype);
343 | }
344 |
345 | return $result;
346 | }
347 | default:
348 | throw new TProtocolException('Unknown field type: '.$type,
349 | TProtocolException::INVALID_DATA);
350 | }
351 | }
352 | }
353 |
--------------------------------------------------------------------------------
/Thrift/Protocol/TProtocolDecorator.php:
--------------------------------------------------------------------------------
1 | TProtocolDecorator forwards all requests to an enclosed
28 | * TProtocol
instance, providing a way to author concise
29 | * concrete decorator subclasses. While it has no abstract methods, it
30 | * is marked abstract as a reminder that by itself, it does not modify
31 | * the behaviour of the enclosed TProtocol
.
32 | *
33 | * @package Thrift\Protocol
34 | */
35 | abstract class TProtocolDecorator extends TProtocol
36 | {
37 | /**
38 | * Instance of protocol, to which all operations will be forwarded.
39 | *
40 | * @var TProtocol
41 | */
42 | private $concreteProtocol_;
43 |
44 | /**
45 | * Constructor of TProtocolDecorator
class.
46 | * Encloses the specified protocol.
47 | *
48 | * @param TProtocol $protocol All operations will be forward to this instance. Must be non-null.
49 | */
50 | protected function __construct(TProtocol $protocol)
51 | {
52 | parent::__construct($protocol->getTransport());
53 | $this->concreteProtocol_ = $protocol;
54 | }
55 |
56 | /**
57 | * Writes the message header.
58 | *
59 | * @param string $name Function name
60 | * @param int $type message type TMessageType::CALL or TMessageType::REPLY
61 | * @param int $seqid The sequence id of this message
62 | */
63 | public function writeMessageBegin($name, $type, $seqid)
64 | {
65 | return $this->concreteProtocol_->writeMessageBegin($name, $type, $seqid);
66 | }
67 |
68 | /**
69 | * Closes the message.
70 | */
71 | public function writeMessageEnd()
72 | {
73 | return $this->concreteProtocol_->writeMessageEnd();
74 | }
75 |
76 | /**
77 | * Writes a struct header.
78 | *
79 | * @param string $name Struct name
80 | *
81 | * @throws TException on write error
82 | * @return int How many bytes written
83 | */
84 | public function writeStructBegin($name)
85 | {
86 | return $this->concreteProtocol_->writeStructBegin($name);
87 | }
88 |
89 | /**
90 | * Close a struct.
91 | *
92 | * @throws TException on write error
93 | * @return int How many bytes written
94 | */
95 | public function writeStructEnd()
96 | {
97 | return $this->concreteProtocol_->writeStructEnd();
98 | }
99 |
100 | public function writeFieldBegin($fieldName, $fieldType, $fieldId)
101 | {
102 | return $this->concreteProtocol_->writeFieldBegin($fieldName, $fieldType, $fieldId);
103 | }
104 |
105 | public function writeFieldEnd()
106 | {
107 | return $this->concreteProtocol_->writeFieldEnd();
108 | }
109 |
110 | public function writeFieldStop()
111 | {
112 | return $this->concreteProtocol_->writeFieldStop();
113 | }
114 |
115 | public function writeMapBegin($keyType, $valType, $size)
116 | {
117 | return $this->concreteProtocol_->writeMapBegin($keyType, $valType, $size);
118 | }
119 |
120 | public function writeMapEnd()
121 | {
122 | return $this->concreteProtocol_->writeMapEnd();
123 | }
124 |
125 | public function writeListBegin($elemType, $size)
126 | {
127 | return $this->concreteProtocol_->writeListBegin($elemType, $size);
128 | }
129 |
130 | public function writeListEnd()
131 | {
132 | return $this->concreteProtocol_->writeListEnd();
133 | }
134 |
135 | public function writeSetBegin($elemType, $size)
136 | {
137 | return $this->concreteProtocol_->writeSetBegin($elemType, $size);
138 | }
139 |
140 | public function writeSetEnd()
141 | {
142 | return $this->concreteProtocol_->writeSetEnd();
143 | }
144 |
145 | public function writeBool($bool)
146 | {
147 | return $this->concreteProtocol_->writeBool($bool);
148 | }
149 |
150 | public function writeByte($byte)
151 | {
152 | return $this->concreteProtocol_->writeByte($byte);
153 | }
154 |
155 | public function writeI16($i16)
156 | {
157 | return $this->concreteProtocol_->writeI16($i16);
158 | }
159 |
160 | public function writeI32($i32)
161 | {
162 | return $this->concreteProtocol_->writeI32($i32);
163 | }
164 |
165 | public function writeI64($i64)
166 | {
167 | return $this->concreteProtocol_->writeI64($i64);
168 | }
169 |
170 | public function writeDouble($dub)
171 | {
172 | return $this->concreteProtocol_->writeDouble($dub);
173 | }
174 |
175 | public function writeString($str)
176 | {
177 | return $this->concreteProtocol_->writeString($str);
178 | }
179 |
180 | /**
181 | * Reads the message header
182 | *
183 | * @param string $name Function name
184 | * @param int $type message type TMessageType::CALL or TMessageType::REPLY
185 | * @param int $seqid The sequence id of this message
186 | */
187 | public function readMessageBegin(&$name, &$type, &$seqid)
188 | {
189 | return $this->concreteProtocol_->readMessageBegin($name, $type, $seqid);
190 | }
191 |
192 | /**
193 | * Read the close of message
194 | */
195 | public function readMessageEnd()
196 | {
197 | return $this->concreteProtocol_->readMessageEnd();
198 | }
199 |
200 | public function readStructBegin(&$name)
201 | {
202 | return $this->concreteProtocol_->readStructBegin($name);
203 | }
204 |
205 | public function readStructEnd()
206 | {
207 | return $this->concreteProtocol_->readStructEnd();
208 | }
209 |
210 | public function readFieldBegin(&$name, &$fieldType, &$fieldId)
211 | {
212 | return $this->concreteProtocol_->readFieldBegin($name, $fieldType, $fieldId);
213 | }
214 |
215 | public function readFieldEnd()
216 | {
217 | return $this->concreteProtocol_->readFieldEnd();
218 | }
219 |
220 | public function readMapBegin(&$keyType, &$valType, &$size)
221 | {
222 | $this->concreteProtocol_->readMapBegin($keyType, $valType, $size);
223 | }
224 |
225 | public function readMapEnd()
226 | {
227 | return $this->concreteProtocol_->readMapEnd();
228 | }
229 |
230 | public function readListBegin(&$elemType, &$size)
231 | {
232 | $this->concreteProtocol_->readListBegin($elemType, $size);
233 | }
234 |
235 | public function readListEnd()
236 | {
237 | return $this->concreteProtocol_->readListEnd();
238 | }
239 |
240 | public function readSetBegin(&$elemType, &$size)
241 | {
242 | return $this->concreteProtocol_->readSetBegin($elemType, $size);
243 | }
244 |
245 | public function readSetEnd()
246 | {
247 | return $this->concreteProtocol_->readSetEnd();
248 | }
249 |
250 | public function readBool(&$bool)
251 | {
252 | return $this->concreteProtocol_->readBool($bool);
253 | }
254 |
255 | public function readByte(&$byte)
256 | {
257 | return $this->concreteProtocol_->readByte($byte);
258 | }
259 |
260 | public function readI16(&$i16)
261 | {
262 | return $this->concreteProtocol_->readI16($i16);
263 | }
264 |
265 | public function readI32(&$i32)
266 | {
267 | return $this->concreteProtocol_->readI32($i32);
268 | }
269 |
270 | public function readI64(&$i64)
271 | {
272 | return $this->concreteProtocol_->readI64($i64);
273 | }
274 |
275 | public function readDouble(&$dub)
276 | {
277 | return $this->concreteProtocol_->readDouble($dub);
278 | }
279 |
280 | public function readString(&$str)
281 | {
282 | return $this->concreteProtocol_->readString($str);
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/Thrift/Protocol/TSimpleJSONProtocol.php:
--------------------------------------------------------------------------------
1 | writeContextStack_[] = $this->writeContext_;
59 | $this->writeContext_ = $c;
60 | }
61 |
62 | /**
63 | * Pop the last write context off the stack
64 | */
65 | protected function popWriteContext() {
66 | $this->writeContext_ = array_pop($this->writeContextStack_);
67 | }
68 |
69 | /**
70 | * Used to make sure that we are not encountering a map whose keys are containers
71 | */
72 | protected function assertContextIsNotMapKey($invalidKeyType) {
73 | if ($this->writeContext_->isMapKey()) {
74 | throw new CollectionMapKeyException(
75 | "Cannot serialize a map with keys that are of type " .
76 | $invalidKeyType
77 | );
78 | }
79 | }
80 |
81 | private function writeJSONString($b)
82 | {
83 | $this->writeContext_->write();
84 |
85 | $this->trans_->write(json_encode((string)$b));
86 | }
87 |
88 | private function writeJSONInteger($num)
89 | {
90 | $isMapKey = $this->writeContext_->isMapKey();
91 |
92 | $this->writeContext_->write();
93 |
94 | if ($isMapKey) {
95 | $this->trans_->write(self::QUOTE);
96 | }
97 |
98 | $this->trans_->write((int)$num);
99 |
100 | if ($isMapKey) {
101 | $this->trans_->write(self::QUOTE);
102 | }
103 | }
104 |
105 | private function writeJSONDouble($num)
106 | {
107 | $isMapKey = $this->writeContext_->isMapKey();
108 |
109 | $this->writeContext_->write();
110 |
111 | if ($isMapKey) {
112 | $this->trans_->write(self::QUOTE);
113 | }
114 |
115 | $this->trans_->write(json_encode((float)$num));
116 |
117 | if ($isMapKey) {
118 | $this->trans_->write(self::QUOTE);
119 | }
120 | }
121 |
122 | /**
123 | * Constructor
124 | */
125 | public function __construct($trans)
126 | {
127 | parent::__construct($trans);
128 | $this->writeContext_ = new Context();
129 | }
130 |
131 | /**
132 | * Writes the message header
133 | *
134 | * @param string $name Function name
135 | * @param int $type message type TMessageType::CALL or TMessageType::REPLY
136 | * @param int $seqid The sequence id of this message
137 | */
138 | public function writeMessageBegin($name, $type, $seqid)
139 | {
140 | $this->trans_->write(self::LBRACKET);
141 | $this->pushWriteContext(new ListContext($this));
142 | $this->writeJSONString($name);
143 | $this->writeJSONInteger($type);
144 | $this->writeJSONInteger($seqid);
145 | }
146 |
147 | /**
148 | * Close the message
149 | */
150 | public function writeMessageEnd()
151 | {
152 | $this->popWriteContext();
153 | $this->trans_->write(self::RBRACKET);
154 | }
155 |
156 | /**
157 | * Writes a struct header.
158 | *
159 | * @param string $name Struct name
160 | */
161 | public function writeStructBegin($name)
162 | {
163 | $this->writeContext_->write();
164 | $this->trans_->write(self::LBRACE);
165 | $this->pushWriteContext(new StructContext($this));
166 | }
167 |
168 | /**
169 | * Close a struct.
170 | */
171 | public function writeStructEnd()
172 | {
173 | $this->popWriteContext();
174 | $this->trans_->write(self::RBRACE);
175 | }
176 |
177 | public function writeFieldBegin($fieldName, $fieldType, $fieldId)
178 | {
179 | $this->writeJSONString($fieldName);
180 | }
181 |
182 | public function writeFieldEnd()
183 | {
184 | }
185 |
186 | public function writeFieldStop()
187 | {
188 | }
189 |
190 | public function writeMapBegin($keyType, $valType, $size)
191 | {
192 | $this->assertContextIsNotMapKey(self::NAME_MAP);
193 | $this->writeContext_->write();
194 | $this->trans_->write(self::LBRACE);
195 | $this->pushWriteContext(new MapContext($this));
196 | }
197 |
198 | public function writeMapEnd()
199 | {
200 | $this->popWriteContext();
201 | $this->trans_->write(self::RBRACE);
202 | }
203 |
204 | public function writeListBegin($elemType, $size)
205 | {
206 | $this->assertContextIsNotMapKey(self::NAME_LIST);
207 | $this->writeContext_->write();
208 | $this->trans_->write(self::LBRACKET);
209 | $this->pushWriteContext(new ListContext($this));
210 | // No metadata!
211 | }
212 |
213 | public function writeListEnd()
214 | {
215 | $this->popWriteContext();
216 | $this->trans_->write(self::RBRACKET);
217 | }
218 |
219 | public function writeSetBegin($elemType, $size)
220 | {
221 | $this->assertContextIsNotMapKey(self::NAME_SET);
222 | $this->writeContext_->write();
223 | $this->trans_->write(self::LBRACKET);
224 | $this->pushWriteContext(new ListContext($this));
225 | // No metadata!
226 | }
227 |
228 | public function writeSetEnd()
229 | {
230 | $this->popWriteContext();
231 | $this->trans_->write(self::RBRACKET);
232 | }
233 |
234 | public function writeBool($bool)
235 | {
236 | $this->writeJSONInteger($bool ? 1 : 0);
237 | }
238 |
239 | public function writeByte($byte)
240 | {
241 | $this->writeJSONInteger($byte);
242 | }
243 |
244 | public function writeI16($i16)
245 | {
246 | $this->writeJSONInteger($i16);
247 | }
248 |
249 | public function writeI32($i32)
250 | {
251 | $this->writeJSONInteger($i32);
252 | }
253 |
254 | public function writeI64($i64)
255 | {
256 | $this->writeJSONInteger($i64);
257 | }
258 |
259 | public function writeDouble($dub)
260 | {
261 | $this->writeJSONDouble($dub);
262 | }
263 |
264 | public function writeString($str)
265 | {
266 | $this->writeJSONString($str);
267 | }
268 |
269 | /**
270 | * Reading methods.
271 | *
272 | * simplejson is not meant to be read back into thrift
273 | * - see http://wiki.apache.org/thrift/ThriftUsageJava
274 | * - use JSON instead
275 | */
276 |
277 | public function readMessageBegin(&$name, &$type, &$seqid)
278 | {
279 | throw new TException("Not implemented");
280 | }
281 |
282 | public function readMessageEnd()
283 | {
284 | throw new TException("Not implemented");
285 | }
286 |
287 | public function readStructBegin(&$name)
288 | {
289 | throw new TException("Not implemented");
290 | }
291 |
292 | public function readStructEnd()
293 | {
294 | throw new TException("Not implemented");
295 | }
296 |
297 | public function readFieldBegin(&$name, &$fieldType, &$fieldId)
298 | {
299 | throw new TException("Not implemented");
300 | }
301 |
302 | public function readFieldEnd()
303 | {
304 | throw new TException("Not implemented");
305 | }
306 |
307 | public function readMapBegin(&$keyType, &$valType, &$size)
308 | {
309 | throw new TException("Not implemented");
310 | }
311 |
312 | public function readMapEnd()
313 | {
314 | throw new TException("Not implemented");
315 | }
316 |
317 | public function readListBegin(&$elemType, &$size)
318 | {
319 | throw new TException("Not implemented");
320 | }
321 |
322 | public function readListEnd()
323 | {
324 | throw new TException("Not implemented");
325 | }
326 |
327 | public function readSetBegin(&$elemType, &$size)
328 | {
329 | throw new TException("Not implemented");
330 | }
331 |
332 | public function readSetEnd()
333 | {
334 | throw new TException("Not implemented");
335 | }
336 |
337 | public function readBool(&$bool)
338 | {
339 | throw new TException("Not implemented");
340 | }
341 |
342 | public function readByte(&$byte)
343 | {
344 | throw new TException("Not implemented");
345 | }
346 |
347 | public function readI16(&$i16)
348 | {
349 | throw new TException("Not implemented");
350 | }
351 |
352 | public function readI32(&$i32)
353 | {
354 | throw new TException("Not implemented");
355 | }
356 |
357 | public function readI64(&$i64)
358 | {
359 | throw new TException("Not implemented");
360 | }
361 |
362 | public function readDouble(&$dub)
363 | {
364 | throw new TException("Not implemented");
365 | }
366 |
367 | public function readString(&$str)
368 | {
369 | throw new TException("Not implemented");
370 | }
371 | }
372 |
--------------------------------------------------------------------------------
/Thrift/Serializer/TBinarySerializer.php:
--------------------------------------------------------------------------------
1 | getName(),
47 | TMessageType::REPLY, $object,
48 | 0, $protocol->isStrictWrite());
49 |
50 | $protocol->readMessageBegin($unused_name, $unused_type,
51 | $unused_seqid);
52 | } else {
53 | $object->write($protocol);
54 | }
55 | $protocol->getTransport()->flush();
56 |
57 | return $transport->getBuffer();
58 | }
59 |
60 | public static function deserialize($string_object, $class_name)
61 | {
62 | $transport = new TMemoryBuffer();
63 | $protocol = new TBinaryProtocolAccelerated($transport);
64 | if (function_exists('thrift_protocol_read_binary')) {
65 | // NOTE (t.heintz) TBinaryProtocolAccelerated internally wraps our TMemoryBuffer in a
66 | // TBufferedTransport, so we have to retrieve it again or risk losing data when writing
67 | // less than 512 bytes to the transport (see the comment there as well).
68 | // @see THRIFT-1579
69 | $protocol->writeMessageBegin('', TMessageType::REPLY, 0);
70 | $protocolTransport = $protocol->getTransport();
71 | $protocolTransport->write($string_object);
72 | $protocolTransport->flush();
73 |
74 | return thrift_protocol_read_binary($protocol, $class_name,
75 | $protocol->isStrictRead());
76 | } else {
77 | $transport->write($string_object);
78 | $object = new $class_name();
79 | $object->read($protocol);
80 |
81 | return $object;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Thrift/Server/TForkingServer.php:
--------------------------------------------------------------------------------
1 | transport_->listen();
40 |
41 | while (!$this->stop_) {
42 | try {
43 | $transport = $this->transport_->accept();
44 |
45 | if ($transport != null) {
46 | $pid = pcntl_fork();
47 |
48 | if ($pid > 0) {
49 | $this->handleParent($transport, $pid);
50 | } elseif ($pid === 0) {
51 | $this->handleChild($transport);
52 | } else {
53 | throw new TException('Failed to fork');
54 | }
55 | }
56 | } catch (TTransportException $e) { }
57 |
58 | $this->collectChildren();
59 | }
60 | }
61 |
62 | /**
63 | * Code run by the parent
64 | *
65 | * @param TTransport $transport
66 | * @param int $pid
67 | * @return void
68 | */
69 | private function handleParent(TTransport $transport, $pid)
70 | {
71 | $this->children_[$pid] = $transport;
72 | }
73 |
74 | /**
75 | * Code run by the child.
76 | *
77 | * @param TTransport $transport
78 | * @return void
79 | */
80 | private function handleChild(TTransport $transport)
81 | {
82 | try {
83 | $inputTransport = $this->inputTransportFactory_->getTransport($transport);
84 | $outputTransport = $this->outputTransportFactory_->getTransport($transport);
85 | $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport);
86 | $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport);
87 | while ($this->processor_->process($inputProtocol, $outputProtocol)) { }
88 | @$transport->close();
89 | } catch (TTransportException $e) { }
90 |
91 | exit(0);
92 | }
93 |
94 | /**
95 | * Collects any children we may have
96 | *
97 | * @return void
98 | */
99 | private function collectChildren()
100 | {
101 | foreach ($this->children_ as $pid => $transport) {
102 | if (pcntl_waitpid($pid, $status, WNOHANG) > 0) {
103 | unset($this->children_[$pid]);
104 | if ($transport) @$transport->close();
105 | }
106 | }
107 | }
108 |
109 | /**
110 | * Stops the server running. Kills the transport
111 | * and then stops the main serving loop
112 | *
113 | * @return void
114 | */
115 | public function stop()
116 | {
117 | $this->transport_->close();
118 | $this->stop_ = true;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Thrift/Server/TServer.php:
--------------------------------------------------------------------------------
1 | processor_ = $processor;
76 | $this->transport_ = $transport;
77 | $this->inputTransportFactory_ = $inputTransportFactory;
78 | $this->outputTransportFactory_ = $outputTransportFactory;
79 | $this->inputProtocolFactory_ = $inputProtocolFactory;
80 | $this->outputProtocolFactory_ = $outputProtocolFactory;
81 | }
82 |
83 | /**
84 | * Serves the server. This should never return
85 | * unless a problem permits it to do so or it
86 | * is interrupted intentionally
87 | *
88 | * @abstract
89 | * @return void
90 | */
91 | abstract public function serve();
92 |
93 | /**
94 | * Stops the server serving
95 | *
96 | * @abstract
97 | * @return void
98 | */
99 | abstract public function stop();
100 | }
101 |
--------------------------------------------------------------------------------
/Thrift/Server/TServerSocket.php:
--------------------------------------------------------------------------------
1 | host_ = $host;
52 | $this->port_ = $port;
53 | }
54 |
55 | /**
56 | * Sets the accept timeout
57 | *
58 | * @param int $acceptTimeout
59 | * @return void
60 | */
61 | public function setAcceptTimeout($acceptTimeout)
62 | {
63 | $this->acceptTimeout_ = $acceptTimeout;
64 | }
65 |
66 | /**
67 | * Opens a new socket server handle
68 | *
69 | * @return void
70 | */
71 | public function listen()
72 | {
73 | $this->listener_ = stream_socket_server('tcp://' . $this->host_ . ':' . $this->port_);
74 | }
75 |
76 | /**
77 | * Closes the socket server handle
78 | *
79 | * @return void
80 | */
81 | public function close()
82 | {
83 | @fclose($this->listener_);
84 | $this->listener_ = null;
85 | }
86 |
87 | /**
88 | * Implementation of accept. If not client is accepted in the given time
89 | *
90 | * @return TSocket
91 | */
92 | protected function acceptImpl()
93 | {
94 | $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0);
95 | if(!$handle) return null;
96 |
97 | $socket = new TSocket();
98 | $socket->setHandle($handle);
99 |
100 | return $socket;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Thrift/Server/TServerTransport.php:
--------------------------------------------------------------------------------
1 | acceptImpl();
49 |
50 | if ($transport == null) {
51 | throw new TTransportException("accept() may not return NULL");
52 | }
53 |
54 | return $transport;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Thrift/Server/TSimpleServer.php:
--------------------------------------------------------------------------------
1 | transport_->listen();
31 |
32 | while (!$this->stop_) {
33 | try {
34 | $transport = $this->transport_->accept();
35 |
36 | if ($transport != null) {
37 | $inputTransport = $this->inputTransportFactory_->getTransport($transport);
38 | $outputTransport = $this->outputTransportFactory_->getTransport($transport);
39 | $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport);
40 | $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport);
41 | while ($this->processor_->process($inputProtocol, $outputProtocol)) { }
42 | }
43 | } catch (TTransportException $e) { }
44 | }
45 | }
46 |
47 | /**
48 | * Stops the server running. Kills the transport
49 | * and then stops the main serving loop
50 | *
51 | * @return void
52 | */
53 | public function stop()
54 | {
55 | $this->transport_->close();
56 | $this->stop_ = true;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Thrift/StringFunc/Core.php:
--------------------------------------------------------------------------------
1 | strlen($str) - $start;
37 | }
38 |
39 | return mb_substr($str, $start, $length, '8bit');
40 | }
41 |
42 | public function strlen($str)
43 | {
44 | return mb_strlen($str, '8bit');
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Thrift/StringFunc/TStringFunc.php:
--------------------------------------------------------------------------------
1 | TMultiplexedProcessor is a Processor allowing
33 | * a single TServer
to provide multiple services.
34 | *
35 | *
To do so, you instantiate the processor and then register additional 36 | * processors with it, as shown in the following example:
37 | * 38 | *
39 | * $processor = new TMultiplexedProcessor();
40 | *
41 | * processor->registerProcessor(
42 | * "Calculator",
43 | * new \tutorial\CalculatorProcessor(new CalculatorHandler()));
44 | *
45 | * processor->registerProcessor(
46 | * "WeatherReport",
47 | * new \tutorial\WeatherReportProcessor(new WeatherReportHandler()));
48 | *
49 | * $processor->process($protocol, $protocol);
50 | *
51 | */
52 |
53 | class TMultiplexedProcessor
54 | {
55 | private $serviceProcessorMap_;
56 |
57 | /**
58 | * 'Register' a service with this TMultiplexedProcessor
. This
59 | * allows us to broker requests to individual services by using the service
60 | * name to select them at request time.
61 | *
62 | * @param serviceName Name of a service, has to be identical to the name
63 | * declared in the Thrift IDL, e.g. "WeatherReport".
64 | * @param processor Implementation of a service, usually referred to
65 | * as "handlers", e.g. WeatherReportHandler implementing WeatherReport.Iface.
66 | */
67 | public function registerProcessor($serviceName, $processor)
68 | {
69 | $this->serviceProcessorMap_[$serviceName] = $processor;
70 | }
71 |
72 | /**
73 | * This implementation of process
performs the following steps:
74 | *
75 | *