CallableStream.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. namespace AsyncAws\Core\Stream;
  3. use AsyncAws\Core\Exception\InvalidArgument;
  4. /**
  5. * Convert a "Curl Callable" into a Stream
  6. * The Callable must return a chunk at each call. And return an empty string on last call.
  7. *
  8. * @author Jérémy Derussé <jeremy@derusse.com>
  9. *
  10. * @internal
  11. */
  12. final class CallableStream implements ReadOnceResultStream, RequestStream
  13. {
  14. private $content;
  15. private $chunkSize;
  16. private function __construct(callable $content, int $chunkSize = 64 * 1024)
  17. {
  18. $this->content = $content;
  19. $this->chunkSize = $chunkSize;
  20. }
  21. public static function create($content, int $chunkSize = 64 * 1024): CallableStream
  22. {
  23. if ($content instanceof self) {
  24. return $content;
  25. }
  26. if (\is_callable($content)) {
  27. return new self($content, $chunkSize);
  28. }
  29. throw new InvalidArgument(sprintf('Expect content to be a "callable". "%s" given.', \is_object($content) ? \get_class($content) : \gettype($content)));
  30. }
  31. public function length(): ?int
  32. {
  33. return null;
  34. }
  35. public function stringify(): string
  36. {
  37. return implode('', iterator_to_array($this));
  38. }
  39. public function getIterator(): \Traversable
  40. {
  41. while (true) {
  42. if (!\is_string($data = ($this->content)($this->chunkSize))) {
  43. throw new InvalidArgument(sprintf('The return value of content callback must be a string, %s returned.', \is_object($data) ? \get_class($data) : \gettype($data)));
  44. }
  45. if ('' === $data) {
  46. break;
  47. }
  48. yield $data;
  49. }
  50. }
  51. public function hash(string $algo = 'sha256', bool $raw = false): string
  52. {
  53. $ctx = hash_init($algo);
  54. foreach ($this as $chunk) {
  55. hash_update($ctx, $chunk);
  56. }
  57. return hash_final($ctx, $raw);
  58. }
  59. }