File indexing completed on 2024-12-29 05:27:23

0001 <?php
0002 namespace GuzzleHttp\Psr7;
0003 
0004 use Psr\Http\Message\StreamInterface;
0005 
0006 /**
0007  * Stream decorator trait
0008  * @property StreamInterface stream
0009  */
0010 trait StreamDecoratorTrait
0011 {
0012     /**
0013      * @param StreamInterface $stream Stream to decorate
0014      */
0015     public function __construct(StreamInterface $stream)
0016     {
0017         $this->stream = $stream;
0018     }
0019 
0020     /**
0021      * Magic method used to create a new stream if streams are not added in
0022      * the constructor of a decorator (e.g., LazyOpenStream).
0023      *
0024      * @param string $name Name of the property (allows "stream" only).
0025      *
0026      * @return StreamInterface
0027      */
0028     public function __get($name)
0029     {
0030         if ($name == 'stream') {
0031             $this->stream = $this->createStream();
0032             return $this->stream;
0033         }
0034 
0035         throw new \UnexpectedValueException("$name not found on class");
0036     }
0037 
0038     public function __toString()
0039     {
0040         try {
0041             if ($this->isSeekable()) {
0042                 $this->seek(0);
0043             }
0044             return $this->getContents();
0045         } catch (\Exception $e) {
0046             // Really, PHP? https://bugs.php.net/bug.php?id=53648
0047             trigger_error('StreamDecorator::__toString exception: '
0048                 . (string) $e, E_USER_ERROR);
0049             return '';
0050         }
0051     }
0052 
0053     public function getContents()
0054     {
0055         return copy_to_string($this);
0056     }
0057 
0058     /**
0059      * Allow decorators to implement custom methods
0060      *
0061      * @param string $method Missing method name
0062      * @param array  $args   Method arguments
0063      *
0064      * @return mixed
0065      */
0066     public function __call($method, array $args)
0067     {
0068         $result = call_user_func_array([$this->stream, $method], $args);
0069 
0070         // Always return the wrapped object if the result is a return $this
0071         return $result === $this->stream ? $this : $result;
0072     }
0073 
0074     public function close()
0075     {
0076         $this->stream->close();
0077     }
0078 
0079     public function getMetadata($key = null)
0080     {
0081         return $this->stream->getMetadata($key);
0082     }
0083 
0084     public function detach()
0085     {
0086         return $this->stream->detach();
0087     }
0088 
0089     public function getSize()
0090     {
0091         return $this->stream->getSize();
0092     }
0093 
0094     public function eof()
0095     {
0096         return $this->stream->eof();
0097     }
0098 
0099     public function tell()
0100     {
0101         return $this->stream->tell();
0102     }
0103 
0104     public function isReadable()
0105     {
0106         return $this->stream->isReadable();
0107     }
0108 
0109     public function isWritable()
0110     {
0111         return $this->stream->isWritable();
0112     }
0113 
0114     public function isSeekable()
0115     {
0116         return $this->stream->isSeekable();
0117     }
0118 
0119     public function rewind()
0120     {
0121         $this->seek(0);
0122     }
0123 
0124     public function seek($offset, $whence = SEEK_SET)
0125     {
0126         $this->stream->seek($offset, $whence);
0127     }
0128 
0129     public function read($length)
0130     {
0131         return $this->stream->read($length);
0132     }
0133 
0134     public function write($string)
0135     {
0136         return $this->stream->write($string);
0137     }
0138 
0139     /**
0140      * Implement in subclasses to dynamically create streams when requested.
0141      *
0142      * @return StreamInterface
0143      * @throws \BadMethodCallException
0144      */
0145     protected function createStream()
0146     {
0147         throw new \BadMethodCallException('Not implemented');
0148     }
0149 }