primo commit
This commit is contained in:
		
							
								
								
									
										153
									
								
								libraries/vendor/guzzlehttp/psr7/src/CachingStream.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								libraries/vendor/guzzlehttp/psr7/src/CachingStream.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,153 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace GuzzleHttp\Psr7; | ||||
|  | ||||
| use Psr\Http\Message\StreamInterface; | ||||
|  | ||||
| /** | ||||
|  * Stream decorator that can cache previously read bytes from a sequentially | ||||
|  * read stream. | ||||
|  */ | ||||
| final class CachingStream implements StreamInterface | ||||
| { | ||||
|     use StreamDecoratorTrait; | ||||
|  | ||||
|     /** @var StreamInterface Stream being wrapped */ | ||||
|     private $remoteStream; | ||||
|  | ||||
|     /** @var int Number of bytes to skip reading due to a write on the buffer */ | ||||
|     private $skipReadBytes = 0; | ||||
|  | ||||
|     /** | ||||
|      * @var StreamInterface | ||||
|      */ | ||||
|     private $stream; | ||||
|  | ||||
|     /** | ||||
|      * We will treat the buffer object as the body of the stream | ||||
|      * | ||||
|      * @param StreamInterface $stream Stream to cache. The cursor is assumed to be at the beginning of the stream. | ||||
|      * @param StreamInterface $target Optionally specify where data is cached | ||||
|      */ | ||||
|     public function __construct( | ||||
|         StreamInterface $stream, | ||||
|         ?StreamInterface $target = null | ||||
|     ) { | ||||
|         $this->remoteStream = $stream; | ||||
|         $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+')); | ||||
|     } | ||||
|  | ||||
|     public function getSize(): ?int | ||||
|     { | ||||
|         $remoteSize = $this->remoteStream->getSize(); | ||||
|  | ||||
|         if (null === $remoteSize) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return max($this->stream->getSize(), $remoteSize); | ||||
|     } | ||||
|  | ||||
|     public function rewind(): void | ||||
|     { | ||||
|         $this->seek(0); | ||||
|     } | ||||
|  | ||||
|     public function seek($offset, $whence = SEEK_SET): void | ||||
|     { | ||||
|         if ($whence === SEEK_SET) { | ||||
|             $byte = $offset; | ||||
|         } elseif ($whence === SEEK_CUR) { | ||||
|             $byte = $offset + $this->tell(); | ||||
|         } elseif ($whence === SEEK_END) { | ||||
|             $size = $this->remoteStream->getSize(); | ||||
|             if ($size === null) { | ||||
|                 $size = $this->cacheEntireStream(); | ||||
|             } | ||||
|             $byte = $size + $offset; | ||||
|         } else { | ||||
|             throw new \InvalidArgumentException('Invalid whence'); | ||||
|         } | ||||
|  | ||||
|         $diff = $byte - $this->stream->getSize(); | ||||
|  | ||||
|         if ($diff > 0) { | ||||
|             // Read the remoteStream until we have read in at least the amount | ||||
|             // of bytes requested, or we reach the end of the file. | ||||
|             while ($diff > 0 && !$this->remoteStream->eof()) { | ||||
|                 $this->read($diff); | ||||
|                 $diff = $byte - $this->stream->getSize(); | ||||
|             } | ||||
|         } else { | ||||
|             // We can just do a normal seek since we've already seen this byte. | ||||
|             $this->stream->seek($byte); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function read($length): string | ||||
|     { | ||||
|         // Perform a regular read on any previously read data from the buffer | ||||
|         $data = $this->stream->read($length); | ||||
|         $remaining = $length - strlen($data); | ||||
|  | ||||
|         // More data was requested so read from the remote stream | ||||
|         if ($remaining) { | ||||
|             // If data was written to the buffer in a position that would have | ||||
|             // been filled from the remote stream, then we must skip bytes on | ||||
|             // the remote stream to emulate overwriting bytes from that | ||||
|             // position. This mimics the behavior of other PHP stream wrappers. | ||||
|             $remoteData = $this->remoteStream->read( | ||||
|                 $remaining + $this->skipReadBytes | ||||
|             ); | ||||
|  | ||||
|             if ($this->skipReadBytes) { | ||||
|                 $len = strlen($remoteData); | ||||
|                 $remoteData = substr($remoteData, $this->skipReadBytes); | ||||
|                 $this->skipReadBytes = max(0, $this->skipReadBytes - $len); | ||||
|             } | ||||
|  | ||||
|             $data .= $remoteData; | ||||
|             $this->stream->write($remoteData); | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     public function write($string): int | ||||
|     { | ||||
|         // When appending to the end of the currently read stream, you'll want | ||||
|         // to skip bytes from being read from the remote stream to emulate | ||||
|         // other stream wrappers. Basically replacing bytes of data of a fixed | ||||
|         // length. | ||||
|         $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell(); | ||||
|         if ($overflow > 0) { | ||||
|             $this->skipReadBytes += $overflow; | ||||
|         } | ||||
|  | ||||
|         return $this->stream->write($string); | ||||
|     } | ||||
|  | ||||
|     public function eof(): bool | ||||
|     { | ||||
|         return $this->stream->eof() && $this->remoteStream->eof(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Close both the remote stream and buffer stream | ||||
|      */ | ||||
|     public function close(): void | ||||
|     { | ||||
|         $this->remoteStream->close(); | ||||
|         $this->stream->close(); | ||||
|     } | ||||
|  | ||||
|     private function cacheEntireStream(): int | ||||
|     { | ||||
|         $target = new FnStream(['write' => 'strlen']); | ||||
|         Utils::copyToStream($this, $target); | ||||
|  | ||||
|         return $this->tell(); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user