You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.4 KiB
99 lines
2.4 KiB
<?php |
|
|
|
/* |
|
* This file is part of the Symfony package. |
|
* |
|
* (c) Fabien Potencier <fabien@symfony.com> |
|
* |
|
* For the full copyright and license information, please view the LICENSE |
|
* file that was distributed with this source code. |
|
*/ |
|
|
|
namespace Symfony\Component\Process; |
|
|
|
use Symfony\Component\Process\Exception\RuntimeException; |
|
|
|
/** |
|
* Provides a way to continuously write to the input of a Process until the InputStream is closed. |
|
* |
|
* @author Nicolas Grekas <p@tchwork.com> |
|
* |
|
* @implements \IteratorAggregate<int, string> |
|
*/ |
|
class InputStream implements \IteratorAggregate |
|
{ |
|
private ?\Closure $onEmpty = null; |
|
private array $input = []; |
|
private bool $open = true; |
|
|
|
/** |
|
* Sets a callback that is called when the write buffer becomes empty. |
|
* |
|
* @return void |
|
*/ |
|
public function onEmpty(?callable $onEmpty = null) |
|
{ |
|
$this->onEmpty = null !== $onEmpty ? $onEmpty(...) : null; |
|
} |
|
|
|
/** |
|
* Appends an input to the write buffer. |
|
* |
|
* @param resource|string|int|float|bool|\Traversable|null $input The input to append as scalar, |
|
* stream resource or \Traversable |
|
* |
|
* @return void |
|
*/ |
|
public function write(mixed $input) |
|
{ |
|
if (null === $input) { |
|
return; |
|
} |
|
if ($this->isClosed()) { |
|
throw new RuntimeException(sprintf('"%s" is closed.', static::class)); |
|
} |
|
$this->input[] = ProcessUtils::validateInput(__METHOD__, $input); |
|
} |
|
|
|
/** |
|
* Closes the write buffer. |
|
* |
|
* @return void |
|
*/ |
|
public function close() |
|
{ |
|
$this->open = false; |
|
} |
|
|
|
/** |
|
* Tells whether the write buffer is closed or not. |
|
* |
|
* @return bool |
|
*/ |
|
public function isClosed() |
|
{ |
|
return !$this->open; |
|
} |
|
|
|
public function getIterator(): \Traversable |
|
{ |
|
$this->open = true; |
|
|
|
while ($this->open || $this->input) { |
|
if (!$this->input) { |
|
yield ''; |
|
continue; |
|
} |
|
$current = array_shift($this->input); |
|
|
|
if ($current instanceof \Iterator) { |
|
yield from $current; |
|
} else { |
|
yield $current; |
|
} |
|
if (!$this->input && $this->open && null !== $onEmpty = $this->onEmpty) { |
|
$this->write($onEmpty($this)); |
|
} |
|
} |
|
} |
|
}
|
|
|