/**
  * Get the best storage based on request and/or parameters.
  *
  * @param  UploadContext                                    $context
  * @throws \SRIO\RestUploadBundle\Exception\UploadException
  * @throws \RuntimeException
  * @return FileStorage
  */
 public function getStorage(UploadContext $context)
 {
     if (count($this->storages) == 0) {
         throw new UploadException('No storage found');
     }
     if (($storageName = $context->getStorageName()) !== null || ($storageName = $this->defaultStorage) !== null) {
         if (!array_key_exists($storageName, $this->storages)) {
             throw new \RuntimeException(sprintf('Storage with name %s do not exists', $storageName));
         }
         return $this->storages[$storageName];
     }
     return current($this->storages);
 }
 /**
  * Handle an upload resume.
  *
  * @param  Request                                                   $request
  * @param  ResumableUploadSession                                    $uploadSession
  * @throws \SRIO\RestUploadBundle\Exception\UploadProcessorException
  * @return UploadResult
  */
 protected function handleResume(Request $request, ResumableUploadSession $uploadSession)
 {
     $filePath = $uploadSession->getFilePath();
     $context = new UploadContext();
     $context->setStorageName($uploadSession->getStorageName());
     $contentLength = $request->headers->get('Content-Length');
     if ($request->headers->has('Content-Range')) {
         $range = $this->parseContentRange($request->headers->get('Content-Range'));
         if ($range['total'] != $uploadSession->getContentLength()) {
             throw new UploadProcessorException(sprintf('File size must be "%d", range total length is %d', $uploadSession->getContentLength(), $range['total']));
         } elseif ($range['start'] === '*') {
             if ($contentLength == 0) {
                 $file = $this->storageHandler->get($context, $filePath);
                 return $this->requestUploadStatus($context, $uploadSession, $file, $range);
             }
             throw new UploadProcessorException('Content-Length must be 0 if asking upload status');
         }
         $uploaded = $this->storageHandler->size($context, $filePath);
         if ($range['start'] != $uploaded) {
             throw new UploadProcessorException(sprintf('Unable to start at %d while uploaded is %d', $range['start'], $uploaded));
         }
     } else {
         $range = array('start' => 0, 'end' => $uploadSession->getContentLength() - 1, 'total' => $uploadSession->getContentLength() - 1);
     }
     // Handle upload from
     $handler = $this->getRequestContentHandler($request);
     $writer = $this->storageHandler->getStream($context, $filePath);
     if ($writer->open(new StreamMode('c')) !== true) {
         throw new UploadProcessorException('Unable to open stream');
     }
     $writer->seek($range['start']);
     $wrote = 0;
     while (!$handler->eof()) {
         if (($bytes = $writer->write($handler->gets())) !== false) {
             $wrote += $bytes;
         } else {
             throw new UploadProcessorException('Unable to wrote to file');
         }
     }
     $writer->close();
     // Get file in context and its size
     $file = $this->storageHandler->get($context, $filePath);
     $size = $file->getSize();
     // If upload is completed, create the upload file, else
     // return like the request upload status
     if ($size < $uploadSession->getContentLength()) {
         return $this->requestUploadStatus($context, $uploadSession, $file, $range);
     } elseif ($size == $uploadSession->getContentLength()) {
         return $this->handleCompletedUpload($context, $uploadSession, $file);
     } else {
         throw new UploadProcessorException('Wrote file size is greater that expected Content-Length');
     }
 }