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();
 }
示例#2
0
 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'));
 }
示例#3
0
 public function __construct(ReadableStreamInterface $input)
 {
     $this->input = $input;
     $that = $this;
     $input->on('data', function ($data) use($that) {
         $that->emit('data', array($data, $that));
     });
     $input->on('error', function ($error) use($that) {
         $that->emit('error', array($error, $that));
     });
     $input->on('end', function () use($that) {
         $that->emit('end', array($that));
         $that->emit('close', array($that));
     });
     $input->on('close', function () use($that) {
         $that->emit('close', array($that));
     });
 }
示例#4
0
/**
 * 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 $multiplexed, $stderrEvent = null)
 {
     $this->multiplexed = $multiplexed;
     if ($stderrEvent === null) {
         $stderrEvent = 'data';
     }
     $this->stderrEvent = $stderrEvent;
     $out = $this;
     $buffer =& $this->buffer;
     $closed =& $this->closed;
     // pass all input data chunks through the parser
     $multiplexed->on('data', array($out, 'push'));
     // forward end event to output (unless parsing is still in progress)
     $multiplexed->on('end', function () use(&$buffer, $out, &$closed) {
         // ignore duplicate end events
         if ($closed) {
             return;
         }
         // buffer must be empty on end, otherwise this is an error situation
         if ($buffer === '') {
             $out->emit('end', array());
         } else {
             $out->emit('error', array(new \RuntimeException('Stream ended within incomplete multiplexed chunk')));
         }
         $out->close();
     });
     // forward error event to output
     $multiplexed->on('error', function ($error) use($out) {
         $out->emit('error', array($error));
         $out->close();
     });
     // forward close event to output
     $multiplexed->on('close', function ($error) use($out) {
         $out->close();
     });
 }
 public function close()
 {
     $this->closed = true;
     return $this->stream->close();
 }
示例#7
0
/**
 * Removes all given listeners from the stream
 *
 * @param Stream $stream
 * @param array  &$listeners
 */
function _remove_listeners(Stream $stream, array $listeners)
{
    foreach ($listeners as $event => $callable) {
        $stream->removeListener($event, $callable);
    }
}
 public static function createPromise(ReadableStreamInterface $stream)
 {
     $sink = new static();
     $stream->pipe($sink);
     return $sink->promise();
 }