104fd306cSNickeau<?php 204fd306cSNickeau 304fd306cSNickeau/* 404fd306cSNickeau * This file is part of the Symfony package. 504fd306cSNickeau * 604fd306cSNickeau * (c) Fabien Potencier <fabien@symfony.com> 704fd306cSNickeau * 804fd306cSNickeau * For the full copyright and license information, please view the LICENSE 904fd306cSNickeau * file that was distributed with this source code. 1004fd306cSNickeau */ 1104fd306cSNickeau 1204fd306cSNickeaunamespace Symfony\Component\Process; 1304fd306cSNickeau 1404fd306cSNickeauuse Symfony\Component\Process\Exception\RuntimeException; 1504fd306cSNickeau 1604fd306cSNickeau/** 1704fd306cSNickeau * Provides a way to continuously write to the input of a Process until the InputStream is closed. 1804fd306cSNickeau * 1904fd306cSNickeau * @author Nicolas Grekas <p@tchwork.com> 2004fd306cSNickeau * 2104fd306cSNickeau * @implements \IteratorAggregate<int, string> 2204fd306cSNickeau */ 2304fd306cSNickeauclass InputStream implements \IteratorAggregate 2404fd306cSNickeau{ 2504fd306cSNickeau /** @var callable|null */ 2604fd306cSNickeau private $onEmpty = null; 2704fd306cSNickeau private $input = []; 2804fd306cSNickeau private $open = true; 2904fd306cSNickeau 3004fd306cSNickeau /** 3104fd306cSNickeau * Sets a callback that is called when the write buffer becomes empty. 3204fd306cSNickeau */ 33*83c68632SNico public function onEmpty(?callable $onEmpty = null) 3404fd306cSNickeau { 3504fd306cSNickeau $this->onEmpty = $onEmpty; 3604fd306cSNickeau } 3704fd306cSNickeau 3804fd306cSNickeau /** 3904fd306cSNickeau * Appends an input to the write buffer. 4004fd306cSNickeau * 4104fd306cSNickeau * @param resource|string|int|float|bool|\Traversable|null $input The input to append as scalar, 4204fd306cSNickeau * stream resource or \Traversable 4304fd306cSNickeau */ 4404fd306cSNickeau public function write($input) 4504fd306cSNickeau { 4604fd306cSNickeau if (null === $input) { 4704fd306cSNickeau return; 4804fd306cSNickeau } 4904fd306cSNickeau if ($this->isClosed()) { 5004fd306cSNickeau throw new RuntimeException(sprintf('"%s" is closed.', static::class)); 5104fd306cSNickeau } 5204fd306cSNickeau $this->input[] = ProcessUtils::validateInput(__METHOD__, $input); 5304fd306cSNickeau } 5404fd306cSNickeau 5504fd306cSNickeau /** 5604fd306cSNickeau * Closes the write buffer. 5704fd306cSNickeau */ 5804fd306cSNickeau public function close() 5904fd306cSNickeau { 6004fd306cSNickeau $this->open = false; 6104fd306cSNickeau } 6204fd306cSNickeau 6304fd306cSNickeau /** 6404fd306cSNickeau * Tells whether the write buffer is closed or not. 6504fd306cSNickeau */ 6604fd306cSNickeau public function isClosed() 6704fd306cSNickeau { 6804fd306cSNickeau return !$this->open; 6904fd306cSNickeau } 7004fd306cSNickeau 7104fd306cSNickeau /** 7204fd306cSNickeau * @return \Traversable<int, string> 7304fd306cSNickeau */ 7404fd306cSNickeau #[\ReturnTypeWillChange] 7504fd306cSNickeau public function getIterator() 7604fd306cSNickeau { 7704fd306cSNickeau $this->open = true; 7804fd306cSNickeau 7904fd306cSNickeau while ($this->open || $this->input) { 8004fd306cSNickeau if (!$this->input) { 8104fd306cSNickeau yield ''; 8204fd306cSNickeau continue; 8304fd306cSNickeau } 8404fd306cSNickeau $current = array_shift($this->input); 8504fd306cSNickeau 8604fd306cSNickeau if ($current instanceof \Iterator) { 8704fd306cSNickeau yield from $current; 8804fd306cSNickeau } else { 8904fd306cSNickeau yield $current; 9004fd306cSNickeau } 9104fd306cSNickeau if (!$this->input && $this->open && null !== $onEmpty = $this->onEmpty) { 9204fd306cSNickeau $this->write($onEmpty($this)); 9304fd306cSNickeau } 9404fd306cSNickeau } 9504fd306cSNickeau } 9604fd306cSNickeau} 97