contents, $this->offset, min($length, $this->chunkSize)); $this->offset += \strlen($chunk); return $chunk; } public function eof(): bool { return $this->offset >= \strlen($this->contents); } public function getSize(): ?int { return $this->advertiseSize ? \strlen($this->contents) : null; } public function isSeekable(): bool { return false; } public function __toString(): string { return $this->contents; } public function getContents(): string { return substr($this->contents, $this->offset); } public function close(): void { } public function detach() { return null; } public function tell(): int { return $this->offset; } public function seek(int $offset, int $whence = \SEEK_SET): void { throw new \RuntimeException('Not seekable.'); } public function rewind(): void { throw new \RuntimeException('Not seekable.'); } public function isWritable(): bool { return false; } public function write(string $string): int { throw new \RuntimeException('Not writable.'); } public function isReadable(): bool { return true; } public function getMetadata(?string $key = null) { return null === $key ? [] : null; } }