GuzzleHttpPsr7LimitStream

Decorator used to return only a subset of a stream.

Defined (1)

The class is defined in the following location(s).

/lib/Azure/GuzzleHttp/Psr7/LimitStream.php  
  1. class LimitStream implements StreamInterface 
  2. use StreamDecoratorTrait; 
  3.  
  4. /** @var int Offset to start reading from */ 
  5. private $offset; 
  6.  
  7. /** @var int Limit the number of bytes that can be read */ 
  8. private $limit; 
  9.  
  10. /** 
  11. * @param StreamInterface $stream Stream to wrap 
  12. * @param int $limit Total number of bytes to allow to be read 
  13. * from the stream. Pass -1 for no limit. 
  14. * @param int|null $offset Position to seek to before reading (only 
  15. * works on seekable streams). 
  16. */ 
  17. public function __construct( 
  18. StreamInterface $stream,  
  19. $limit = -1,  
  20. $offset = 0 
  21. ) { 
  22. $this->stream = $stream; 
  23. $this->setLimit($limit); 
  24. $this->setOffset($offset); 
  25.  
  26. public function eof() 
  27. // Always return true if the underlying stream is EOF 
  28. if ($this->stream->eof()) { 
  29. return true; 
  30.  
  31. // No limit and the underlying stream is not at EOF 
  32. if ($this->limit == -1) { 
  33. return false; 
  34.  
  35. return $this->stream->tell() >= $this->offset + $this->limit; 
  36.  
  37. /** 
  38. * Returns the size of the limited subset of data 
  39. * {@inheritdoc} 
  40. */ 
  41. public function getSize() 
  42. if (null === ($length = $this->stream->getSize())) { 
  43. return null; 
  44. } elseif ($this->limit == -1) { 
  45. return $length - $this->offset; 
  46. } else { 
  47. return min($this->limit, $length - $this->offset); 
  48.  
  49. /** 
  50. * Allow for a bounded seek on the read limited stream 
  51. * {@inheritdoc} 
  52. */ 
  53. public function seek($offset, $whence = SEEK_SET) 
  54. if ($whence !== SEEK_SET || $offset < 0) { 
  55. throw new \RuntimeException(sprintf( 
  56. 'Cannot seek to offset % with whence %s',  
  57. $offset,  
  58. $whence 
  59. )); 
  60.  
  61. $offset += $this->offset; 
  62.  
  63. if ($this->limit !== -1) { 
  64. if ($offset > $this->offset + $this->limit) { 
  65. $offset = $this->offset + $this->limit; 
  66.  
  67. $this->stream->seek($offset); 
  68.  
  69. /** 
  70. * Give a relative tell() 
  71. * {@inheritdoc} 
  72. */ 
  73. public function tell() 
  74. return $this->stream->tell() - $this->offset; 
  75.  
  76. /** 
  77. * Set the offset to start limiting from 
  78. * @param int $offset Offset to seek to and begin byte limiting from 
  79. * @throws \RuntimeException if the stream cannot be seeked. 
  80. */ 
  81. public function setOffset($offset) 
  82. $current = $this->stream->tell(); 
  83.  
  84. if ($current !== $offset) { 
  85. // If the stream cannot seek to the offset position, then read to it 
  86. if ($this->stream->isSeekable()) { 
  87. $this->stream->seek($offset); 
  88. } elseif ($current > $offset) { 
  89. throw new \RuntimeException("Could not seek to stream offset $offset"); 
  90. } else { 
  91. $this->stream->read($offset - $current); 
  92.  
  93. $this->offset = $offset; 
  94.  
  95. /** 
  96. * Set the limit of bytes that the decorator allows to be read from the 
  97. * stream. 
  98. * @param int $limit Number of bytes to allow to be read from the stream. 
  99. * Use -1 for no limit. 
  100. */ 
  101. public function setLimit($limit) 
  102. $this->limit = $limit; 
  103.  
  104. public function read($length) 
  105. if ($this->limit == -1) { 
  106. return $this->stream->read($length); 
  107.  
  108. // Check if the current position is less than the total allowed 
  109. // bytes + original offset 
  110. $remaining = ($this->offset + $this->limit) - $this->stream->tell(); 
  111. if ($remaining > 0) { 
  112. // Only return the amount of requested data, ensuring that the byte 
  113. // limit is not exceeded 
  114. return $this->stream->read(min($remaining, $length)); 
  115.  
  116. return '';