• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
GetSize()26   FX_FILESIZE GetSize() override { return m_pFile->GetSize(); }
IsEOF()27   bool IsEOF() override { return GetPosition() >= GetSize(); }
GetPosition()28   FX_FILESIZE GetPosition() override { return m_pFile->GetPosition(); }
ReadBlock(void * buffer,FX_FILESIZE offset,size_t size)29   bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
30     return m_pFile->ReadPos(buffer, size, offset) > 0;
31   }
ReadBlock(void * buffer,size_t size)32   size_t ReadBlock(void* buffer, size_t size) override {
33     return m_pFile->Read(buffer, size);
34   }
WriteBlock(const void * buffer,FX_FILESIZE offset,size_t size)35   bool WriteBlock(const void* buffer,
36                   FX_FILESIZE offset,
37                   size_t size) override {
38     return !!m_pFile->WritePos(buffer, size, offset);
39   }
Flush()40   bool Flush() override { return m_pFile->Flush(); }
41 
42  private:
CFX_CRTFileStream(std::unique_ptr<IFX_FileAccess> pFA)43   explicit CFX_CRTFileStream(std::unique_ptr<IFX_FileAccess> pFA)
44       : m_pFile(std::move(pFA)) {}
~CFX_CRTFileStream()45   ~CFX_CRTFileStream() override {}
46 
47   std::unique_ptr<IFX_FileAccess> m_pFile;
48 };
49 
50 }  // namespace
51 
52 // static
CreateFromFilename(const char * filename,uint32_t dwModes)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
CreateFromFilename(const wchar_t * filename,uint32_t dwModes)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
CreateFromFilename(const char * filename)73 RetainPtr<IFX_SeekableReadStream> IFX_SeekableReadStream::CreateFromFilename(
74     const char* filename) {
75   return IFX_SeekableStream::CreateFromFilename(filename, FX_FILEMODE_ReadOnly);
76 }
77 
WriteBlock(const void * pData,size_t size)78 bool IFX_SeekableWriteStream::WriteBlock(const void* pData, size_t size) {
79   return WriteBlock(pData, GetSize(), size);
80 }
81 
IsEOF()82 bool IFX_SeekableReadStream::IsEOF() {
83   return false;
84 }
85 
GetPosition()86 FX_FILESIZE IFX_SeekableReadStream::GetPosition() {
87   return 0;
88 }
89 
ReadBlock(void * buffer,size_t size)90 size_t IFX_SeekableReadStream::ReadBlock(void* buffer, size_t size) {
91   return 0;
92 }
93 
WriteBlock(const void * buffer,size_t size)94 bool IFX_SeekableStream::WriteBlock(const void* buffer, size_t size) {
95   return WriteBlock(buffer, GetSize(), size);
96 }
97 
WriteString(const ByteStringView & str)98 bool IFX_SeekableStream::WriteString(const ByteStringView& str) {
99   return WriteBlock(str.unterminated_c_str(), str.GetLength());
100 }
101 
FX_OpenFolder(const char * path)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 
FX_GetNextFile(FX_FileHandle * handle,ByteString * filename,bool * bFolder)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 
FX_CloseFolder(FX_FileHandle * handle)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