namespace Symfony\Component\Process\Pipes;
+use Symfony\Component\Process\Exception\InvalidArgumentException;
+
/**
* @author Romain Neutron <imprec@gmail.com>
*
/** @var string */
private $inputBuffer = '';
- /** @var resource|null */
+ /** @var resource|scalar|\Iterator|null */
private $input;
/** @var bool */
private $blocked = true;
public function __construct($input)
{
- if (is_resource($input)) {
+ if (is_resource($input) || $input instanceof \Iterator) {
$this->input = $input;
} elseif (is_string($input)) {
$this->inputBuffer = $input;
foreach ($this->pipes as $pipe) {
stream_set_blocking($pipe, 0);
}
- if (null !== $this->input) {
+ if (is_resource($this->input)) {
stream_set_blocking($this->input, 0);
}
/**
* Writes input to stdin.
+ *
+ * @throws InvalidArgumentException When an input iterator yields a non supported value
*/
protected function write()
{
return;
}
$input = $this->input;
+
+ if ($input instanceof \Iterator) {
+ if (!$input->valid()) {
+ $input = null;
+ } elseif (is_resource($input = $input->current())) {
+ stream_set_blocking($input, 0);
+ } elseif (!isset($this->inputBuffer[0])) {
+ if (!is_string($input)) {
+ if (!is_scalar($input)) {
+ throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported', get_class($this->input), gettype($input)));
+ }
+ $input = (string) $input;
+ }
+ $this->inputBuffer = $input;
+ $this->input->next();
+ $input = null;
+ } else {
+ $input = null;
+ }
+ }
+
$r = $e = array();
$w = array($this->pipes[0]);
}
}
if (feof($input)) {
- // no more data to read on input resource
- // use an empty buffer in the next reads
- $this->input = null;
+ if ($this->input instanceof \Iterator) {
+ $this->input->next();
+ } else {
+ $this->input = null;
+ }
}
}
}
// no input to read on resource, buffer is empty
- if (null === $this->input && !isset($this->inputBuffer[0])) {
+ if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) {
+ $this->input = null;
fclose($this->pipes[0]);
unset($this->pipes[0]);
} elseif (!$w) {