FileUtils::LoadFile: replace implementation with call of CFile::LoadFile
authorKarlson2k <k2k@narod.ru>
Thu, 31 Oct 2013 11:34:49 +0000 (15:34 +0400)
committerKarlson2k <k2k@narod.ru>
Mon, 4 Nov 2013 21:27:32 +0000 (01:27 +0400)
xbmc/utils/FileUtils.cpp

index 18511ee..98da2de 100644 (file)
@@ -152,97 +152,12 @@ bool CFileUtils::RemoteAccessAllowed(const CStdString &strPath)
 
 unsigned int CFileUtils::LoadFile(const std::string &filename, void* &outputBuffer)
 {
-  static const unsigned int max_file_size = 0x7FFFFFFF;
-  static const unsigned int min_chunk_size = 64*1024U;
-  static const unsigned int max_chunk_size = 2048*1024U;
-
-  outputBuffer = NULL;
-  if (filename.empty())
-    return 0;
-
+  XFILE::auto_buffer buffer;
   XFILE::CFile file;
-  if (!file.Open(filename, READ_TRUNCATED))
-    return 0;
-
-  /*
-   GetLength() will typically return values that fall into three cases:
-   1. The real filesize. This is the typical case.
-   2. Zero. This is the case for some http:// streams for example.
-   3. Some value smaller than the real filesize. This is the case for an expanding file.
-
-   In order to handle all three cases, we read the file in chunks, relying on Read()
-   returning 0 at EOF.  To minimize (re)allocation of the buffer, the chunksize in
-   cases 1 and 3 is set to one byte larger than the value returned by GetLength().
-   The chunksize in case 2 is set to the lowest value larger than min_chunk_size aligned
-   to GetChunkSize().
-
-   We fill the buffer entirely before reallocation.  Thus, reallocation never occurs in case 1
-   as the buffer is larger than the file, so we hit EOF before we hit the end of buffer.
-
-   To minimize reallocation, we double the chunksize each read while chunksize is lower
-   than max_chunk_size.
-   */
-  int64_t filesize = file.GetLength();
-  if (filesize > max_file_size)
-  { /* file is too large for this function */
-    file.Close();
-    return 0;
-  }
-  unsigned int chunksize = (filesize > 0) ? (unsigned int)(filesize + 1) : CFile::GetChunkSize(file.GetChunkSize(), min_chunk_size);
-  unsigned char *inputBuff = NULL;
-  unsigned int inputBuffSize = 0;
-
-  unsigned int total_read = 0, free_space = 0;
-  while (true)
-  {
-    if (!free_space)
-    { // (re)alloc
-      inputBuffSize += chunksize;
-      unsigned char *tempinputBuff = NULL;
-      if (inputBuffSize <= max_file_size)
-        tempinputBuff = (unsigned char *)realloc(inputBuff, inputBuffSize);
-      if (!tempinputBuff)
-      {
-        CLog::Log(LOGERROR, "%s unable to (re)allocate buffer of size %u for file \"%s\"", __FUNCTION__, inputBuffSize, filename.c_str());
-        free(inputBuff);
-        file.Close();
-        return 0;
-      }
-      inputBuff = tempinputBuff;
-      free_space = chunksize;
-      if (chunksize < max_chunk_size)
-        chunksize *= 2;
-    }
-    unsigned int read = file.Read(inputBuff + total_read, free_space);
-    free_space -= read;
-    total_read += read;
-    if (!read)
-      break;
-  }
-
-  file.Close();
-
-  if (total_read == 0)
-  {
-    free(inputBuff);
-    return 0;
-  }
 
-  if (total_read + 1 < inputBuffSize)
-  {
-    /* free extra memory if more than 1 byte (cases 1 and 3) */
-    unsigned char *tempinputBuff = (unsigned char *)realloc(inputBuff, total_read);
-    if (!tempinputBuff)
-    {
-      /* just a precaution, shouldn't really happen */
-      CLog::Log(LOGERROR, "%s unable to reallocate buffer for file \"%s\"", __FUNCTION__, filename.c_str());
-      free(inputBuff);
-      return 0;
-    }
-    inputBuff = tempinputBuff;
-  }
+  const unsigned int total_read = file.LoadFile(filename, buffer);
+  outputBuffer = buffer.detach();
 
-  outputBuffer = (void *) inputBuff;
   return total_read;
 }