function decode($response, array &$args, stdClass $context) { if ($context->oneway) { return null; } if (empty($response)) { throw new Exception("EOF"); } if ($response[strlen($response) - 1] !== Tags::TagEnd) { throw new Exception("Wrong Response: \r\n{$response}"); } $mode = $context->mode; if ($mode === ResultMode::RawWithEndTag) { return $response; } elseif ($mode === ResultMode::Raw) { return substr($response, 0, -1); } $stream = new BytesIO($response); $reader = new Reader($stream); $result = null; $tag = $stream->getc(); if ($tag === Tags::TagResult) { if ($mode === ResultMode::Normal) { $result = $reader->unserialize(); } elseif ($mode === ResultMode::Serialized) { $result = $reader->readRaw()->toString(); } $tag = $stream->getc(); if ($tag === Tags::TagArgument) { $reader->reset(); $arguments = $reader->readList(); $n = min(count($arguments), count($args)); for ($i = 0; $i < $n; $i++) { $args[$i] = $arguments[$i]; } $tag = $stream->getc(); } } elseif ($tag === Tags::TagError) { $e = new Exception($reader->readString()); $stream->close(); throw $e; } if ($tag !== Tags::TagEnd) { $stream->close(); throw new Exception("Wrong Response: \r\n{$response}"); } $stream->close(); return $result; }
private function doInput($response, &$args, $mode, $context) { $count = count($this->filters); for ($i = $count - 1; $i >= 0; $i--) { $response = $this->filters[$i]->inputFilter($response, $context); } if ($mode == ResultMode::RawWithEndTag) { return $response; } if ($mode == ResultMode::Raw) { return substr($response, 0, -1); } $stream = new BytesIO($response); $reader = new Reader($stream); $result = null; while (($tag = $stream->getc()) !== Tags::TagEnd) { switch ($tag) { case Tags::TagResult: if ($mode == ResultMode::Serialized) { $result = $reader->readRaw()->toString(); } else { $reader->reset(); $result = $reader->unserialize(); } break; case Tags::TagArgument: $reader->reset(); $_args = $reader->readList(); $n = min(count($_args), count($args)); for ($i = 0; $i < $n; $i++) { $args[$i] = $_args[$i]; } break; case Tags::TagError: $reader->reset(); throw new \Exception($reader->readString()); break; default: throw new \Exception("Wrong Response: \r\n" . $response); break; } } return $result; }
protected function doInvoke($input, $context) { $output = new BytesIO(); $reader = new Reader($input); do { $reader->reset(); $name = $reader->readString(); $alias = strtolower($name); if (isset($this->calls[$alias])) { $call = $this->calls[$alias]; } elseif (isset($this->calls['*'])) { $call = $this->calls['*']; } else { throw new \Exception("Can't find this function " . $name . "()."); } $mode = $call->mode; $simple = $call->simple; if ($simple === null) { $simple = $this->simple; } $args = array(); $byref = false; $async = $call->async; $tag = $input->getc(); if ($tag == Tags::TagList) { $reader->reset(); $args = $reader->readListWithoutTag(); $tag = $input->getc(); if ($tag == Tags::TagTrue) { $byref = true; $tag = $input->getc(); } if ($call->byref) { $_args = array(); foreach ($args as $i => &$arg) { if ($call->params[$i]->isPassedByReference()) { $_args[] =& $arg; } else { $_args[] = $arg; } } $args = $_args; } } if ($tag != Tags::TagEnd && $tag != Tags::TagCall) { throw new \Exception('Unknown tag: ' . $tag . "\r\n" . 'with following data: ' . $input->toString()); } if ($this->onBeforeInvoke !== null) { $beforeInvoke = $this->onBeforeInvoke; call_user_func_array($beforeInvoke, array($name, &$args, $byref, $context)); } if (array_key_exists('*', $this->calls) && $call === $this->calls['*']) { $args = array($name, $args); } if ($async) { $completer = new Completer(); $args[] = array(new AsyncCallback($completer), "handler"); call_user_func_array($call->func, $args); $result = $completer->future(); } else { $result = call_user_func_array($call->func, $args); } if ($result != null && $result instanceof Future) { $completer = new Completer(); $callback = new AfterInvokeCallback($this, $completer, $name, $args, $byref, $mode, $simple, $context); $result->then(array($callback, "handler"))->catchError(array($callback, "errorHandler")); return $completer->future(); } $result = $this->afterInvoke($name, $args, $byref, $mode, $simple, $context, $result, $output, false); if ($result != null) { return $result; } } while ($tag == Tags::TagCall); $output->write(Tags::TagEnd); return $this->outputFilter($output->toString(), $context); }
protected function doInvoke($input, $context) { $output = new BytesIO(); $reader = new Reader($input); do { $reader->reset(); $name = $reader->readString(); $alias = strtolower($name); if (isset($this->calls[$alias])) { $call = $this->calls[$alias]; } elseif (isset($this->calls['*'])) { $call = $this->calls['*']; } else { throw new \Exception("Can't find this function " . $name . "()."); } $mode = $call->mode; $simple = $call->simple; if ($simple === null) { $simple = $this->simple; } $args = array(); $byref = false; $tag = $input->getc(); if ($tag == Tags::TagList) { $reader->reset(); $args = $reader->readListWithoutTag(); $tag = $input->getc(); if ($tag == Tags::TagTrue) { $byref = true; $tag = $input->getc(); } if ($call->byref) { $_args = array(); foreach ($args as $i => &$arg) { if ($call->params[$i]->isPassedByReference()) { $_args[] =& $arg; } else { $_args[] = $arg; } } $args = $_args; } } if ($tag != Tags::TagEnd && $tag != Tags::TagCall) { throw new \Exception('Unknown tag: ' . $tag . "\r\n" . 'with following data: ' . $input->toString()); } if ($this->onBeforeInvoke !== null) { $beforeInvoke = $this->onBeforeInvoke; $beforeInvoke($name, $args, $byref, $context); } if (array_key_exists('*', $this->calls) && $call === $this->calls['*']) { $args = array($name, $args); } $result = call_user_func_array($call->func, $args); if ($this->onAfterInvoke !== null) { $afterInvoke = $this->onAfterInvoke; $afterInvoke($name, $args, $byref, $result, $context); } if ($mode == ResultMode::RawWithEndTag) { return $this->outputFilter($result, $context); } elseif ($mode == ResultMode::Raw) { $output->write($result); } else { $writer = new Writer($output, $simple); $output->write(Tags::TagResult); if ($mode == ResultMode::Serialized) { $output->write($result); } else { $writer->reset(); $writer->serialize($result); } if ($byref) { $output->write(Tags::TagArgument); $writer->reset(); $writer->writeArray($args); } } } while ($tag == Tags::TagCall); $output->write(Tags::TagEnd); return $this->outputFilter($output->toString(), $context); }
private function doInvoke(BytesIO $stream, stdClass $context) { $results = array(); $reader = new Reader($stream); do { $reader->reset(); $name = $reader->readString(); $alias = strtolower($name); $cc = new stdClass(); $cc->isMissingMethod = false; foreach ($context as $key => $value) { $cc->{$key} = $value; } if (isset($this->calls[$alias])) { $call = $this->calls[$alias]; } else { if (isset($this->calls['*'])) { $call = $this->calls['*']; $cc->isMissingMethod = true; } } if ($call) { foreach ($call as $key => $value) { $cc->{$key} = $value; } } $args = array(); $cc->byref = false; $tag = $stream->getc(); if ($tag === Tags::TagList) { $reader->reset(); $args = $reader->readListWithoutTag(); $tag = $stream->getc(); if ($tag === Tags::TagTrue) { $cc->byref = true; $tag = $stream->getc(); } } if ($tag !== Tags::TagEnd && $tag !== Tags::TagCall) { $data = $stream->toString(); throw new Exception("Unknown tag: {$tag}\r\nwith following data: {$data}"); } if ($call) { $results[] = $this->beforeInvoke($name, $args, $cc); } else { $results[] = $this->sendError(new Exception("Can\\'t find this function {$name}()."), $cc); } } while ($tag === Tags::TagCall); return reduce($results, function ($stream, $result) { $stream->write($result); return $stream; }, new BytesIO())->then(function ($stream) { $stream->write(Tags::TagEnd); $data = $stream->toString(); $stream->close(); return $data; }); }