| 
<?phpnamespace GuzzleHttp\Psr7;
 
 use Psr\Http\Message\StreamInterface;
 
 /**
 * Stream decorator trait
 * @property StreamInterface stream
 */
 trait StreamDecoratorTrait
 {
 /**
 * @param StreamInterface $stream Stream to decorate
 */
 public function __construct(StreamInterface $stream)
 {
 $this->stream = $stream;
 }
 
 /**
 * Magic method used to create a new stream if streams are not added in
 * the constructor of a decorator (e.g., LazyOpenStream).
 *
 * @param string $name Name of the property (allows "stream" only).
 *
 * @return StreamInterface
 */
 public function __get($name)
 {
 if ($name == 'stream') {
 $this->stream = $this->createStream();
 return $this->stream;
 }
 
 throw new \UnexpectedValueException("$name not found on class");
 }
 
 public function __toString()
 {
 try {
 if ($this->isSeekable()) {
 $this->seek(0);
 }
 return $this->getContents();
 } catch (\Exception $e) {
 // Really, PHP? https://bugs.php.net/bug.php?id=53648
 trigger_error('StreamDecorator::__toString exception: '
 . (string) $e, E_USER_ERROR);
 return '';
 }
 }
 
 public function getContents()
 {
 return copy_to_string($this);
 }
 
 /**
 * Allow decorators to implement custom methods
 *
 * @param string $method Missing method name
 * @param array  $args   Method arguments
 *
 * @return mixed
 */
 public function __call($method, array $args)
 {
 $result = call_user_func_array([$this->stream, $method], $args);
 
 // Always return the wrapped object if the result is a return $this
 return $result === $this->stream ? $this : $result;
 }
 
 public function close()
 {
 $this->stream->close();
 }
 
 public function getMetadata($key = null)
 {
 return $this->stream->getMetadata($key);
 }
 
 public function detach()
 {
 return $this->stream->detach();
 }
 
 public function getSize()
 {
 return $this->stream->getSize();
 }
 
 public function eof()
 {
 return $this->stream->eof();
 }
 
 public function tell()
 {
 return $this->stream->tell();
 }
 
 public function isReadable()
 {
 return $this->stream->isReadable();
 }
 
 public function isWritable()
 {
 return $this->stream->isWritable();
 }
 
 public function isSeekable()
 {
 return $this->stream->isSeekable();
 }
 
 public function rewind()
 {
 $this->seek(0);
 }
 
 public function seek($offset, $whence = SEEK_SET)
 {
 $this->stream->seek($offset, $whence);
 }
 
 public function read($length)
 {
 return $this->stream->read($length);
 }
 
 public function write($string)
 {
 return $this->stream->write($string);
 }
 
 /**
 * Implement in subclasses to dynamically create streams when requested.
 *
 * @return StreamInterface
 * @throws \BadMethodCallException
 */
 protected function createStream()
 {
 throw new \BadMethodCallException('Not implemented');
 }
 }
 
 |