public function deferredStream(ReadableStreamInterface $stream, $progressEventName) { // cancelling the deferred will (try to) close the stream $deferred = new Deferred(function () use($stream) { $stream->close(); throw new RuntimeException('Cancelled'); }); if ($stream->isReadable()) { // buffer all data events for deferred resolving $buffered = array(); $stream->on($progressEventName, function ($data) use(&$buffered) { $buffered[] = $data; }); // error event rejects $stream->on('error', function ($error) use($deferred) { $deferred->reject($error); }); // close event resolves with buffered events (unless already error'ed) $stream->on('close', function () use($deferred, &$buffered) { $deferred->resolve($buffered); }); } else { $deferred->reject(new RuntimeException('Stream already ended, looks like it could not be opened')); } return $deferred->promise(); }
/** * Creates a `Promise` which resolves with the stream data buffer * * @param ReadableStreamInterface $stream * @return CancellablePromiseInterface Promise<string, Exception> */ function buffer(ReadableStreamInterface $stream) { // stream already ended => resolve with empty buffer if (!$stream->isReadable()) { return Promise\resolve(''); } $buffer = ''; $bufferer = function ($data) use(&$buffer) { $buffer .= $data; }; $stream->on('data', $bufferer); $promise = new Promise\Promise(function ($resolve, $reject) use($stream, &$buffer) { $stream->on('error', function ($error) use($reject) { $reject(new \RuntimeException('An error occured on the underlying stream while buffering', 0, $error)); }); $stream->on('close', function () use($resolve, &$buffer) { $resolve($buffer); }); }, function ($_, $reject) { $reject(new \RuntimeException('Cancelled buffering')); }); return $promise->then(null, function ($error) use(&$buffer, $bufferer, $stream) { // promise rejected => clear buffer and buffering $buffer = ''; $stream->removeListener('data', $bufferer); throw $error; }); }
public function __construct(ReadableStreamInterface $input, $replacementCharacter = '?') { $this->input = $input; $this->invalid = $replacementCharacter; if (!$input->isReadable()) { return $this->close(); } $this->input->on('data', array($this, 'handleData')); $this->input->on('end', array($this, 'handleEnd')); $this->input->on('error', array($this, 'handleError')); $this->input->on('close', array($this, 'close')); }
public function isReadable() { return $this->stream->isReadable(); }