| 
<?phpnamespace Aws;
 
 use GuzzleHttp\Psr7\StreamDecoratorTrait;
 use Psr\Http\Message\StreamInterface;
 
 /**
 * Stream decorator that calculates a rolling hash of the stream as it is read.
 */
 class HashingStream implements StreamInterface
 {
 use StreamDecoratorTrait;
 
 /** @var HashInterface */
 private $hash;
 
 /** @var callable|null */
 private $callback;
 
 /**
 * @param StreamInterface $stream     Stream that is being read.
 * @param HashInterface   $hash       Hash used to calculate checksum.
 * @param callable        $onComplete Optional function invoked when the
 *                                    hash calculation is completed.
 */
 public function __construct(
 StreamInterface $stream,
 HashInterface $hash,
 callable $onComplete = null
 ) {
 $this->stream = $stream;
 $this->hash = $hash;
 $this->callback = $onComplete;
 }
 
 public function read($length)
 {
 $data = $this->stream->read($length);
 $this->hash->update($data);
 if ($this->eof()) {
 $result = $this->hash->complete();
 if ($this->callback) {
 call_user_func($this->callback, $result);
 }
 }
 
 return $data;
 }
 
 public function seek($offset, $whence = SEEK_SET)
 {
 if ($offset === 0) {
 $this->hash->reset();
 return $this->stream->seek($offset);
 } else {
 // Seeking arbitrarily is not supported.
 return false;
 }
 }
 }
 
 |