Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2017 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fxcrt/fx_stream.h"
      8 
      9 #include <algorithm>
     10 #include <memory>
     11 #include <utility>
     12 #include <vector>
     13 
     14 #include "core/fxcrt/fx_safe_types.h"
     15 #include "core/fxcrt/ifx_fileaccess.h"
     16 #include "third_party/base/ptr_util.h"
     17 
     18 namespace {
     19 
     20 class CFX_CRTFileStream final : public IFX_SeekableStream {
     21  public:
     22   template <typename T, typename... Args>
     23   friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
     24 
     25   // IFX_SeekableStream:
     26   FX_FILESIZE GetSize() override { return m_pFile->GetSize(); }
     27   bool IsEOF() override { return GetPosition() >= GetSize(); }
     28   FX_FILESIZE GetPosition() override { return m_pFile->GetPosition(); }
     29   bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
     30     return m_pFile->ReadPos(buffer, size, offset) > 0;
     31   }
     32   size_t ReadBlock(void* buffer, size_t size) override {
     33     return m_pFile->Read(buffer, size);
     34   }
     35   bool WriteBlock(const void* buffer,
     36                   FX_FILESIZE offset,
     37                   size_t size) override {
     38     return !!m_pFile->WritePos(buffer, size, offset);
     39   }
     40   bool Flush() override { return m_pFile->Flush(); }
     41 
     42  private:
     43   explicit CFX_CRTFileStream(std::unique_ptr<IFX_FileAccess> pFA)
     44       : m_pFile(std::move(pFA)) {}
     45   ~CFX_CRTFileStream() override {}
     46 
     47   std::unique_ptr<IFX_FileAccess> m_pFile;
     48 };
     49 
     50 }  // namespace
     51 
     52 // static
     53 RetainPtr<IFX_SeekableStream> IFX_SeekableStream::CreateFromFilename(
     54     const char* filename,
     55     uint32_t dwModes) {
     56   std::unique_ptr<IFX_FileAccess> pFA = IFX_FileAccess::Create();
     57   if (!pFA->Open(filename, dwModes))
     58     return nullptr;
     59   return pdfium::MakeRetain<CFX_CRTFileStream>(std::move(pFA));
     60 }
     61 
     62 // static
     63 RetainPtr<IFX_SeekableStream> IFX_SeekableStream::CreateFromFilename(
     64     const wchar_t* filename,
     65     uint32_t dwModes) {
     66   std::unique_ptr<IFX_FileAccess> pFA = IFX_FileAccess::Create();
     67   if (!pFA->Open(filename, dwModes))
     68     return nullptr;
     69   return pdfium::MakeRetain<CFX_CRTFileStream>(std::move(pFA));
     70 }
     71 
     72 // static
     73 RetainPtr<IFX_SeekableReadStream> IFX_SeekableReadStream::CreateFromFilename(
     74     const char* filename) {
     75   return IFX_SeekableStream::CreateFromFilename(filename, FX_FILEMODE_ReadOnly);
     76 }
     77 
     78 bool IFX_SeekableWriteStream::WriteBlock(const void* pData, size_t size) {
     79   return WriteBlock(pData, GetSize(), size);
     80 }
     81 
     82 bool IFX_SeekableReadStream::IsEOF() {
     83   return false;
     84 }
     85 
     86 FX_FILESIZE IFX_SeekableReadStream::GetPosition() {
     87   return 0;
     88 }
     89 
     90 size_t IFX_SeekableReadStream::ReadBlock(void* buffer, size_t size) {
     91   return 0;
     92 }
     93 
     94 bool IFX_SeekableStream::WriteBlock(const void* buffer, size_t size) {
     95   return WriteBlock(buffer, GetSize(), size);
     96 }
     97 
     98 bool IFX_SeekableStream::WriteString(const ByteStringView& str) {
     99   return WriteBlock(str.unterminated_c_str(), str.GetLength());
    100 }
    101 
    102 FX_FileHandle* FX_OpenFolder(const char* path) {
    103 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
    104   auto pData = pdfium::MakeUnique<CFindFileDataA>();
    105   pData->m_Handle =
    106       FindFirstFileExA((ByteString(path) + "/*.*").c_str(), FindExInfoStandard,
    107                        &pData->m_FindData, FindExSearchNameMatch, nullptr, 0);
    108   if (pData->m_Handle == INVALID_HANDLE_VALUE)
    109     return nullptr;
    110 
    111   pData->m_bEnd = false;
    112   return pData.release();
    113 #else
    114   return opendir(path);
    115 #endif
    116 }
    117 
    118 bool FX_GetNextFile(FX_FileHandle* handle,
    119                     ByteString* filename,
    120                     bool* bFolder) {
    121   if (!handle)
    122     return false;
    123 
    124 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
    125   if (handle->m_bEnd)
    126     return false;
    127 
    128   *filename = handle->m_FindData.cFileName;
    129   *bFolder =
    130       (handle->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
    131   if (!FindNextFileA(handle->m_Handle, &handle->m_FindData))
    132     handle->m_bEnd = true;
    133   return true;
    134 #else
    135   struct dirent* de = readdir(handle);
    136   if (!de)
    137     return false;
    138   *filename = de->d_name;
    139   *bFolder = de->d_type == DT_DIR;
    140   return true;
    141 #endif
    142 }
    143 
    144 void FX_CloseFolder(FX_FileHandle* handle) {
    145   if (!handle)
    146     return;
    147 
    148 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
    149   FindClose(handle->m_Handle);
    150   delete handle;
    151 #else
    152   closedir(handle);
    153 #endif
    154 }
    155