1 <?php 2 3 declare(strict_types=1); 4 5 namespace GuzzleHttp\Psr7; 6 7 use Psr\Http\Message\StreamInterface; 8 9 /** 10 * Stream decorator trait 11 * 12 * @property StreamInterface $stream 13 */ 14 trait StreamDecoratorTrait 15 { 16 /** 17 * @param StreamInterface $stream Stream to decorate 18 */ 19 public function __construct(StreamInterface $stream) 20 { 21 $this->stream = $stream; 22 } 23 24 /** 25 * Magic method used to create a new stream if streams are not added in 26 * the constructor of a decorator (e.g., LazyOpenStream). 27 * 28 * @return StreamInterface 29 */ 30 public function __get(string $name) 31 { 32 if ($name === 'stream') { 33 $this->stream = $this->createStream(); 34 return $this->stream; 35 } 36 37 throw new \UnexpectedValueException("$name not found on class"); 38 } 39 40 public function __toString(): string 41 { 42 try { 43 if ($this->isSeekable()) { 44 $this->seek(0); 45 } 46 return $this->getContents(); 47 } catch (\Throwable $e) { 48 if (\PHP_VERSION_ID >= 70400) { 49 throw $e; 50 } 51 trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); 52 return ''; 53 } 54 } 55 56 public function getContents(): string 57 { 58 return Utils::copyToString($this); 59 } 60 61 /** 62 * Allow decorators to implement custom methods 63 * 64 * @return mixed 65 */ 66 public function __call(string $method, array $args) 67 { 68 /** @var callable $callable */ 69 $callable = [$this->stream, $method]; 70 $result = call_user_func_array($callable, $args); 71 72 // Always return the wrapped object if the result is a return $this 73 return $result === $this->stream ? $this : $result; 74 } 75 76 public function close(): void 77 { 78 $this->stream->close(); 79 } 80 81 /** 82 * {@inheritdoc} 83 * 84 * @return mixed 85 */ 86 public function getMetadata($key = null) 87 { 88 return $this->stream->getMetadata($key); 89 } 90 91 public function detach() 92 { 93 return $this->stream->detach(); 94 } 95 96 public function getSize(): ?int 97 { 98 return $this->stream->getSize(); 99 } 100 101 public function eof(): bool 102 { 103 return $this->stream->eof(); 104 } 105 106 public function tell(): int 107 { 108 return $this->stream->tell(); 109 } 110 111 public function isReadable(): bool 112 { 113 return $this->stream->isReadable(); 114 } 115 116 public function isWritable(): bool 117 { 118 return $this->stream->isWritable(); 119 } 120 121 public function isSeekable(): bool 122 { 123 return $this->stream->isSeekable(); 124 } 125 126 public function rewind(): void 127 { 128 $this->seek(0); 129 } 130 131 public function seek($offset, $whence = SEEK_SET): void 132 { 133 $this->stream->seek($offset, $whence); 134 } 135 136 public function read($length): string 137 { 138 return $this->stream->read($length); 139 } 140 141 public function write($string): int 142 { 143 return $this->stream->write($string); 144 } 145 146 /** 147 * Implement in subclasses to dynamically create streams when requested. 148 * 149 * @throws \BadMethodCallException 150 */ 151 protected function createStream(): StreamInterface 152 { 153 throw new \BadMethodCallException('Not implemented'); 154 } 155 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body