Viewing file: PumpStream.php (4.5 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
declare(strict_types=1);
namespace GuzzleHttp\Psr7;
use Psr\Http\Message\StreamInterface;
/** * Provides a read only stream that pumps data from a PHP callable. * * When invoking the provided callable, the PumpStream will pass the amount of * data requested to read to the callable. The callable can choose to ignore * this value and return fewer or more bytes than requested. Any extra data * returned by the provided callable is buffered internally until drained using * the read() function of the PumpStream. The provided callable MUST return * false when there is no more data to read. */ final class PumpStream implements StreamInterface { /** @var callable|null */ private $source;
/** @var int|null */ private $size;
/** @var int */ private $tellPos = 0;
/** @var array */ private $metadata;
/** @var BufferStream */ private $buffer;
/** * @param callable(int): (string|null|false) $source Source of the stream data. The callable MAY * accept an integer argument used to control the * amount of data to return. The callable MUST * return a string when called, or false|null on error * or EOF. * @param array{size?: int, metadata?: array} $options Stream options: * - metadata: Hash of metadata to use with stream. * - size: Size of the stream, if known. */ public function __construct(callable $source, array $options = []) { $this->source = $source; $this->size = $options['size'] ?? null; $this->metadata = $options['metadata'] ?? []; $this->buffer = new BufferStream(); }
public function __toString(): string { try { return Utils::copyToString($this); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); return ''; } }
public function close(): void { $this->detach(); }
public function detach() { $this->tellPos = 0; $this->source = null;
return null; }
public function getSize(): ?int { return $this->size; }
public function tell(): int { return $this->tellPos; }
public function eof(): bool { return $this->source === null; }
public function isSeekable(): bool { return false; }
public function rewind(): void { $this->seek(0); }
public function seek($offset, $whence = SEEK_SET): void { throw new \RuntimeException('Cannot seek a PumpStream'); }
public function isWritable(): bool { return false; }
public function write($string): int { throw new \RuntimeException('Cannot write to a PumpStream'); }
public function isReadable(): bool { return true; }
public function read($length): string { $data = $this->buffer->read($length); $readLen = strlen($data); $this->tellPos += $readLen; $remaining = $length - $readLen;
if ($remaining) { $this->pump($remaining); $data .= $this->buffer->read($remaining); $this->tellPos += strlen($data) - $readLen; }
return $data; }
public function getContents(): string { $result = ''; while (!$this->eof()) { $result .= $this->read(1000000); }
return $result; }
/** * {@inheritdoc} * * @return mixed */ public function getMetadata($key = null) { if (!$key) { return $this->metadata; }
return $this->metadata[$key] ?? null; }
private function pump(int $length): void { if ($this->source) { do { $data = call_user_func($this->source, $length); if ($data === false || $data === null) { $this->source = null; return; } $this->buffer->write($data); $length -= strlen($data); } while ($length > 0); } } }
|