/wp-content/plugins/iwp-client/lib/amazon/guzzle/guzzle/src/Guzzle/Http/CachingEntityBody.php
PHP | 229 lines | 142 code | 38 blank | 49 comment | 16 complexity | 2230deb3e32e877ca3ef34c981ba0705 MD5 | raw file
- <?php
-
- namespace Guzzle\Http;
-
- use Guzzle\Common\Exception\RuntimeException;
-
- /**
- * EntityBody decorator that can cache previously read bytes from a sequentially read tstream
- */
- class CachingEntityBody extends AbstractEntityBodyDecorator
- {
- /** @var EntityBody Remote stream used to actually pull data onto the buffer */
- protected $remoteStream;
-
- /** @var int The number of bytes to skip reading due to a write on the temporary buffer */
- protected $skipReadBytes = 0;
-
- /**
- * We will treat the buffer object as the body of the entity body
- * {@inheritdoc}
- */
- public function __construct(EntityBodyInterface $body)
- {
- $this->remoteStream = $body;
- $this->body = new EntityBody(fopen('php://temp', 'r+'));
- }
-
- /**
- * Will give the contents of the buffer followed by the exhausted remote stream.
- *
- * Warning: Loads the entire stream into memory
- *
- * @return string
- */
- public function __toString()
- {
- $pos = $this->ftell();
- $this->rewind();
-
- $str = '';
- while (!$this->isConsumed()) {
- $str .= $this->read(16384);
- }
-
- $this->seek($pos);
-
- return $str;
- }
-
- public function getSize()
- {
- return max($this->body->getSize(), $this->remoteStream->getSize());
- }
-
- /**
- * {@inheritdoc}
- * @throws RuntimeException When seeking with SEEK_END or when seeking past the total size of the buffer stream
- */
- public function seek($offset, $whence = SEEK_SET)
- {
- if ($whence == SEEK_SET) {
- $byte = $offset;
- } elseif ($whence == SEEK_CUR) {
- $byte = $offset + $this->ftell();
- } else {
- throw new RuntimeException(__CLASS__ . ' supports only SEEK_SET and SEEK_CUR seek operations');
- }
-
- // You cannot skip ahead past where you've read from the remote stream
- if ($byte > $this->body->getSize()) {
- throw new RuntimeException(
- "Cannot seek to byte {$byte} when the buffered stream only contains {$this->body->getSize()} bytes"
- );
- }
-
- return $this->body->seek($byte);
- }
-
- public function rewind()
- {
- return $this->seek(0);
- }
-
- /**
- * Does not support custom rewind functions
- *
- * @throws RuntimeException
- */
- public function setRewindFunction($callable)
- {
- throw new RuntimeException(__CLASS__ . ' does not support custom stream rewind functions');
- }
-
- public function read($length)
- {
- // Perform a regular read on any previously read data from the buffer
- $data = $this->body->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->body->write($remoteData);
- }
-
- return $data;
- }
-
- public function write($string)
- {
- // 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->ftell()) - $this->remoteStream->ftell();
- if ($overflow > 0) {
- $this->skipReadBytes += $overflow;
- }
-
- return $this->body->write($string);
- }
-
- /**
- * {@inheritdoc}
- * @link http://php.net/manual/en/function.fgets.php
- */
- public function readLine($maxLength = null)
- {
- $buffer = '';
- $size = 0;
- while (!$this->isConsumed()) {
- $byte = $this->read(1);
- $buffer .= $byte;
- // Break when a new line is found or the max length - 1 is reached
- if ($byte == PHP_EOL || ++$size == $maxLength - 1) {
- break;
- }
- }
-
- return $buffer;
- }
-
- public function isConsumed()
- {
- return $this->body->isConsumed() && $this->remoteStream->isConsumed();
- }
-
- /**
- * Close both the remote stream and buffer stream
- */
- public function close()
- {
- return $this->remoteStream->close() && $this->body->close();
- }
-
- public function setStream($stream, $size = 0)
- {
- $this->remoteStream->setStream($stream, $size);
- }
-
- public function getContentType()
- {
- return $this->remoteStream->getContentType();
- }
-
- public function getContentEncoding()
- {
- return $this->remoteStream->getContentEncoding();
- }
-
- public function getMetaData($key = null)
- {
- return $this->remoteStream->getMetaData($key);
- }
-
- public function getStream()
- {
- return $this->remoteStream->getStream();
- }
-
- public function getWrapper()
- {
- return $this->remoteStream->getWrapper();
- }
-
- public function getWrapperData()
- {
- return $this->remoteStream->getWrapperData();
- }
-
- public function getStreamType()
- {
- return $this->remoteStream->getStreamType();
- }
-
- public function getUri()
- {
- return $this->remoteStream->getUri();
- }
-
- /**
- * Always retrieve custom data from the remote stream
- * {@inheritdoc}
- */
- public function getCustomData($key)
- {
- return $this->remoteStream->getCustomData($key);
- }
-
- /**
- * Always set custom data on the remote stream
- * {@inheritdoc}
- */
- public function setCustomData($key, $value)
- {
- $this->remoteStream->setCustomData($key, $value);
-
- return $this;
- }
- }