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  * Converts Guzzle streams into PHP stream resources.
0008  */
0009 class StreamWrapper
0010 {
0011     /** @var resource */
0012     public $context;
0013 
0014     /** @var StreamInterface */
0015     private $stream;
0016 
0017     /** @var string r, r+, or w */
0018     private $mode;
0019 
0020     /**
0021      * Returns a resource representing the stream.
0022      *
0023      * @param StreamInterface $stream The stream to get a resource for
0024      *
0025      * @return resource
0026      * @throws \InvalidArgumentException if stream is not readable or writable
0027      */
0028     public static function getResource(StreamInterface $stream)
0029     {
0030         self::register();
0031 
0032         if ($stream->isReadable()) {
0033             $mode = $stream->isWritable() ? 'r+' : 'r';
0034         } elseif ($stream->isWritable()) {
0035             $mode = 'w';
0036         } else {
0037             throw new \InvalidArgumentException('The stream must be readable, '
0038                 . 'writable, or both.');
0039         }
0040 
0041         return fopen('guzzle://stream', $mode, null, stream_context_create([
0042             'guzzle' => ['stream' => $stream]
0043         ]));
0044     }
0045 
0046     /**
0047      * Registers the stream wrapper if needed
0048      */
0049     public static function register()
0050     {
0051         if (!in_array('guzzle', stream_get_wrappers())) {
0052             stream_wrapper_register('guzzle', __CLASS__);
0053         }
0054     }
0055 
0056     public function stream_open($path, $mode, $options, &$opened_path)
0057     {
0058         $options = stream_context_get_options($this->context);
0059 
0060         if (!isset($options['guzzle']['stream'])) {
0061             return false;
0062         }
0063 
0064         $this->mode = $mode;
0065         $this->stream = $options['guzzle']['stream'];
0066 
0067         return true;
0068     }
0069 
0070     public function stream_read($count)
0071     {
0072         return $this->stream->read($count);
0073     }
0074 
0075     public function stream_write($data)
0076     {
0077         return (int) $this->stream->write($data);
0078     }
0079 
0080     public function stream_tell()
0081     {
0082         return $this->stream->tell();
0083     }
0084 
0085     public function stream_eof()
0086     {
0087         return $this->stream->eof();
0088     }
0089 
0090     public function stream_seek($offset, $whence)
0091     {
0092         $this->stream->seek($offset, $whence);
0093 
0094         return true;
0095     }
0096 
0097     public function stream_stat()
0098     {
0099         static $modeMap = [
0100             'r'  => 33060,
0101             'r+' => 33206,
0102             'w'  => 33188
0103         ];
0104 
0105         return [
0106             'dev'     => 0,
0107             'ino'     => 0,
0108             'mode'    => $modeMap[$this->mode],
0109             'nlink'   => 0,
0110             'uid'     => 0,
0111             'gid'     => 0,
0112             'rdev'    => 0,
0113             'size'    => $this->stream->getSize() ?: 0,
0114             'atime'   => 0,
0115             'mtime'   => 0,
0116             'ctime'   => 0,
0117             'blksize' => 0,
0118             'blocks'  => 0
0119         ];
0120     }
0121 }