HashingStream.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <?php
  2. namespace Aws;
  3. use GuzzleHttp\Psr7\StreamDecoratorTrait;
  4. use Psr\Http\Message\StreamInterface;
  5. /**
  6. * Stream decorator that calculates a rolling hash of the stream as it is read.
  7. */
  8. class HashingStream implements StreamInterface
  9. {
  10. use StreamDecoratorTrait;
  11. /** @var HashInterface */
  12. private $hash;
  13. /** @var callable|null */
  14. private $callback;
  15. /**
  16. * @param StreamInterface $stream Stream that is being read.
  17. * @param HashInterface $hash Hash used to calculate checksum.
  18. * @param callable $onComplete Optional function invoked when the
  19. * hash calculation is completed.
  20. */
  21. public function __construct(
  22. StreamInterface $stream,
  23. HashInterface $hash,
  24. callable $onComplete = null
  25. ) {
  26. $this->stream = $stream;
  27. $this->hash = $hash;
  28. $this->callback = $onComplete;
  29. }
  30. public function read($length)
  31. {
  32. $data = $this->stream->read($length);
  33. $this->hash->update($data);
  34. if ($this->eof()) {
  35. $result = $this->hash->complete();
  36. if ($this->callback) {
  37. call_user_func($this->callback, $result);
  38. }
  39. }
  40. return $data;
  41. }
  42. public function seek($offset, $whence = SEEK_SET)
  43. {
  44. if ($offset === 0) {
  45. $this->hash->reset();
  46. return $this->stream->seek($offset);
  47. } else {
  48. // Seeking arbitrarily is not supported.
  49. return false;
  50. }
  51. }
  52. }