PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/zendframework/zend-diactoros/src/Stream.php

https://gitlab.com/reasonat/test8
PHP | 328 lines | 194 code | 52 blank | 82 comment | 32 complexity | 5c90c66f074fd76093b6a80f3028b417 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @see http://github.com/zendframework/zend-diactoros for the canonical source repository
  6. * @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
  8. */
  9. namespace Zend\Diactoros;
  10. use InvalidArgumentException;
  11. use RuntimeException;
  12. use Psr\Http\Message\StreamInterface;
  13. /**
  14. * Implementation of PSR HTTP streams
  15. */
  16. class Stream implements StreamInterface
  17. {
  18. /**
  19. * @var resource
  20. */
  21. protected $resource;
  22. /**
  23. * @var string|resource
  24. */
  25. protected $stream;
  26. /**
  27. * @param string|resource $stream
  28. * @param string $mode Mode with which to open stream
  29. * @throws InvalidArgumentException
  30. */
  31. public function __construct($stream, $mode = 'r')
  32. {
  33. $this->setStream($stream, $mode);
  34. }
  35. /**
  36. * {@inheritdoc}
  37. */
  38. public function __toString()
  39. {
  40. if (! $this->isReadable()) {
  41. return '';
  42. }
  43. try {
  44. $this->rewind();
  45. return $this->getContents();
  46. } catch (RuntimeException $e) {
  47. return '';
  48. }
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. public function close()
  54. {
  55. if (! $this->resource) {
  56. return;
  57. }
  58. $resource = $this->detach();
  59. fclose($resource);
  60. }
  61. /**
  62. * {@inheritdoc}
  63. */
  64. public function detach()
  65. {
  66. $resource = $this->resource;
  67. $this->resource = null;
  68. return $resource;
  69. }
  70. /**
  71. * Attach a new stream/resource to the instance.
  72. *
  73. * @param string|resource $resource
  74. * @param string $mode
  75. * @throws InvalidArgumentException for stream identifier that cannot be
  76. * cast to a resource
  77. * @throws InvalidArgumentException for non-resource stream
  78. */
  79. public function attach($resource, $mode = 'r')
  80. {
  81. $this->setStream($resource, $mode);
  82. }
  83. /**
  84. * {@inheritdoc}
  85. */
  86. public function getSize()
  87. {
  88. if (null === $this->resource) {
  89. return null;
  90. }
  91. $stats = fstat($this->resource);
  92. return $stats['size'];
  93. }
  94. /**
  95. * {@inheritdoc}
  96. */
  97. public function tell()
  98. {
  99. if (! $this->resource) {
  100. throw new RuntimeException('No resource available; cannot tell position');
  101. }
  102. $result = ftell($this->resource);
  103. if (! is_int($result)) {
  104. throw new RuntimeException('Error occurred during tell operation');
  105. }
  106. return $result;
  107. }
  108. /**
  109. * {@inheritdoc}
  110. */
  111. public function eof()
  112. {
  113. if (! $this->resource) {
  114. return true;
  115. }
  116. return feof($this->resource);
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. public function isSeekable()
  122. {
  123. if (! $this->resource) {
  124. return false;
  125. }
  126. $meta = stream_get_meta_data($this->resource);
  127. return $meta['seekable'];
  128. }
  129. /**
  130. * {@inheritdoc}
  131. */
  132. public function seek($offset, $whence = SEEK_SET)
  133. {
  134. if (! $this->resource) {
  135. throw new RuntimeException('No resource available; cannot seek position');
  136. }
  137. if (! $this->isSeekable()) {
  138. throw new RuntimeException('Stream is not seekable');
  139. }
  140. $result = fseek($this->resource, $offset, $whence);
  141. if (0 !== $result) {
  142. throw new RuntimeException('Error seeking within stream');
  143. }
  144. return true;
  145. }
  146. /**
  147. * {@inheritdoc}
  148. */
  149. public function rewind()
  150. {
  151. return $this->seek(0);
  152. }
  153. /**
  154. * {@inheritdoc}
  155. */
  156. public function isWritable()
  157. {
  158. if (! $this->resource) {
  159. return false;
  160. }
  161. $meta = stream_get_meta_data($this->resource);
  162. $mode = $meta['mode'];
  163. return (
  164. strstr($mode, 'x')
  165. || strstr($mode, 'w')
  166. || strstr($mode, 'c')
  167. || strstr($mode, 'a')
  168. || strstr($mode, '+')
  169. );
  170. }
  171. /**
  172. * {@inheritdoc}
  173. */
  174. public function write($string)
  175. {
  176. if (! $this->resource) {
  177. throw new RuntimeException('No resource available; cannot write');
  178. }
  179. if (! $this->isWritable()) {
  180. throw new RuntimeException('Stream is not writable');
  181. }
  182. $result = fwrite($this->resource, $string);
  183. if (false === $result) {
  184. throw new RuntimeException('Error writing to stream');
  185. }
  186. return $result;
  187. }
  188. /**
  189. * {@inheritdoc}
  190. */
  191. public function isReadable()
  192. {
  193. if (! $this->resource) {
  194. return false;
  195. }
  196. $meta = stream_get_meta_data($this->resource);
  197. $mode = $meta['mode'];
  198. return (strstr($mode, 'r') || strstr($mode, '+'));
  199. }
  200. /**
  201. * {@inheritdoc}
  202. */
  203. public function read($length)
  204. {
  205. if (! $this->resource) {
  206. throw new RuntimeException('No resource available; cannot read');
  207. }
  208. if (! $this->isReadable()) {
  209. throw new RuntimeException('Stream is not readable');
  210. }
  211. $result = fread($this->resource, $length);
  212. if (false === $result) {
  213. throw new RuntimeException('Error reading stream');
  214. }
  215. return $result;
  216. }
  217. /**
  218. * {@inheritdoc}
  219. */
  220. public function getContents()
  221. {
  222. if (! $this->isReadable()) {
  223. throw new RuntimeException('Stream is not readable');
  224. }
  225. $result = stream_get_contents($this->resource);
  226. if (false === $result) {
  227. throw new RuntimeException('Error reading from stream');
  228. }
  229. return $result;
  230. }
  231. /**
  232. * {@inheritdoc}
  233. */
  234. public function getMetadata($key = null)
  235. {
  236. if (null === $key) {
  237. return stream_get_meta_data($this->resource);
  238. }
  239. $metadata = stream_get_meta_data($this->resource);
  240. if (! array_key_exists($key, $metadata)) {
  241. return null;
  242. }
  243. return $metadata[$key];
  244. }
  245. /**
  246. * Set the internal stream resource.
  247. *
  248. * @param string|resource $stream String stream target or stream resource.
  249. * @param string $mode Resource mode for stream target.
  250. * @throws InvalidArgumentException for invalid streams or resources.
  251. */
  252. private function setStream($stream, $mode = 'r')
  253. {
  254. $error = null;
  255. $resource = $stream;
  256. if (is_string($stream)) {
  257. set_error_handler(function ($e) use (&$error) {
  258. $error = $e;
  259. }, E_WARNING);
  260. $resource = fopen($stream, $mode);
  261. restore_error_handler();
  262. }
  263. if ($error) {
  264. throw new InvalidArgumentException('Invalid stream reference provided');
  265. }
  266. if (! is_resource($resource) || 'stream' !== get_resource_type($resource)) {
  267. throw new InvalidArgumentException(
  268. 'Invalid stream provided; must be a string stream identifier or stream resource'
  269. );
  270. }
  271. if ($stream !== $resource) {
  272. $this->stream = $stream;
  273. }
  274. $this->resource = $resource;
  275. }
  276. }