Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

166 wiersze
3.9 KiB

  1. <?php
  2. namespace GuzzleHttp\Psr7;
  3. use Psr\Http\Message\StreamInterface;
  4. /**
  5. * Provides a read only stream that pumps data from a PHP callable.
  6. *
  7. * When invoking the provided callable, the PumpStream will pass the amount of
  8. * data requested to read to the callable. The callable can choose to ignore
  9. * this value and return fewer or more bytes than requested. Any extra data
  10. * returned by the provided callable is buffered internally until drained using
  11. * the read() function of the PumpStream. The provided callable MUST return
  12. * false when there is no more data to read.
  13. */
  14. class PumpStream implements StreamInterface
  15. {
  16. /** @var callable */
  17. private $source;
  18. /** @var int */
  19. private $size;
  20. /** @var int */
  21. private $tellPos = 0;
  22. /** @var array */
  23. private $metadata;
  24. /** @var BufferStream */
  25. private $buffer;
  26. /**
  27. * @param callable $source Source of the stream data. The callable MAY
  28. * accept an integer argument used to control the
  29. * amount of data to return. The callable MUST
  30. * return a string when called, or false on error
  31. * or EOF.
  32. * @param array $options Stream options:
  33. * - metadata: Hash of metadata to use with stream.
  34. * - size: Size of the stream, if known.
  35. */
  36. public function __construct(callable $source, array $options = [])
  37. {
  38. $this->source = $source;
  39. $this->size = isset($options['size']) ? $options['size'] : null;
  40. $this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
  41. $this->buffer = new BufferStream();
  42. }
  43. public function __toString()
  44. {
  45. try {
  46. return copy_to_string($this);
  47. } catch (\Exception $e) {
  48. return '';
  49. }
  50. }
  51. public function close()
  52. {
  53. $this->detach();
  54. }
  55. public function detach()
  56. {
  57. $this->tellPos = false;
  58. $this->source = null;
  59. }
  60. public function getSize()
  61. {
  62. return $this->size;
  63. }
  64. public function tell()
  65. {
  66. return $this->tellPos;
  67. }
  68. public function eof()
  69. {
  70. return !$this->source;
  71. }
  72. public function isSeekable()
  73. {
  74. return false;
  75. }
  76. public function rewind()
  77. {
  78. $this->seek(0);
  79. }
  80. public function seek($offset, $whence = SEEK_SET)
  81. {
  82. throw new \RuntimeException('Cannot seek a PumpStream');
  83. }
  84. public function isWritable()
  85. {
  86. return false;
  87. }
  88. public function write($string)
  89. {
  90. throw new \RuntimeException('Cannot write to a PumpStream');
  91. }
  92. public function isReadable()
  93. {
  94. return true;
  95. }
  96. public function read($length)
  97. {
  98. $data = $this->buffer->read($length);
  99. $readLen = strlen($data);
  100. $this->tellPos += $readLen;
  101. $remaining = $length - $readLen;
  102. if ($remaining) {
  103. $this->pump($remaining);
  104. $data .= $this->buffer->read($remaining);
  105. $this->tellPos += strlen($data) - $readLen;
  106. }
  107. return $data;
  108. }
  109. public function getContents()
  110. {
  111. $result = '';
  112. while (!$this->eof()) {
  113. $result .= $this->read(1000000);
  114. }
  115. return $result;
  116. }
  117. public function getMetadata($key = null)
  118. {
  119. if (!$key) {
  120. return $this->metadata;
  121. }
  122. return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
  123. }
  124. private function pump($length)
  125. {
  126. if ($this->source) {
  127. do {
  128. $data = call_user_func($this->source, $length);
  129. if ($data === false || $data === null) {
  130. $this->source = null;
  131. return;
  132. }
  133. $this->buffer->write($data);
  134. $length -= strlen($data);
  135. } while ($length > 0);
  136. }
  137. }
  138. }