/**
  * {@inheritdoc}
  */
 public function transfer()
 {
     while (!$this->stopped && !$this->source->isConsumed()) {
         if ($this->source->getContentLength() && $this->source->isSeekable()) {
             // If the stream is seekable and the Content-Length known, then stream from the data source
             $body = new ReadLimitEntityBody($this->source, $this->partSize, $this->source->ftell());
         } else {
             // We need to read the data source into a temporary buffer before streaming
             $body = EntityBody::factory();
             while ($body->getContentLength() < $this->partSize && $body->write($this->source->read(max(1, min(10 * Size::KB, $this->partSize - $body->getContentLength()))))) {
             }
         }
         // @codeCoverageIgnoreStart
         if ($body->getContentLength() == 0) {
             break;
         }
         // @codeCoverageIgnoreEnd
         $params = $this->state->getUploadId()->toParams();
         $command = $this->client->getCommand('UploadPart', array_replace($params, array('PartNumber' => count($this->state) + 1, 'Body' => $body, 'ContentMD5' => (bool) $this->options['part_md5'], Ua::OPTION => Ua::MULTIPART_UPLOAD)));
         // Notify observers that the part is about to be uploaded
         $eventData = $this->getEventData();
         $eventData['command'] = $command;
         $this->dispatch(self::BEFORE_PART_UPLOAD, $eventData);
         // Allow listeners to stop the transfer if needed
         if ($this->stopped) {
             break;
         }
         $response = $command->getResponse();
         $this->state->addPart(UploadPart::fromArray(array('PartNumber' => count($this->state) + 1, 'ETag' => $response->getEtag(), 'Size' => $body->getContentLength(), 'LastModified' => gmdate(DateFormat::RFC2822))));
         // Notify observers that the part was uploaded
         $this->dispatch(self::AFTER_PART_UPLOAD, $eventData);
     }
 }
 /**
  * {@inheritdoc}
  */
 public static function fromUploadId(AwsClientInterface $client, UploadIdInterface $uploadId)
 {
     $transferState = new self($uploadId);
     foreach ($client->getIterator('ListParts', $uploadId->toParams()) as $part) {
         $transferState->addPart(UploadPart::fromArray($part));
     }
     return $transferState;
 }
 /**
  * {@inheritdoc}
  */
 public function transfer()
 {
     $totalParts = (int) ceil($this->source->getContentLength() / $this->partSize);
     // 		$totalParts  = (int) ceil($size / $this->partSize);
     $concurrency = min($totalParts, $this->options['concurrency']);
     $partsToSend = $this->prepareParts($concurrency);
     $eventData = $this->getEventData();
     $n = count($this->state);
     while (!$this->stopped && count($this->state) < $totalParts + $n) {
         $currentTotal = count($this->state);
         $commands = array();
         for ($i = 0; $i < $concurrency && $i + $currentTotal < $totalParts + $n; $i++) {
             // Move the offset to the correct position
             $partsToSend[$i]->setOffset(($currentTotal - $n + $i) * $this->partSize);
             // @codeCoverageIgnoreStart
             if ($partsToSend[$i]->getContentLength() == 0) {
                 break;
             }
             // @codeCoverageIgnoreEnd
             $params = $this->state->getUploadId()->toParams();
             $eventData['command'] = $this->client->getCommand('UploadPart', array_replace($params, array('PartNumber' => count($this->state) + 1 + $i, 'Body' => $partsToSend[$i], 'ContentMD5' => (bool) $this->options['part_md5'], Ua::OPTION => Ua::MULTIPART_UPLOAD)));
             $commands[] = $eventData['command'];
             // Notify any listeners of the part upload
             $this->dispatch(self::BEFORE_PART_UPLOAD, $eventData);
         }
         // Allow listeners to stop the transfer if needed
         if ($this->stopped) {
             break;
         }
         // Execute each command, iterate over the results, and add to the transfer state
         /** @var $command \Guzzle\Service\Command\OperationCommand */
         foreach ($this->client->execute($commands) as $command) {
             $this->state->addPart(UploadPart::fromArray(array('PartNumber' => count($this->state) + 1, 'ETag' => $command->getResponse()->getEtag(), 'Size' => (int) $command->getResponse()->getContentLength(), 'LastModified' => gmdate(DateFormat::RFC2822))));
             $eventData['command'] = $command;
             // Notify any listeners the the part was uploaded
             $this->dispatch(self::AFTER_PART_UPLOAD, $eventData);
         }
     }
 }