PageRenderTime 46ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/iwp-client/lib/amazon/guzzle/guzzle/src/Guzzle/Http/CachingEntityBody.php

https://gitlab.com/treighton/wpgit
PHP | 229 lines | 142 code | 38 blank | 49 comment | 16 complexity | 2230deb3e32e877ca3ef34c981ba0705 MD5 | raw file
  1. <?php
  2. namespace Guzzle\Http;
  3. use Guzzle\Common\Exception\RuntimeException;
  4. /**
  5. * EntityBody decorator that can cache previously read bytes from a sequentially read tstream
  6. */
  7. class CachingEntityBody extends AbstractEntityBodyDecorator
  8. {
  9. /** @var EntityBody Remote stream used to actually pull data onto the buffer */
  10. protected $remoteStream;
  11. /** @var int The number of bytes to skip reading due to a write on the temporary buffer */
  12. protected $skipReadBytes = 0;
  13. /**
  14. * We will treat the buffer object as the body of the entity body
  15. * {@inheritdoc}
  16. */
  17. public function __construct(EntityBodyInterface $body)
  18. {
  19. $this->remoteStream = $body;
  20. $this->body = new EntityBody(fopen('php://temp', 'r+'));
  21. }
  22. /**
  23. * Will give the contents of the buffer followed by the exhausted remote stream.
  24. *
  25. * Warning: Loads the entire stream into memory
  26. *
  27. * @return string
  28. */
  29. public function __toString()
  30. {
  31. $pos = $this->ftell();
  32. $this->rewind();
  33. $str = '';
  34. while (!$this->isConsumed()) {
  35. $str .= $this->read(16384);
  36. }
  37. $this->seek($pos);
  38. return $str;
  39. }
  40. public function getSize()
  41. {
  42. return max($this->body->getSize(), $this->remoteStream->getSize());
  43. }
  44. /**
  45. * {@inheritdoc}
  46. * @throws RuntimeException When seeking with SEEK_END or when seeking past the total size of the buffer stream
  47. */
  48. public function seek($offset, $whence = SEEK_SET)
  49. {
  50. if ($whence == SEEK_SET) {
  51. $byte = $offset;
  52. } elseif ($whence == SEEK_CUR) {
  53. $byte = $offset + $this->ftell();
  54. } else {
  55. throw new RuntimeException(__CLASS__ . ' supports only SEEK_SET and SEEK_CUR seek operations');
  56. }
  57. // You cannot skip ahead past where you've read from the remote stream
  58. if ($byte > $this->body->getSize()) {
  59. throw new RuntimeException(
  60. "Cannot seek to byte {$byte} when the buffered stream only contains {$this->body->getSize()} bytes"
  61. );
  62. }
  63. return $this->body->seek($byte);
  64. }
  65. public function rewind()
  66. {
  67. return $this->seek(0);
  68. }
  69. /**
  70. * Does not support custom rewind functions
  71. *
  72. * @throws RuntimeException
  73. */
  74. public function setRewindFunction($callable)
  75. {
  76. throw new RuntimeException(__CLASS__ . ' does not support custom stream rewind functions');
  77. }
  78. public function read($length)
  79. {
  80. // Perform a regular read on any previously read data from the buffer
  81. $data = $this->body->read($length);
  82. $remaining = $length - strlen($data);
  83. // More data was requested so read from the remote stream
  84. if ($remaining) {
  85. // If data was written to the buffer in a position that would have been filled from the remote stream,
  86. // then we must skip bytes on the remote stream to emulate overwriting bytes from that position. This
  87. // mimics the behavior of other PHP stream wrappers.
  88. $remoteData = $this->remoteStream->read($remaining + $this->skipReadBytes);
  89. if ($this->skipReadBytes) {
  90. $len = strlen($remoteData);
  91. $remoteData = substr($remoteData, $this->skipReadBytes);
  92. $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
  93. }
  94. $data .= $remoteData;
  95. $this->body->write($remoteData);
  96. }
  97. return $data;
  98. }
  99. public function write($string)
  100. {
  101. // When appending to the end of the currently read stream, you'll want to skip bytes from being read from
  102. // the remote stream to emulate other stream wrappers. Basically replacing bytes of data of a fixed length.
  103. $overflow = (strlen($string) + $this->ftell()) - $this->remoteStream->ftell();
  104. if ($overflow > 0) {
  105. $this->skipReadBytes += $overflow;
  106. }
  107. return $this->body->write($string);
  108. }
  109. /**
  110. * {@inheritdoc}
  111. * @link http://php.net/manual/en/function.fgets.php
  112. */
  113. public function readLine($maxLength = null)
  114. {
  115. $buffer = '';
  116. $size = 0;
  117. while (!$this->isConsumed()) {
  118. $byte = $this->read(1);
  119. $buffer .= $byte;
  120. // Break when a new line is found or the max length - 1 is reached
  121. if ($byte == PHP_EOL || ++$size == $maxLength - 1) {
  122. break;
  123. }
  124. }
  125. return $buffer;
  126. }
  127. public function isConsumed()
  128. {
  129. return $this->body->isConsumed() && $this->remoteStream->isConsumed();
  130. }
  131. /**
  132. * Close both the remote stream and buffer stream
  133. */
  134. public function close()
  135. {
  136. return $this->remoteStream->close() && $this->body->close();
  137. }
  138. public function setStream($stream, $size = 0)
  139. {
  140. $this->remoteStream->setStream($stream, $size);
  141. }
  142. public function getContentType()
  143. {
  144. return $this->remoteStream->getContentType();
  145. }
  146. public function getContentEncoding()
  147. {
  148. return $this->remoteStream->getContentEncoding();
  149. }
  150. public function getMetaData($key = null)
  151. {
  152. return $this->remoteStream->getMetaData($key);
  153. }
  154. public function getStream()
  155. {
  156. return $this->remoteStream->getStream();
  157. }
  158. public function getWrapper()
  159. {
  160. return $this->remoteStream->getWrapper();
  161. }
  162. public function getWrapperData()
  163. {
  164. return $this->remoteStream->getWrapperData();
  165. }
  166. public function getStreamType()
  167. {
  168. return $this->remoteStream->getStreamType();
  169. }
  170. public function getUri()
  171. {
  172. return $this->remoteStream->getUri();
  173. }
  174. /**
  175. * Always retrieve custom data from the remote stream
  176. * {@inheritdoc}
  177. */
  178. public function getCustomData($key)
  179. {
  180. return $this->remoteStream->getCustomData($key);
  181. }
  182. /**
  183. * Always set custom data on the remote stream
  184. * {@inheritdoc}
  185. */
  186. public function setCustomData($key, $value)
  187. {
  188. $this->remoteStream->setCustomData($key, $value);
  189. return $this;
  190. }
  191. }