PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/guzzlehttp/streams/src/Stream.php

https://gitlab.com/jhonn/rest
PHP | 236 lines | 159 code | 38 blank | 39 comment | 17 complexity | f8f0b12ec6efc49300f2a3530ec61c2c MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. namespace GuzzleHttp\Stream;
  3. /**
  4. * PHP stream implementation
  5. */
  6. class Stream implements MetadataStreamInterface
  7. {
  8. private $stream;
  9. private $size;
  10. private $seekable;
  11. private $readable;
  12. private $writable;
  13. private $uri;
  14. /** @var array Hash of readable and writable stream types */
  15. private static $readWriteHash = [
  16. 'read' => [
  17. 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
  18. 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
  19. 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
  20. 'x+t' => true, 'c+t' => true, 'a+' => true
  21. ],
  22. 'write' => [
  23. 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
  24. 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
  25. 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
  26. 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
  27. ]
  28. ];
  29. /**
  30. * Create a new stream based on the input type
  31. *
  32. * @param resource|string|StreamInterface $resource Entity body data
  33. * @param int $size Size of the data contained in the resource
  34. *
  35. * @return Stream
  36. * @throws \InvalidArgumentException if the $resource arg is not valid.
  37. */
  38. public static function factory($resource = '', $size = null)
  39. {
  40. $type = gettype($resource);
  41. if ($type == 'string') {
  42. $stream = fopen('php://temp', 'r+');
  43. if ($resource !== '') {
  44. fwrite($stream, $resource);
  45. fseek($stream, 0);
  46. }
  47. return new self($stream);
  48. }
  49. if ($type == 'resource') {
  50. return new self($resource, $size);
  51. }
  52. if ($resource instanceof StreamInterface) {
  53. return $resource;
  54. }
  55. if ($type == 'object' && method_exists($resource, '__toString')) {
  56. return self::factory((string) $resource, $size);
  57. }
  58. throw new \InvalidArgumentException('Invalid resource type: ' . $type);
  59. }
  60. /**
  61. * @param resource $stream Stream resource to wrap
  62. * @param int $size Size of the stream in bytes. Only pass if the
  63. * size cannot be obtained from the stream.
  64. *
  65. * @throws \InvalidArgumentException if the stream is not a stream resource
  66. */
  67. public function __construct($stream, $size = null)
  68. {
  69. if (!is_resource($stream)) {
  70. throw new \InvalidArgumentException('Stream must be a resource');
  71. }
  72. $this->size = $size;
  73. $this->stream = $stream;
  74. $meta = stream_get_meta_data($this->stream);
  75. $this->seekable = $meta['seekable'];
  76. $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
  77. $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
  78. $this->uri = isset($meta['uri']) ? $meta['uri'] : null;
  79. }
  80. /**
  81. * Closes the stream when the destructed
  82. */
  83. public function __destruct()
  84. {
  85. $this->close();
  86. }
  87. public function __toString()
  88. {
  89. if (!$this->stream) {
  90. return '';
  91. }
  92. $this->seek(0);
  93. return (string) stream_get_contents($this->stream);
  94. }
  95. public function getContents($maxLength = -1)
  96. {
  97. return $this->stream
  98. ? stream_get_contents($this->stream, $maxLength)
  99. : '';
  100. }
  101. public function close()
  102. {
  103. if (is_resource($this->stream)) {
  104. fclose($this->stream);
  105. }
  106. $this->detach();
  107. }
  108. public function detach()
  109. {
  110. $result = $this->stream;
  111. $this->stream = $this->size = $this->uri = null;
  112. $this->readable = $this->writable = $this->seekable = false;
  113. return $result;
  114. }
  115. public function getSize()
  116. {
  117. if ($this->size !== null) {
  118. return $this->size;
  119. }
  120. if (!$this->stream) {
  121. return null;
  122. }
  123. // Clear the stat cache if the stream has a URI
  124. if ($this->uri) {
  125. clearstatcache(true, $this->uri);
  126. }
  127. $stats = fstat($this->stream);
  128. if (isset($stats['size'])) {
  129. $this->size = $stats['size'];
  130. return $this->size;
  131. }
  132. return null;
  133. }
  134. public function isReadable()
  135. {
  136. return $this->readable;
  137. }
  138. public function isWritable()
  139. {
  140. return $this->writable;
  141. }
  142. public function isSeekable()
  143. {
  144. return $this->seekable;
  145. }
  146. public function eof()
  147. {
  148. return $this->stream && feof($this->stream);
  149. }
  150. public function tell()
  151. {
  152. return $this->stream ? ftell($this->stream) : false;
  153. }
  154. public function setSize($size)
  155. {
  156. $this->size = $size;
  157. return $this;
  158. }
  159. public function seek($offset, $whence = SEEK_SET)
  160. {
  161. return $this->seekable
  162. ? fseek($this->stream, $offset, $whence) === 0
  163. : false;
  164. }
  165. public function read($length)
  166. {
  167. return $this->readable ? fread($this->stream, $length) : '';
  168. }
  169. public function write($string)
  170. {
  171. // We can't know the size after writing anything
  172. $this->size = null;
  173. return $this->writable ? fwrite($this->stream, $string) : false;
  174. }
  175. public function flush()
  176. {
  177. return $this->stream ? fflush($this->stream) : false;
  178. }
  179. /**
  180. * Get stream metadata as an associative array or retrieve a specific key.
  181. *
  182. * The keys returned are identical to the keys returned from PHP's
  183. * stream_get_meta_data() function.
  184. *
  185. * @param string $key Specific metadata to retrieve.
  186. *
  187. * @return array|mixed|null Returns an associative array if no key is
  188. * no key is provided. Returns a specific key
  189. * value if a key is provided and the value is
  190. * found, or null if the key is not found.
  191. * @see http://php.net/manual/en/function.stream-get-meta-data.php
  192. */
  193. public function getMetadata($key = null)
  194. {
  195. $meta = $this->stream ? stream_get_meta_data($this->stream) : [];
  196. return !$key ? $meta : (isset($meta[$key]) ? $meta[$key] : null);
  197. }
  198. }