/**
  * Read one line from export response, if read success converts line to associative array according to export data
  * format.
  *
  * @return array|null
  */
 protected function read()
 {
     if (!$this->body) {
         $response = $this->client->export($this->methodName, $this->parameters);
         $this->body = $response->getBody();
         $this->body->seek(0);
         if ($this->useFirstLineAsHeader) {
             $line = $this->getLineData();
             if ($line) {
                 $this->header = $line;
             }
         }
     }
     return $this->getResponseItem();
 }
 /**
  * Performs the work of reading the body stream, creating tree hashes, and creating UploadPartContext objects
  *
  * @param EntityBodyInterface $body The body to create parts from
  */
 protected function generateUploadParts(EntityBodyInterface $body)
 {
     // Rewind the body stream
     $body->seek(0);
     // Initialize variables for tracking data for upload
     $uploadContext = new UploadPartContext($this->partSize, $body->ftell());
     // Read the data from the streamed body in 1MB chunks
     $data = $this->readPart($body);
     while (strlen($data) > 0) {
         // Add data to the hashes and size calculations
         $uploadContext->addData($data);
         // If the upload part is complete, generate an upload object and reset the currently tracked upload data
         if ($uploadContext->isFull()) {
             $this->updateTotals($uploadContext->generatePart());
             $uploadContext = new UploadPartContext($this->partSize, $body->ftell());
         }
         $data = $this->readPart($body);
     }
     // Handle any leftover data
     if (!$uploadContext->isEmpty()) {
         $this->updateTotals($uploadContext->generatePart());
     }
     // Rewind the body stream
     $body->seek(0);
 }